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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +4 -4
- data/Rakefile +4 -7
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/{bin → exe}/git-reflow +0 -0
- data/git_reflow.gemspec +7 -7
- data/lib/git_reflow/commands/setup.rb +5 -1
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +14 -2
- data/lib/git_reflow/git_server/pull_request.rb +52 -4
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow.rb +1 -7
- data/spec/git_reflow_spec.rb +45 -10
- data/spec/lgtm_git_reflow_spec.rb +496 -0
- data/spec/lib/git_server/git_hub/pull_request_spec.rb +166 -15
- data/spec/lib/git_server/pull_request_spec.rb +321 -22
- metadata +18 -17
- data/bin/gitreflow-common +0 -314
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6773486dad59a6ec3d71cd0047234005b8d06f1
|
4
|
+
data.tar.gz: 07665f57499a6aab0bd31218a0bf8d5e147c8581
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 930b0d1bb58185c59c0d759ef2aad44a10d2b2481bd78843f842c4b703c4b4770a29574cb34be888d01035db40fd66f10df45e343427c2fafee37e06791a1602
|
7
|
+
data.tar.gz: 8aa0cbcf0db37dcbb527f2275cef16125d7f736a18787700e1fc16c2934b68ac75f0f0e2713d1790c5e90efca256926be9df200f3baa61ae8aae427411facd1c
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
git_reflow (0.7.
|
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
|
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
|
3
|
-
require
|
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 =>
|
7
|
+
task :default => :spec
|
8
|
+
|
data/bin/console
ADDED
data/bin/setup
ADDED
data/{bin → exe}/git-reflow
RENAMED
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("\
|
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 =
|
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 =
|
19
|
-
s.require_paths
|
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',
|
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:
|
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
|
-
|
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
|
-
|
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
|
data/lib/git_reflow/version.rb
CHANGED
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
|
158
|
+
say existing_pull_request.rejection_message, :deliver_halted
|
165
159
|
end
|
166
160
|
end
|
167
161
|
|
data/spec/git_reflow_spec.rb
CHANGED
@@ -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.
|
215
|
-
github.
|
216
|
-
existing_pull_request.
|
217
|
-
github.
|
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.
|
225
|
-
existing_pull_request.
|
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.
|
240
|
-
existing_pull_request.
|
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)
|
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)
|
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
|