flash_flow 1.2.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ba7a7fe175b96cc420cab775f520719c7fc83f5
4
- data.tar.gz: 7d49a193d1430a55a3b42a135e8ec35838bb47cc
3
+ metadata.gz: 26e9411883c55d49e496359a23debe7ce7cad73c
4
+ data.tar.gz: c08cd64b3c192f4073802a5b1254e5f821ee2d79
5
5
  SHA512:
6
- metadata.gz: 2b11140dd538fef6a9b37e17d62ffe72174efe6efc723679f0b1982303a992c4de46ddd655fe1889a895dda67de6ca80bb6b6f27697e9a495692bbf81e1dfc0a
7
- data.tar.gz: 29f7e831e2461baf974abf70fdff8ca3a21b34ff937ac993822c04da698963e6251cee1ae8abd791ef0f3493ed87924e97fb3e3316fe7e9b607b049fd835284e
6
+ metadata.gz: 1dfe5cb15b0e924fac257397528ef2b4b6dcc00ae213abf1b909445f4059e2407056778d6f30e199dfc10711fc62ec72e766f937f869f3c0750dd46958e5c657
7
+ data.tar.gz: 45e2f8c31f6900c51f84e9c9d74bf1662c43ef74fc4f91c64f1f267c6f9ba41c2eb5e6cdb687aab711bd701f316118622e6568cafae13ea14cb88d93246a87b5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flash_flow (1.2.3)
4
+ flash_flow (1.3.0)
5
5
  hipchat (~> 1.5)
6
6
  octokit (~> 4.1)
7
7
  pivotal-tracker (~> 0.5)
@@ -33,16 +33,16 @@ GEM
33
33
  json (~> 1.8)
34
34
  multi_xml (>= 0.5.2)
35
35
  json (1.8.3)
36
- mime-types (2.6.2)
36
+ mime-types (2.99)
37
37
  mimemagic (0.3.0)
38
- mini_portile (0.6.2)
38
+ mini_portile2 (2.0.0)
39
39
  minitest (5.3.5)
40
40
  minitest-stub_any_instance (1.0.1)
41
41
  multi_xml (0.5.5)
42
42
  multipart-post (2.0.0)
43
43
  netrc (0.11.0)
44
- nokogiri (1.6.6.2)
45
- mini_portile (~> 0.6.0)
44
+ nokogiri (1.6.7.2)
45
+ mini_portile2 (~> 2.0.0.rc2)
46
46
  nokogiri-happymapper (0.5.9)
47
47
  nokogiri (~> 1.5)
48
48
  octokit (4.1.1)
@@ -5,7 +5,7 @@ module FlashFlow
5
5
 
6
6
  class Branch
7
7
  attr_accessor :remote, :remote_url, :ref, :sha, :status, :resolutions, :stories, :conflict_sha, :metadata,
8
- :current_record, :updated_at, :created_at
8
+ :current_record, :merge_order, :updated_at, :created_at
9
9
 
10
10
  def initialize(_remote, _remote_url, _ref)
11
11
  @remote = _remote
@@ -21,6 +21,7 @@ module FlashFlow
21
21
  branch = new(hash['remote'], hash['remote_url'], hash['ref'])
22
22
  branch.sha = hash['sha']
23
23
  branch.status = hash['status']
24
+ branch.merge_order = hash['merge_order']
24
25
  branch.resolutions = hash['resolutions']
25
26
  branch.stories = hash['stories']
26
27
  branch.metadata = hash['metadata']
@@ -52,6 +53,7 @@ module FlashFlow
52
53
  'ref' => ref,
53
54
  'sha' => sha,
54
55
  'status' => status,
56
+ 'merge_order' => merge_order,
55
57
  'resolutions' => resolutions,
56
58
  'stories' => stories,
57
59
  'conflict_sha' => conflict_sha,
@@ -70,6 +72,7 @@ module FlashFlow
70
72
  unless other.nil?
71
73
  self.sha = other.sha
72
74
  self.status = other.status
75
+ self.merge_order = other.merge_order
73
76
  self.resolutions = other.resolutions
74
77
  self.stories = self.stories.to_a | other.stories.to_a
75
78
  self.updated_at = Time.now
@@ -65,6 +65,7 @@ module FlashFlow
65
65
  branch.created_at = info.created_at
66
66
  branch.resolutions = info.resolutions.to_h.merge(branch.resolutions.to_h)
67
67
  branch.stories = info.stories.to_a | merged_branches[full_ref].stories.to_a
68
+ branch.merge_order ||= info.merge_order
68
69
  if branch.fail?
69
70
  branch.conflict_sha ||= info.conflict_sha
70
71
  end
@@ -38,7 +38,8 @@ module FlashFlow
38
38
  'remote_url' => pr.head.repo.ssh_url,
39
39
  'ref' => pr.head.ref,
40
40
  'status' => status_from_labels(pr),
41
- 'metadata' => metadata(pr)
41
+ 'metadata' => metadata(pr),
42
+ 'sha' => pr.head.sha
42
43
  )
43
44
  end
44
45
  end
@@ -98,7 +99,7 @@ module FlashFlow
98
99
  end
99
100
 
100
101
  def pull_requests
101
- @pull_requests ||= octokit.pull_requests(repo).sort_by(&:updated_at)
102
+ @pull_requests ||= octokit.pull_requests(repo).sort_by(&:created_at)
102
103
  end
103
104
 
104
105
  def remove_label(pull_request_number, label)
@@ -136,4 +137,4 @@ module FlashFlow
136
137
  end
137
138
  end
138
139
  end
139
- end
140
+ end
@@ -5,6 +5,7 @@ require 'flash_flow/data'
5
5
  require 'flash_flow/lock'
6
6
  require 'flash_flow/notifier'
7
7
  require 'flash_flow/branch_merger'
8
+ require 'flash_flow/merge_order'
8
9
  require 'flash_flow/shadow_repo'
9
10
 
10
11
  module FlashFlow
@@ -104,7 +105,10 @@ module FlashFlow
104
105
  end
105
106
 
106
107
  def merge_branches
107
- @data.mergeable.each do |branch|
108
+ ordered_branches = MergeOrder.new(@git, @data.merged_branches.mergeable).get_order
109
+ ordered_branches.each_with_index do |branch, index|
110
+ branch.merge_order = index + 1
111
+
108
112
  remote = @git.fetch_remote_for_url(branch.remote_url)
109
113
  if remote.nil?
110
114
  raise RuntimeError.new("No remote found for #{branch.remote_url}. Please run 'git remote add *your_remote_name* #{branch.remote_url}' and try again.")
@@ -182,7 +186,7 @@ module FlashFlow
182
186
  Flash Flow run from branch: #{@local_git.working_branch}
183
187
 
184
188
  Merged branches:
185
- #{@data.successes.empty? ? 'None' : @data.successes.map(&:ref).join("\n")}
189
+ #{@data.successes.empty? ? 'None' : @data.successes.sort_by(&:merge_order).map(&:ref).join("\n")}
186
190
 
187
191
  Failed branches:
188
192
  #{@data.failures.empty? ? 'None' : @data.failures.map(&:ref).join("\n")}
@@ -32,7 +32,8 @@ module FlashFlow
32
32
  deliver(story_id)
33
33
  end
34
34
  end
35
- removed_branches.each do |branch|
35
+
36
+ removed_and_failed_branches.each do |branch|
36
37
  branch.stories.to_a.each do |story_id|
37
38
  undeliver(story_id)
38
39
  end
@@ -188,8 +189,8 @@ module FlashFlow
188
189
  @branches.select { |b| b.success? }
189
190
  end
190
191
 
191
- def removed_branches
192
- @branches.select { |b| b.removed? }
192
+ def removed_and_failed_branches
193
+ @branches.select { |b| b.removed? || b.fail? }
193
194
  end
194
195
 
195
196
  def merged_working_branch
@@ -0,0 +1,27 @@
1
+ module FlashFlow
2
+ class MergeOrder
3
+
4
+ def initialize(git, branches)
5
+ @git = git
6
+ @branches = branches
7
+ end
8
+
9
+ def get_order
10
+ branches = @branches.sort_by(&:merge_order)
11
+
12
+ unchanged, changed = branches.partition { |branch| current_sha(branch) == branch.sha }
13
+ my_branch_index = changed.find_index { |branch| branch.ref == @git.working_branch }
14
+ my_branch_changed = my_branch_index ? changed.delete_at(my_branch_index) : nil
15
+
16
+ [unchanged, changed, my_branch_changed].flatten.compact
17
+ end
18
+
19
+ private
20
+
21
+ def current_sha(branch)
22
+ @git.run("rev-parse #{branch.remote}/#{branch.ref}")
23
+ @git.last_stdout.strip if @git.last_success?
24
+ end
25
+
26
+ end
27
+ end
@@ -21,7 +21,7 @@ module FlashFlow
21
21
  opts.on('-c', '--config-file FILE_PATH', 'The path to your config file. Defaults to config/flash_flow.yml.erb') { |v| options[:config_file] = v }
22
22
  opts.on('--resolve', 'Launch a bash shell to save your conflict resolutions') { |v| options[:resolve] = true }
23
23
  opts.on('--resolve-manual', 'Print instructions to use git to resolve conflicts') { |v| options[:resolve_manual] = true }
24
- opts.on('--merge-status', 'Print instructions to use git to resolve conflicts') { |v| options[:merge_status] = true }
24
+ opts.on('--merge-status', 'Show status of all branches and their stories and exit') { |v| options[:merge_status] = true }
25
25
 
26
26
  opts.on_tail("-h", "--help", "Show this message") do
27
27
  puts opts
@@ -1,3 +1,3 @@
1
1
  module FlashFlow
2
- VERSION = "1.2.3"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -202,6 +202,7 @@ module FlashFlow
202
202
  'remote' => 'origin',
203
203
  'sha' => 'random_sha',
204
204
  'status' => 'success',
205
+ 'merge_order' => nil,
205
206
  'resolutions' => {},
206
207
  'stories' => ['123'],
207
208
  'conflict_sha' => 'conflict_sha',
@@ -28,6 +28,7 @@ module FlashFlow
28
28
  stub_tracker_gem(@project_mock) do
29
29
  mock_find(nil, '111')
30
30
  mock_find(nil, '222')
31
+ mock_find(nil, '333')
31
32
  mock_find(nil, '555')
32
33
 
33
34
  Pivotal.new(sample_branches, nil).stories_delivered
@@ -46,11 +47,15 @@ module FlashFlow
46
47
  .expect(:id, '222')
47
48
  .expect(:current_state, 'delivered')
48
49
  story3_mock = MiniTest::Mock.new
50
+ .expect(:id, '333')
51
+ .expect(:current_state, 'fail')
52
+ story4_mock = MiniTest::Mock.new
49
53
  .expect(:id, '555')
50
54
  .expect(:current_state, 'removed')
51
55
  mock_find(story1_mock)
52
56
  mock_find(story2_mock)
53
57
  mock_find(story3_mock)
58
+ mock_find(story4_mock)
54
59
 
55
60
  Pivotal.new(sample_branches, nil).stories_delivered
56
61
  story1_mock.verify
@@ -141,6 +141,18 @@ module FlashFlow
141
141
  end
142
142
  end
143
143
 
144
+ def test_commit_message_ordering
145
+ data
146
+ .expect(:successes, ['data_successes'])
147
+ .expect(:successes, sample_branches)
148
+ .expect(:failures, [])
149
+ .expect(:removals, [])
150
+
151
+ expected_message = sample_branches.sort_by(&:merge_order).map(&:ref).join("\n")
152
+ assert_output(/#{expected_message}/) { print @deploy.commit_message }
153
+ data.verify
154
+ end
155
+
144
156
  private
145
157
 
146
158
  def with_versions(current, written)
@@ -172,5 +184,10 @@ module FlashFlow
172
184
  @deploy.instance_variable_set('@data'.to_sym, @data)
173
185
  end
174
186
 
187
+ def sample_branches
188
+ @sample_branches ||= [Data::Branch.from_hash({'ref' => 'branch3', 'merge_order' => 2}),
189
+ Data::Branch.from_hash({'ref' => 'branch1', 'merge_order' => 3}),
190
+ Data::Branch.from_hash({'ref' => 'branch2', 'merge_order' => 1})]
191
+ end
175
192
  end
176
193
  end
@@ -0,0 +1,72 @@
1
+ require 'minitest_helper'
2
+ require 'minitest/stub_any_instance'
3
+
4
+ module FlashFlow
5
+ class TestMergeOrder < Minitest::Test
6
+
7
+ def setup
8
+ @git = Minitest::Mock.new
9
+ end
10
+
11
+ def test_get_order_unchanged_shas_get_ordered_as_previous
12
+ mock_working_branch(sample_branches[2])
13
+ mock_current_sha(sample_branches[1], sample_branches[1].sha)
14
+ mock_current_sha(sample_branches[0], sample_branches[0].sha)
15
+ mock_current_sha(sample_branches[2], sample_branches[2].sha)
16
+
17
+ ordered_branches = MergeOrder.new(@git, mergeable_order(1,0,2)).get_order
18
+ assert_equal(ordered_branches.map(&:sha), mergeable_order(1,0,2).map(&:sha))
19
+ end
20
+
21
+ def test_get_order_changed_working_branch_is_always_last
22
+ mock_working_branch(sample_branches[0])
23
+ mock_current_sha(sample_branches[1], sample_branches[1].sha)
24
+ mock_current_sha(sample_branches[0], sample_branches[0].sha)
25
+ mock_current_sha(sample_branches[2], sample_branches[2].sha)
26
+
27
+ sample_branches[0].sha = 'sha0-1'
28
+
29
+ ordered_branches = MergeOrder.new(@git, mergeable_order(1,0,2)).get_order
30
+ assert_equal(ordered_branches.map(&:sha), mergeable_order(1,2,0).map(&:sha))
31
+ end
32
+ #
33
+ def test_get_order_changed_shas_are_between_unchanged_shas_and_changed_working_branch
34
+ mock_working_branch(sample_branches[1])
35
+ mock_current_sha(sample_branches[2], sample_branches[2].sha)
36
+ mock_current_sha(sample_branches[1], sample_branches[1].sha)
37
+ mock_current_sha(sample_branches[0], sample_branches[0].sha)
38
+
39
+ sample_branches[1].sha = 'sha0-1'
40
+ sample_branches[2].sha = 'sha2-1'
41
+
42
+ ordered_branches = MergeOrder.new(@git, mergeable_order(2,1,0)).get_order
43
+ assert_equal(ordered_branches.map(&:sha), mergeable_order(0,2,1).map(&:sha))
44
+ end
45
+
46
+ private
47
+
48
+ def mock_current_sha(branch, sha)
49
+ @git.expect(:run, sha, ["rev-parse #{branch.remote}/#{branch.ref}"])
50
+ .expect(:last_success?, true)
51
+ .expect(:last_stdout, sha)
52
+ end
53
+
54
+ def mock_working_branch(branch)
55
+ sample_branches.count.times { @git.expect(:working_branch, branch.ref) }
56
+ end
57
+
58
+ def sample_branches
59
+ @sample_branches ||= [Data::Branch.from_hash({'ref' => 'branch0', 'remote' => 'origin', 'sha' => 'sha0', 'merge_order' => 1}),
60
+ Data::Branch.from_hash({'ref' => 'branch1', 'remote' => 'origin', 'sha' => 'sha1', 'merge_order' => 2}),
61
+ Data::Branch.from_hash({'ref' => 'branch2', 'remote' => 'origin', 'sha' => 'sha2', 'merge_order' => 3})]
62
+ end
63
+
64
+ def mergeable_order(*order)
65
+ order.map.with_index do |nth, merge_order|
66
+ sample_branches[nth].merge_order = merge_order
67
+ sample_branches[nth]
68
+ end
69
+ end
70
+
71
+ end
72
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flash_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flashfunders
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-01 00:00:00.000000000 Z
11
+ date: 2016-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit
@@ -176,6 +176,7 @@ files:
176
176
  - lib/flash_flow/merge_master/merge_status.html.erb
177
177
  - lib/flash_flow/merge_master/release_graph.rb
178
178
  - lib/flash_flow/merge_master/status.rb
179
+ - lib/flash_flow/merge_order.rb
179
180
  - lib/flash_flow/notifier.rb
180
181
  - lib/flash_flow/notifier/hipchat.rb
181
182
  - lib/flash_flow/options.rb
@@ -198,6 +199,7 @@ files:
198
199
  - test/lib/test_deploy.rb
199
200
  - test/lib/test_git.rb
200
201
  - test/lib/test_issue_tracker.rb
202
+ - test/lib/test_merge_order.rb
201
203
  - test/lib/test_notifier.rb
202
204
  - test/lib/test_resolve.rb
203
205
  - test/minitest_helper.rb
@@ -241,6 +243,7 @@ test_files:
241
243
  - test/lib/test_deploy.rb
242
244
  - test/lib/test_git.rb
243
245
  - test/lib/test_issue_tracker.rb
246
+ - test/lib/test_merge_order.rb
244
247
  - test/lib/test_notifier.rb
245
248
  - test/lib/test_resolve.rb
246
249
  - test/minitest_helper.rb