flash_flow 1.3.2.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 338f724ecab800bc4a3bd13a8f4fbf91c7e9e57e
4
- data.tar.gz: 49d3e823233fc4d1e65edb566d5a7fd47005b570
3
+ metadata.gz: a41f62720b6a1d95aac60bc4275d5711b4ab82e3
4
+ data.tar.gz: 88ca498a5fef9fbec2d48bb12ea0c973123cf15f
5
5
  SHA512:
6
- metadata.gz: b97e6178e3e02eab5dac92edd5bfc2ef62285562091555aa69b7fe88999c81419c9ef1be84e11d0481a7f51a79d40187eb05a3f69ab28face2d2ffe00b0c67aa
7
- data.tar.gz: d0a71e6374fa222596222ad29684303c5d8955c3a5da5ada1da79b763c64264a25d0a9d3871cf318a6d9ea1735adeaa6eeba959532443b95b7e48fae841bbb18
6
+ metadata.gz: 9d6d4dc8b130952e6c002af7d5f524f35464f2359e88b5c7b01cdae49f8fc63cb11a8c5e97b681c4be509ca9851a50d0040ff60129843c163e01ea1ee115b7ab
7
+ data.tar.gz: d6f2cf9bcd93e7cf2a169b138a3fadc56b9494702d4bd36a347e9fe9d2b6404022d05e92eb58d987ec53f84484e14f0b6cc11d900f60ab33e98b7a1012ae7492
data/Gemfile.lock CHANGED
@@ -4,6 +4,7 @@ PATH
4
4
  flash_flow (1.3.2.1)
5
5
  hipchat (~> 1.5)
6
6
  octokit (~> 4.1)
7
+ percy-client
7
8
  pivotal-tracker (~> 0.5)
8
9
  ruby-graphviz (> 0)
9
10
 
@@ -20,7 +21,7 @@ GEM
20
21
  crack (0.4.3)
21
22
  safe_yaml (~> 1.0.0)
22
23
  debugger-linecache (1.2.0)
23
- domain_name (0.5.20160310)
24
+ domain_name (0.5.20160615)
24
25
  unf (>= 0.0.5, < 1.0.0)
25
26
  faraday (0.9.2)
26
27
  multipart-post (>= 1.2, < 3)
@@ -29,11 +30,12 @@ GEM
29
30
  mimemagic
30
31
  http-cookie (1.0.2)
31
32
  domain_name (~> 0.5)
32
- httparty (0.13.7)
33
- json (~> 1.8)
33
+ httparty (0.14.0)
34
34
  multi_xml (>= 0.5.2)
35
- json (1.8.3)
36
- mime-types (2.99.2)
35
+ httpclient (2.8.0)
36
+ mime-types (3.1)
37
+ mime-types-data (~> 3.2015)
38
+ mime-types-data (3.2016.0521)
37
39
  mimemagic (0.3.1)
38
40
  mini_portile2 (2.1.0)
39
41
  minitest (5.3.5)
@@ -48,6 +50,9 @@ GEM
48
50
  nokogiri (~> 1.5)
49
51
  octokit (4.3.0)
50
52
  sawyer (~> 0.7.0, >= 0.5.3)
53
+ percy-client (1.6.0)
54
+ faraday (>= 0.9)
55
+ httpclient (>= 2.6)
51
56
  pivotal-tracker (0.5.13)
52
57
  builder
53
58
  crack
@@ -56,10 +61,10 @@ GEM
56
61
  rest-client (>= 1.8.0)
57
62
  pkg-config (1.1.7)
58
63
  rake (10.4.2)
59
- rest-client (1.8.0)
64
+ rest-client (2.0.0)
60
65
  http-cookie (>= 1.0.2, < 2.0)
61
- mime-types (>= 1.16, < 3.0)
62
- netrc (~> 0.7)
66
+ mime-types (>= 1.16, < 4.0)
67
+ netrc (~> 0.8)
63
68
  ruby-graphviz (1.2.2)
64
69
  safe_yaml (1.0.4)
65
70
  sawyer (0.7.0)
data/bin/flash_flow CHANGED
@@ -25,12 +25,12 @@ case
25
25
  when options[:resolve_manual]
26
26
  FlashFlow::Resolve.new(FlashFlow::Config.configuration.git, FlashFlow::Config.configuration.branch_info_file, logger: FlashFlow::Config.configuration.logger).manual_instructions
27
27
  when options[:merge_status]
28
- FlashFlow::MergeMaster::Status.new(FlashFlow::Config.configuration.issue_tracker, FlashFlow::Config.configuration.branches, FlashFlow::Config.configuration.branch_info_file, FlashFlow::Config.configuration.git, logger: FlashFlow::Config.configuration.logger).status
28
+ FlashFlow::Merge::Status.new(FlashFlow::Config.configuration.issue_tracker, FlashFlow::Config.configuration.branches, FlashFlow::Config.configuration.branch_info_file, FlashFlow::Config.configuration.git, logger: FlashFlow::Config.configuration.logger).status
29
29
  when options[:merge_status_html]
30
- FlashFlow::MergeMaster::Status.new(FlashFlow::Config.configuration.issue_tracker, FlashFlow::Config.configuration.branches, FlashFlow::Config.configuration.branch_info_file, FlashFlow::Config.configuration.git, logger: FlashFlow::Config.configuration.logger).status_html
30
+ FlashFlow::Merge::Status.new(FlashFlow::Config.configuration.issue_tracker, FlashFlow::Config.configuration.branches, FlashFlow::Config.configuration.branch_info_file, FlashFlow::Config.configuration.git, logger: FlashFlow::Config.configuration.logger).status_html
31
31
  when options[:release_branches]
32
- FlashFlow::Deploy.new(options).run_release
32
+ FlashFlow::Merge::Master.new(options).run
33
33
  else
34
- FlashFlow::Deploy.new(options).run
34
+ FlashFlow::Merge::Acceptance.new(options).run
35
35
  FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).stories_pushed
36
36
  end
data/flash_flow.gemspec CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency 'hipchat', "~> 1.5"
22
22
  spec.add_dependency 'pivotal-tracker', "~> 0.5"
23
23
  spec.add_dependency 'ruby-graphviz', "> 0"
24
+ spec.add_dependency 'percy-client'
24
25
 
25
26
  spec.add_development_dependency "bundler", "~> 1.6"
26
27
  spec.add_development_dependency "rake", "> 0"
@@ -82,3 +82,10 @@ branch_info_file: 'your/random/file'
82
82
  # unmergeable_label: unmergeable
83
83
  # do_not_merge_label: 'do not merge'
84
84
  # shippable_label: 'shippable'
85
+
86
+ #release:
87
+ # class:
88
+ # name: 'FlashFlow::Release::Percy'
89
+ # token: <%= ENV['PERCY_TOKEN'] %>
90
+ # repo: # Your github repo. For example, the flash_flow repo is 'flashfunders/flash_flow'
91
+ # api_url: 'https://percy.io/api/v1/'
data/lib/flash_flow.rb CHANGED
@@ -3,7 +3,7 @@ module FlashFlow; end
3
3
  require 'flash_flow/options'
4
4
  require 'flash_flow/install'
5
5
  require 'flash_flow/config'
6
- require 'flash_flow/deploy'
7
6
  require 'flash_flow/issue_tracker'
8
7
  require 'flash_flow/resolve'
9
- require 'flash_flow/merge_master'
8
+ require 'flash_flow/merge'
9
+ require 'flash_flow/release'
@@ -16,7 +16,7 @@ module FlashFlow
16
16
  end
17
17
 
18
18
  ATTRIBUTES = [
19
- :git, :branch_info_file, :log_file, :notifier, :issue_tracker, :lock, :branches
19
+ :git, :branch_info_file, :log_file, :notifier, :issue_tracker, :lock, :branches, :release
20
20
  ]
21
21
 
22
22
  attr_reader *ATTRIBUTES
@@ -55,6 +55,7 @@ module FlashFlow
55
55
  issue_tracker: nil,
56
56
  lock: nil,
57
57
  branches: nil,
58
+ release: nil
58
59
  }
59
60
  end
60
61
 
@@ -13,6 +13,8 @@ module FlashFlow
13
13
  :remove_from_merge, :add_to_merge, :failures, :successes, :removals, :set_resolutions,
14
14
  :to_a, :code_reviewed?, :branch_link
15
15
 
16
+ attr_reader :collection
17
+
16
18
  def initialize(branch_config, filename, git, opts={})
17
19
  @git = git
18
20
  @store = Store.new(filename, git, opts)
@@ -20,14 +22,23 @@ module FlashFlow
20
22
  end
21
23
 
22
24
  def initialize_collection(branch_config, remotes)
23
- collection = Collection.fetch(remotes, branch_config) ||
24
- Collection.from_hash(remotes, backwards_compatible_store['branches'])
25
- collection.mark_all_as_current
26
- collection
25
+ stored_collection = Collection.from_hash(remotes, stored_branches)
26
+
27
+ if ! branch_config.empty?
28
+ collection = Collection.fetch(remotes, branch_config)
29
+ # Order matters. We are marking the PRs as current, not the branches stored in the json
30
+ collection.mark_all_as_current
31
+ collection.reverse_merge(stored_collection)
32
+
33
+ else
34
+ collection = stored_collection
35
+ collection.mark_all_as_current
36
+ collection
37
+ end
27
38
  end
28
39
 
29
40
  def version
30
- backwards_compatible_store['version']
41
+ stored_data['version']
31
42
  end
32
43
 
33
44
  def save!
@@ -37,24 +48,29 @@ module FlashFlow
37
48
  def to_hash
38
49
  {
39
50
  'version' => FlashFlow::VERSION,
40
- 'branches' => merged_branches.to_hash
51
+ 'branches' => @collection.to_hash,
52
+ 'releases' => releases
41
53
  }
42
54
  end
43
55
 
44
- def merged_branches
45
- @collection.reverse_merge(Collection.from_hash({}, backwards_compatible_store['branches']))
56
+ def stored_branches
57
+ @stored_branches ||= stored_data['branches'] || {}
46
58
  end
47
59
 
48
- def backwards_compatible_store
49
- @backwards_compatible_store ||= begin
50
- hash = @store.get
60
+ def releases
61
+ @releases ||= stored_data['releases'] || []
62
+ end
51
63
 
52
- hash.has_key?('branches') ? hash : { 'branches' => hash }
53
- end
64
+ def merged_branches
65
+ @collection.reverse_merge(Collection.from_hash({}, stored_branches))
66
+ end
67
+
68
+ def stored_data
69
+ @stored_data ||= @store.get
54
70
  end
55
71
 
56
72
  def saved_branches
57
- Collection.from_hash(@git.remotes, backwards_compatible_store['branches']).to_a
73
+ Collection.from_hash(@git.remotes, stored_branches).to_a
58
74
  end
59
75
  end
60
76
  end
@@ -63,9 +63,13 @@ module FlashFlow
63
63
  end
64
64
  end
65
65
 
66
- def master_branch_contains?(ref)
66
+ def branch_contains?(branch, ref)
67
67
  run("branch --contains #{ref}", log: CmdRunner::LOG_CMD)
68
- last_stdout.split("\n").detect { |str| str[2..-1] == master_branch }
68
+ last_stdout.split("\n").detect { |str| str[2..-1] == branch }
69
+ end
70
+
71
+ def master_branch_contains?(ref)
72
+ branch_contains?(master_branch, ref)
69
73
  end
70
74
 
71
75
  def in_original_merge_branch
@@ -197,7 +201,7 @@ module FlashFlow
197
201
  run("push #{'-f' if force} #{merge_remote} #{branch}")
198
202
  end
199
203
 
200
- def copy_temp_to_branch(branch, squash_message = nil)
204
+ def copy_temp_to_branch(branch, squash_message = nil)
201
205
  run("checkout #{temp_merge_branch}")
202
206
  run("merge --strategy=ours --no-edit #{branch}")
203
207
  run("checkout #{branch}")
@@ -232,6 +236,20 @@ module FlashFlow
232
236
  end
233
237
  end
234
238
 
239
+ def temp_merge_branch
240
+ "flash_flow/#{merge_branch}"
241
+ end
242
+
243
+ def get_sha(branch)
244
+ run("rev-parse #{branch}")
245
+ last_stdout.strip if last_success?
246
+ end
247
+
248
+ def branch_exists?(branch)
249
+ run("rev-parse --verify #{branch}")
250
+ last_success?
251
+ end
252
+
235
253
  private
236
254
 
237
255
  def squash_commits(branch, commit_message)
@@ -249,14 +267,5 @@ module FlashFlow
249
267
  run("commit -m '#{commit_message}'")
250
268
  end
251
269
 
252
- def branch_exists?(branch)
253
- run("rev-parse --verify #{branch}")
254
- last_success?
255
- end
256
-
257
- def temp_merge_branch
258
- "flash_flow/#{merge_branch}"
259
- end
260
-
261
270
  end
262
271
  end
@@ -59,7 +59,7 @@ module FlashFlow
59
59
  end
60
60
 
61
61
  def get_branches
62
- branch_info_store = Data::Base.new(Config.configuration.branches, Config.configuration.branch_info_file, git, logger: Config.configuration.logger)
62
+ branch_info_store = Data::Base.new({}, Config.configuration.branch_info_file, git, logger: Config.configuration.logger)
63
63
 
64
64
  branch_info_store.saved_branches
65
65
  end
@@ -0,0 +1,8 @@
1
+ module FlashFlow
2
+ module Merge
3
+ end
4
+ end
5
+
6
+ require 'flash_flow/merge/acceptance'
7
+ require 'flash_flow/merge/master'
8
+ require 'flash_flow/merge/status'
@@ -0,0 +1,156 @@
1
+ require 'flash_flow/merge/base'
2
+
3
+ module FlashFlow
4
+ module Merge
5
+ class Acceptance < Base
6
+
7
+ def initialize(opts={})
8
+ super(opts)
9
+
10
+ @data = Data::Base.new(Config.configuration.branches, Config.configuration.branch_info_file, @git, logger: logger)
11
+
12
+ @do_not_merge = opts[:do_not_merge]
13
+ @force = opts[:force]
14
+ @rerere_forget = opts[:rerere_forget]
15
+ @stories = [opts[:stories]].flatten.compact
16
+ end
17
+
18
+ def run
19
+ check_version
20
+ check_repo
21
+ puts "Building #{@local_git.merge_branch}... Log can be found in #{FlashFlow::Config.configuration.log_file}"
22
+ logger.info "\n\n### Beginning #{@local_git.merge_branch} merge ###\n\n"
23
+
24
+ begin
25
+ open_pull_request
26
+
27
+ @lock.with_lock do
28
+ @git.fetch(@git.merge_remote)
29
+ @git.in_original_merge_branch do
30
+ @git.initialize_rerere
31
+ end
32
+
33
+ @git.reset_temp_merge_branch
34
+ @git.in_temp_merge_branch do
35
+ merge_branches(@data.mergeable) do |branch, merger|
36
+ process_result(branch, merger)
37
+ end
38
+ commit_branch_info
39
+ commit_rerere
40
+ end
41
+
42
+ @git.copy_temp_to_branch(@git.merge_branch, commit_message)
43
+ @git.delete_temp_merge_branch
44
+ @git.push(@git.merge_branch, true)
45
+ end
46
+
47
+ print_errors
48
+ logger.info "### Finished #{@local_git.merge_branch} merge ###"
49
+ rescue Lock::Error, OutOfSyncWithRemote => e
50
+ puts 'Failure!'
51
+ puts e.message
52
+ ensure
53
+ @local_git.run("checkout #{@local_git.working_branch}")
54
+ end
55
+ end
56
+
57
+ def commit_branch_info
58
+ @stories.each do |story_id|
59
+ @data.add_story(@git.merge_remote, @git.working_branch, story_id)
60
+ end
61
+ @data.save!
62
+ end
63
+
64
+ def commit_rerere
65
+ current_branches = @data.to_a.select { |branch| !@git.master_branch_contains?(branch.sha) && (Time.now - branch.updated_at < two_weeks) }
66
+ current_rereres = current_branches.map { |branch| branch.resolutions.to_h.values }.flatten
67
+
68
+ @git.commit_rerere(current_rereres)
69
+ end
70
+
71
+ def two_weeks
72
+ 60 * 60 * 24 * 14
73
+ end
74
+
75
+ def process_result(branch, merger)
76
+ case merger.result
77
+ when :deleted
78
+ @data.mark_deleted(branch)
79
+ @notifier.deleted_branch(branch) unless is_working_branch(branch)
80
+
81
+ when :success
82
+ branch.sha = merger.sha
83
+ @data.mark_success(branch)
84
+ @data.set_resolutions(branch, merger.resolutions)
85
+
86
+ when :conflict
87
+ if is_working_branch(branch)
88
+ @data.mark_failure(branch, merger.conflict_sha)
89
+ else
90
+ @data.mark_failure(branch, nil)
91
+ @notifier.merge_conflict(branch)
92
+ end
93
+ end
94
+ end
95
+
96
+ def is_working_branch(branch)
97
+ branch.ref == @git.working_branch
98
+ end
99
+
100
+ def open_pull_request
101
+ return false if [@local_git.master_branch, @local_git.merge_branch].include?(@local_git.working_branch)
102
+
103
+ # TODO - This should use the actual remote for the branch we're on
104
+ @local_git.push(@local_git.working_branch, @force)
105
+ raise OutOfSyncWithRemote.new("Your branch is out of sync with the remote. If you want to force push, run 'flash_flow -f'") unless @local_git.last_success?
106
+
107
+ # TODO - This should use the actual remote for the branch we're on
108
+ if @do_not_merge
109
+ @data.remove_from_merge(@local_git.merge_remote, @local_git.working_branch)
110
+ else
111
+ @data.add_to_merge(@local_git.merge_remote, @local_git.working_branch)
112
+ end
113
+ end
114
+
115
+ def print_errors
116
+ puts format_errors
117
+ end
118
+
119
+ def format_errors
120
+ errors = []
121
+ branch_not_merged = nil
122
+ @data.failures.each do |branch|
123
+ if branch.ref == @local_git.working_branch
124
+ branch_not_merged = "ERROR: Your branch did not merge to #{@local_git.merge_branch}. Run 'flash_flow --resolve', fix the merge conflict(s) and then re-run this script\n"
125
+ else
126
+ errors << "WARNING: Unable to merge branch #{branch.remote}/#{branch.ref} to #{@local_git.merge_branch} due to conflicts."
127
+ end
128
+ end
129
+ errors << branch_not_merged if branch_not_merged
130
+
131
+ if errors.empty?
132
+ "Success!"
133
+ else
134
+ errors.join("\n")
135
+ end
136
+ end
137
+
138
+ def commit_message
139
+ message =<<-EOS
140
+ Flash Flow run from branch: #{@local_git.working_branch}
141
+
142
+ Merged branches:
143
+ #{@data.successes.empty? ? 'None' : @data.successes.sort_by(&:merge_order).map(&:ref).join("\n")}
144
+
145
+ Failed branches:
146
+ #{@data.failures.empty? ? 'None' : @data.failures.map(&:ref).join("\n")}
147
+
148
+ Removed branches:
149
+ #{@data.removals.empty? ? 'None' : @data.removals.map(&:ref).join("\n")}
150
+ EOS
151
+ message.gsub(/'/, '')
152
+ end
153
+
154
+ end
155
+ end
156
+ end