flash_flow 1.3.2.1 → 1.4.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: 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