git_reflow 0.7.4 → 0.7.5

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: 64b5781cd74b023d9f5a94c91949cac9528636f7
4
- data.tar.gz: f509d8459ca0b092d4bd710722987613bfb6cd5f
3
+ metadata.gz: c6773486dad59a6ec3d71cd0047234005b8d06f1
4
+ data.tar.gz: 07665f57499a6aab0bd31218a0bf8d5e147c8581
5
5
  SHA512:
6
- metadata.gz: 0ec9acd3327e943147292d1a6f794b23ae5cedbc80250e4c29c3884d26d7382f4b972ef0151ece4ea989e524721248a02ffc2df453c1c1bd094c7f1cd6de62bd
7
- data.tar.gz: 860b02e97c65b9121ec31428ee8218a463fe5ccfab846767ee7312891a2321853e053902448bd29111f65200153b0cca775b4432d674465b5d6422239c2c9b02
6
+ metadata.gz: 930b0d1bb58185c59c0d759ef2aad44a10d2b2481bd78843f842c4b703c4b4770a29574cb34be888d01035db40fd66f10df45e343427c2fafee37e06791a1602
7
+ data.tar.gz: 8aa0cbcf0db37dcbb527f2275cef16125d7f736a18787700e1fc16c2934b68ac75f0f0e2713d1790c5e90efca256926be9df200f3baa61ae8aae427411facd1c
data/.gitignore CHANGED
@@ -2,3 +2,4 @@ pkg/*
2
2
  **/.DS_Store
3
3
  .rspec
4
4
  gemfiles
5
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git_reflow (0.7.4)
4
+ git_reflow (0.7.5)
5
5
  colorize (>= 0.7.0)
6
6
  github_api (= 0.12.4)
7
7
  gli (= 2.13.2)
@@ -104,13 +104,13 @@ PLATFORMS
104
104
 
105
105
  DEPENDENCIES
106
106
  appraisal (= 1.0.3)
107
- bundler
107
+ bundler (~> 1.11)
108
108
  chronic
109
109
  git_reflow!
110
110
  pry-byebug
111
- rake
111
+ rake (~> 10.0)
112
112
  rdoc
113
- rspec (~> 3.0.0)
113
+ rspec (~> 3.0)
114
114
  webmock
115
115
  wwtd (= 0.7.0)
116
116
 
data/Rakefile CHANGED
@@ -1,11 +1,8 @@
1
1
  #!/usr/bin/env rake
2
- require 'rake'
3
- require 'bundler/gem_tasks'
4
- require 'bundler/setup'
5
- require 'rspec/core/rake_task'
6
-
7
- Dir[File.join(File.dirname(__FILE__),'lib/tasks/*.rake')].each { |f| load f }
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
8
4
 
9
5
  RSpec::Core::RakeTask.new(:spec)
10
6
 
11
- task :default => [:spec]
7
+ task :default => :spec
8
+
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "git_reflow"
5
+
6
+ require "irb"
7
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
File without changes
data/git_reflow.gemspec CHANGED
@@ -10,22 +10,22 @@ spec = Gem::Specification.new do |s|
10
10
  s.summary = "A better git process"
11
11
  s.description = "Git Reflow manages your git workflow."
12
12
  s.platform = Gem::Platform::RUBY
13
- s.files = `git ls-files`.split("\n")
13
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
14
14
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
16
  s.has_rdoc = true
17
17
  s.extra_rdoc_files = ['README.rdoc']
18
- s.bindir = 'bin'
19
- s.require_paths << 'lib'
18
+ s.bindir = "exe"
19
+ s.require_paths = ["lib"]
20
20
  s.rdoc_options << '--title' << 'git_reflow' << '--main' << 'README.rdoc' << '-ri'
21
21
 
22
22
  s.add_development_dependency('appraisal', '1.0.3')
23
- s.add_development_dependency('bundler')
23
+ s.add_development_dependency('bundler', "~> 1.11")
24
24
  s.add_development_dependency('chronic')
25
25
  s.add_development_dependency('pry-byebug')
26
- s.add_development_dependency('rake')
26
+ s.add_development_dependency('rake', "~> 10.0")
27
27
  s.add_development_dependency('rdoc')
28
- s.add_development_dependency('rspec', '~> 3.0.0')
28
+ s.add_development_dependency('rspec', "~> 3.0")
29
29
  s.add_development_dependency('webmock')
30
30
  s.add_development_dependency('wwtd', '0.7.0')
31
31
 
@@ -15,11 +15,15 @@ command :setup do |c|
15
15
  end
16
16
 
17
17
  choose do |menu|
18
- menu.header = "Available remote Git Server services:"
18
+ menu.header = "Available remote Git Server services"
19
19
  menu.prompt = "Which service would you like to use for this project? "
20
20
 
21
21
  menu.choice('GitHub') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'GitHub', silent: false }) }
22
22
  menu.choice('BitBucket (team-owned repos only)') { GitReflow::GitServer.connect reflow_options.merge({ provider: 'BitBucket', silent: false }) }
23
23
  end
24
+
25
+ GitReflow::Config.add "constants.minimumApprovals", ask("Set the minimum number of approvals (leaving blank will require approval from all commenters): "), local: reflow_options[:project_only]
26
+ GitReflow::Config.add "constants.approvalRegex", GitReflow::GitServer::PullRequest::DEFAULT_APPROVAL_REGEX, local: reflow_options[:project_only]
27
+
24
28
  end
25
29
  end
@@ -52,7 +52,7 @@ module GitReflow
52
52
 
53
53
  def approvals
54
54
  pull_last_committed_at = get_committed_time(self.head.sha)
55
- comment_authors(with: LGTM, after: pull_last_committed_at)
55
+ comment_authors(with: self.class.approval_regex, after: pull_last_committed_at)
56
56
  end
57
57
 
58
58
  def comments
@@ -63,7 +63,19 @@ module GitReflow
63
63
  end
64
64
 
65
65
  def last_comment
66
- "#{comments.last.body.inspect}"
66
+ if comments.last.nil?
67
+ ""
68
+ else
69
+ "#{comments.last.body.inspect}"
70
+ end
71
+ end
72
+
73
+ def approved?
74
+ if self.class.minimum_approvals.to_i == 0
75
+ super
76
+ else
77
+ approvals.size >= self.class.minimum_approvals.to_i and !last_comment.match(self.class.approval_regex).nil?
78
+ end
67
79
  end
68
80
 
69
81
  def build
@@ -3,6 +3,20 @@ module GitReflow
3
3
  class PullRequest
4
4
  attr_accessor :description, :html_url, :feature_branch_name, :base_branch_name, :build_status, :source_object, :number
5
5
 
6
+ DEFAULT_APPROVAL_REGEX = /(?i-mx:lgtm|looks good to me|:\+1:|:thumbsup:|:shipit:)/
7
+
8
+ def self.minimum_approvals
9
+ "#{GitReflow::Config.get('constants.minimumApprovals')}"
10
+ end
11
+
12
+ def self.approval_regex
13
+ if "#{GitReflow::Config.get('constants.approvalRegex')}".length > 0
14
+ Regexp.new("#{GitReflow::Config.get('constants.approvalRegex')}")
15
+ else
16
+ DEFAULT_APPROVAL_REGEX
17
+ end
18
+ end
19
+
6
20
  def initialize(attributes)
7
21
  raise "PullRequest#initialize must be implemented"
8
22
  end
@@ -35,13 +49,47 @@ module GitReflow
35
49
  reviewers - approvals
36
50
  end
37
51
 
52
+ def approved?
53
+ has_comments_or_approvals = (has_comments? or approvals.any?)
54
+
55
+ case self.class.minimum_approvals
56
+ when "0"
57
+ true
58
+ when "", nil
59
+ # Approvals from every commenter
60
+ has_comments_or_approvals && reviewers_pending_response.empty?
61
+ else
62
+ approvals.size >= self.class.minimum_approvals.to_i
63
+ end
64
+ end
65
+
66
+ def rejection_message
67
+ if !build_status.nil? and build_status != "success"
68
+ "#{build.description}: #{build.url}"
69
+ elsif !approval_minimums_reached?
70
+ "You need approval from at least #{self.class.minimum_approvals} users!"
71
+ elsif !all_comments_addressed?
72
+ # Maybe add what the last comment is?
73
+ "The last comment is holding up approval:\n#{last_comment}"
74
+ elsif reviewers_pending_response.count > 0
75
+ "You still need a LGTM from: #{reviewers_pending_response.join(', ')}"
76
+ else
77
+ "Your code has not been reviewed yet."
78
+ end
79
+ end
80
+
81
+ def approval_minimums_reached?
82
+ self.class.minimum_approvals.length <= 0 or approvals.size >= self.class.minimum_approvals.to_i
83
+ end
84
+
85
+ def all_comments_addressed?
86
+ self.class.minimum_approvals.length <= 0 or last_comment.match(self.class.approval_regex)
87
+ end
88
+
38
89
  def good_to_merge?(force: false)
39
90
  return true if force
40
- has_comments_or_approvals = (has_comments? or approvals.any?)
41
91
 
42
- force == true or (
43
- (build_status.nil? or build_status == "success") and
44
- (has_comments_or_approvals and reviewers_pending_response.empty?))
92
+ (build_status.nil? or build_status == "success") and approved?
45
93
  end
46
94
 
47
95
  def display_pull_request_summary
@@ -1,3 +1,3 @@
1
1
  module GitReflow
2
- VERSION = "0.7.4"
2
+ VERSION = "0.7.5"
3
3
  end
data/lib/git_reflow.rb CHANGED
@@ -21,8 +21,6 @@ module GitReflow
21
21
 
22
22
  extend self
23
23
 
24
- LGTM = /lgtm|looks good to me|:\+1:|:thumbsup:|:shipit:/i
25
-
26
24
  def status(destination_branch)
27
25
  pull_request = git_server.find_open_pull_request( :from => current_branch, :to => destination_branch )
28
26
 
@@ -156,12 +154,8 @@ module GitReflow
156
154
  else
157
155
  say "There were problems commiting your feature... please check the errors above and try again.", :error
158
156
  end
159
- elsif !existing_pull_request.build_status.nil? and existing_pull_request.build_status != "success"
160
- say "#{existing_pull_request.build.description}: #{existing_pull_request.build.url}", :deliver_halted
161
- elsif existing_pull_request.reviewers_pending_response.count > 0
162
- say "You still need a LGTM from: #{existing_pull_request.reviewers_pending_response.join(', ')}", :deliver_halted
163
157
  else
164
- say "Your code has not been reviewed yet.", :deliver_halted
158
+ say existing_pull_request.rejection_message, :deliver_halted
165
159
  end
166
160
  end
167
161
 
@@ -18,6 +18,11 @@ describe GitReflow do
18
18
  let(:existing_pull_request) { GitReflow::GitServer::GitHub::PullRequest.new existing_pull_requests.first }
19
19
 
20
20
  before do
21
+
22
+ # Stubbing out numlgtm value to test all reviewers in gitconfig file
23
+ allow(GitReflow::Config).to receive(:get).with("constants.minimumApprovals").and_return('')
24
+ allow(GitReflow::Config).to receive(:get).and_call_original
25
+
21
26
  HighLine.any_instance.stub(:ask) do |terminal, question|
22
27
  values = {
23
28
  "Please enter your GitHub username: " => user,
@@ -211,18 +216,18 @@ describe GitReflow do
211
216
 
212
217
  context "and pull request exists for the feature branch to the destination branch" do
213
218
  before do
214
- github.stub(:get_build_status).and_return(build_status)
215
- github.should_receive(:find_open_pull_request).and_return(existing_pull_request)
216
- existing_pull_request.stub(:has_comments?).and_return(true)
217
- github.stub(:reviewers).and_return(['codenamev'])
219
+ allow(github).to receive(:build_status).and_return(build_status)
220
+ allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
221
+ allow(existing_pull_request).to receive(:has_comments?).and_return(true)
222
+ allow(github).to receive(:reviewers).and_return(['codenamev'])
218
223
  end
219
224
 
220
225
  context 'and build status is not "success"' do
221
226
  let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)' }) }
222
227
 
223
228
  before do
224
- existing_pull_request.stub(:build).and_return(build_status)
225
- existing_pull_request.stub(:has_comments?).and_return(true)
229
+ allow(existing_pull_request).to receive(:build).and_return(build_status)
230
+ allow(existing_pull_request).to receive(:has_comments?).and_return(true)
226
231
  end
227
232
 
228
233
  it "halts delivery and notifies user of a failed build" do
@@ -236,8 +241,8 @@ describe GitReflow do
236
241
 
237
242
  before do
238
243
  # stubbing unrelated results so we can just test that it made it insdide the conditional block
239
- existing_pull_request.stub(:has_comments?).and_return(true)
240
- existing_pull_request.stub(:reviewers).and_return([])
244
+ allow(existing_pull_request).to receive(:has_comments?).and_return(true)
245
+ allow(existing_pull_request).to receive(:reviewers).and_return([])
241
246
  GitReflow.stub(:update_destination).and_return(true)
242
247
  GitReflow.stub(:merge_feature_branch).and_return(true)
243
248
  GitReflow.stub(:append_to_squashed_commit_message).and_return(true)
@@ -269,6 +274,34 @@ describe GitReflow do
269
274
  subject
270
275
  end
271
276
 
277
+ context "build status failure, testing description and target_url" do
278
+ let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)', target_url: "www.error.com" }) }
279
+
280
+ before do
281
+ existing_pull_request.stub(:build).and_return(build_status)
282
+ existing_pull_request.stub(:reviewers).and_return(lgtm_comment_authors)
283
+ existing_pull_request.stub(:has_comments?).and_return(true)
284
+ end
285
+
286
+ it "halts delivery and notifies user of a failed build" do
287
+ expect { subject }.to have_said "#{build_status.description}: #{build_status.url}", :deliver_halted
288
+ end
289
+ end
290
+
291
+ context "build status nil" do
292
+ let(:build_status) { nil }
293
+
294
+ before do
295
+ github.stub(:build).and_return(build_status)
296
+ existing_pull_request.stub(:reviewers_pending_response).and_return([])
297
+ existing_pull_request.stub(:has_comments_or_approvals).and_return(true)
298
+ end
299
+
300
+ it "commits the changes if the build status is nil but has comments/approvals and no pending response" do
301
+ expect{ subject }.to have_said 'Merge complete!', :success
302
+ end
303
+ end
304
+
272
305
  context "and the pull request has no body" do
273
306
  let(:first_commit_message) { "We'll do it live." }
274
307
 
@@ -325,7 +358,8 @@ describe GitReflow do
325
358
 
326
359
  context "not always" do
327
360
  before do
328
- GitReflow::Config.stub(:get) { "false" }
361
+ GitReflow::Config.stub(:get).with("reflow.always-deploy-and-cleanup").and_return("false")
362
+ GitReflow::Config.stub(:get).and_call_original
329
363
  end
330
364
 
331
365
  it "pushes local squash merged base branch to remote repo" do
@@ -343,7 +377,8 @@ describe GitReflow do
343
377
 
344
378
  context "always" do
345
379
  before do
346
- GitReflow::Config.stub(:get) { "true" }
380
+ GitReflow::Config.stub(:get).with("reflow.always-deploy-and-cleanup").and_return("true")
381
+ GitReflow::Config.stub(:get).and_call_original
347
382
  end
348
383
 
349
384
  it "pushes local squash merged base branch to remote repo" do