git_reflow 0.6.7 → 0.7.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 +4 -4
- data/Gemfile.lock +11 -9
- data/README.rdoc +3 -1
- data/bin/git-reflow +0 -11
- data/bin/gitreflow-common +1 -1
- data/git_reflow.gemspec +3 -2
- data/lib/git_reflow.rb +13 -60
- data/lib/git_reflow/commands/deliver.rb +1 -2
- data/lib/git_reflow/commands/start.rb +0 -6
- data/lib/git_reflow/config.rb +15 -14
- data/lib/git_reflow/git_server.rb +14 -4
- data/lib/git_reflow/git_server/base.rb +0 -39
- data/lib/git_reflow/git_server/bit_bucket.rb +15 -80
- data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -0
- data/lib/git_reflow/git_server/git_hub.rb +18 -75
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +108 -0
- data/lib/git_reflow/git_server/pull_request.rb +97 -0
- data/lib/git_reflow/version.rb +1 -1
- data/spec/fixtures/issues/comment.json.erb +27 -0
- data/spec/fixtures/issues/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/comment.json.erb +45 -0
- data/spec/fixtures/pull_requests/comments.json.erb +15 -0
- data/spec/fixtures/pull_requests/commits.json +29 -0
- data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
- data/spec/fixtures/pull_requests/pull_request.json +19 -0
- data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
- data/spec/fixtures/pull_requests/pull_requests.json +19 -0
- data/spec/fixtures/repositories/commit.json.erb +53 -0
- data/spec/fixtures/repositories/commits.json.erb +13 -0
- data/spec/git_reflow_spec.rb +32 -25
- data/spec/lib/git_reflow/config_spec.rb +22 -6
- data/spec/lib/git_server/bit_bucket_spec.rb +5 -34
- data/spec/lib/git_server/git_hub/pull_request_spec.rb +319 -0
- data/spec/lib/git_server/git_hub_spec.rb +17 -25
- data/spec/lib/git_server/pull_request_spec.rb +93 -0
- data/spec/support/command_line_helpers.rb +16 -1
- data/spec/support/fake_github.rb +128 -0
- data/spec/support/fixtures.rb +52 -6
- data/spec/support/github_helpers.rb +22 -12
- metadata +47 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b04665f9b041b4458192a789b097f5c455f5322
|
4
|
+
data.tar.gz: e1f40457e04fdf6f3e0f6876bdbd00ed2983f5b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90869eb8058b2de453b8790520daf94e5d47ae63010b05cf1065c2590c3ff2138774b58360708d399a91cfac9527eeb71454b0d838a7ad001e5ee30ca6e2e797
|
7
|
+
data.tar.gz: 93640654d91e1e1c1d23be975c15df7346a42df35c044e02e444917d8f059b788cb4eeee7536ffd8cacaa46d9384ba8e9f98d54b92d175eb1ae9c21304bc7331
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
git_reflow (0.
|
4
|
+
git_reflow (0.7.0)
|
5
5
|
colorize (>= 0.7.0)
|
6
|
-
github_api (= 0.12.
|
7
|
-
gli (= 2.
|
6
|
+
github_api (= 0.12.4)
|
7
|
+
gli (= 2.13.2)
|
8
8
|
highline
|
9
9
|
httpclient
|
10
10
|
json_pure
|
@@ -21,6 +21,7 @@ GEM
|
|
21
21
|
byebug (4.0.1)
|
22
22
|
columnize (= 0.9.0)
|
23
23
|
rb-readline (= 0.5.2)
|
24
|
+
chronic (0.10.2)
|
24
25
|
coderay (1.1.0)
|
25
26
|
colorize (0.7.7)
|
26
27
|
columnize (0.9.0)
|
@@ -31,19 +32,19 @@ GEM
|
|
31
32
|
diff-lcs (1.2.5)
|
32
33
|
faraday (0.9.1)
|
33
34
|
multipart-post (>= 1.2, < 3)
|
34
|
-
faraday_middleware (0.9.
|
35
|
+
faraday_middleware (0.9.2)
|
35
36
|
faraday (>= 0.7.4, < 0.10)
|
36
|
-
github_api (0.12.
|
37
|
+
github_api (0.12.4)
|
37
38
|
addressable (~> 2.3)
|
38
39
|
descendants_tracker (~> 0.0.4)
|
39
40
|
faraday (~> 0.8, < 0.10)
|
40
|
-
hashie (>= 3.
|
41
|
+
hashie (>= 3.4)
|
41
42
|
multi_json (>= 1.7.5, < 2.0)
|
42
|
-
nokogiri (~> 1.6.
|
43
|
+
nokogiri (~> 1.6.6)
|
43
44
|
oauth2
|
44
|
-
gli (2.
|
45
|
+
gli (2.13.2)
|
45
46
|
hashie (3.4.2)
|
46
|
-
highline (1.7.
|
47
|
+
highline (1.7.7)
|
47
48
|
httpclient (2.6.0.1)
|
48
49
|
json_pure (1.8.2)
|
49
50
|
jwt (1.5.1)
|
@@ -106,6 +107,7 @@ PLATFORMS
|
|
106
107
|
DEPENDENCIES
|
107
108
|
appraisal (= 1.0.3)
|
108
109
|
bundler
|
110
|
+
chronic
|
109
111
|
git_reflow!
|
110
112
|
pry-byebug
|
111
113
|
rake
|
data/README.rdoc
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= git-reflow (2015 Fukuoka Ruby Award Winner)
|
2
2
|
|
3
|
+
{<img src="https://circleci.com/gh/reenhanced/gitreflow/tree/master.svg?style=svg" alt="Circle CI" />}[https://circleci.com/gh/reenhanced/gitreflow/tree/master]
|
4
|
+
|
3
5
|
http://reenhanced.com/reflow/git-reflow-deliver.gif
|
4
6
|
|
5
7
|
If your workflow looks like this:
|
@@ -301,7 +303,7 @@ http://reenhanced.com/images/reflow.png
|
|
301
303
|
* If you make a new commit in your branch, you require another review.
|
302
304
|
|
303
305
|
* All participants in a pull request must approve the pull request.
|
304
|
-
If 2
|
306
|
+
If 2 people comment, you need 2 'LGTM's before the code is ready to merge.
|
305
307
|
|
306
308
|
* Once approved, your feature branch is squash merged to master.
|
307
309
|
This makes the history of the master branch extremely clean and easy to follow.
|
data/bin/git-reflow
CHANGED
@@ -1,15 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# 1.9 adds realpath to resolve symlinks; 1.8 doesn't
|
3
|
-
# have this method, so we add it so we get resolved symlinks
|
4
|
-
# and compatibility
|
5
|
-
unless File.respond_to? :realpath
|
6
|
-
class File #:nodoc:
|
7
|
-
def self.realpath path
|
8
|
-
return realpath(File.readlink(path)) if symlink?(path)
|
9
|
-
path
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
2
|
$: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
|
14
3
|
require 'rubygems'
|
15
4
|
require 'gli'
|
data/bin/gitreflow-common
CHANGED
@@ -259,7 +259,7 @@ require_clean_working_tree() {
|
|
259
259
|
die "fatal: Working tree contains unstaged changes. Aborting."
|
260
260
|
fi
|
261
261
|
if [ $result -eq 2 ]; then
|
262
|
-
die "fatal: Index contains
|
262
|
+
die "fatal: Index contains uncommitted changes. Aborting."
|
263
263
|
fi
|
264
264
|
}
|
265
265
|
|
data/git_reflow.gemspec
CHANGED
@@ -21,6 +21,7 @@ spec = Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_development_dependency('appraisal', '1.0.3')
|
23
23
|
s.add_development_dependency('bundler')
|
24
|
+
s.add_development_dependency('chronic')
|
24
25
|
s.add_development_dependency('pry-byebug')
|
25
26
|
s.add_development_dependency('rake')
|
26
27
|
s.add_development_dependency('rdoc')
|
@@ -29,11 +30,11 @@ spec = Gem::Specification.new do |s|
|
|
29
30
|
s.add_development_dependency('wwtd', '0.7.0')
|
30
31
|
|
31
32
|
s.add_dependency('colorize', '>= 0.7.0')
|
32
|
-
s.add_dependency('gli', '2.
|
33
|
+
s.add_dependency('gli', '2.13.2')
|
33
34
|
s.add_dependency('highline')
|
34
35
|
s.add_dependency('httpclient')
|
35
36
|
s.add_dependency('json_pure')
|
36
|
-
s.add_dependency('github_api', '0.12.
|
37
|
+
s.add_dependency('github_api', '0.12.4')
|
37
38
|
s.add_dependency('reenhanced_bitbucket_api', '0.3.2')
|
38
39
|
|
39
40
|
s.post_install_message = "You need to setup your GitHub OAuth token\nPlease run 'git-reflow setup'"
|
data/lib/git_reflow.rb
CHANGED
@@ -31,7 +31,7 @@ module GitReflow
|
|
31
31
|
puts "[notice] Run 'git reflow review #{destination_branch}' to start the review process"
|
32
32
|
else
|
33
33
|
puts "Here's the status of your review:"
|
34
|
-
display_pull_request_summary
|
34
|
+
pull_request.display_pull_request_summary
|
35
35
|
ask_to_open_in_browser(pull_request.html_url)
|
36
36
|
end
|
37
37
|
end
|
@@ -46,7 +46,7 @@ module GitReflow
|
|
46
46
|
existing_pull_request = git_server.find_open_pull_request( from: current_branch, to: options['base'] )
|
47
47
|
if existing_pull_request
|
48
48
|
puts "A pull request already exists for these branches:"
|
49
|
-
display_pull_request_summary
|
49
|
+
existing_pull_request.display_pull_request_summary
|
50
50
|
ask_to_open_in_browser(existing_pull_request.html_url)
|
51
51
|
else
|
52
52
|
pull_request = git_server.create_pull_request(title: options['title'],
|
@@ -78,23 +78,20 @@ module GitReflow
|
|
78
78
|
say "No pull request exists for #{remote_user}:#{current_branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted
|
79
79
|
else
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
else
|
87
|
-
"#{get_first_commit_message}"
|
88
|
-
end
|
81
|
+
commit_message = if "#{existing_pull_request.description}".length > 0
|
82
|
+
existing_pull_request.description
|
83
|
+
else
|
84
|
+
"#{get_first_commit_message}"
|
85
|
+
end
|
89
86
|
|
90
|
-
if
|
87
|
+
if existing_pull_request.good_to_merge?(force: options['skip_lgtm'])
|
91
88
|
puts "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.feature_branch_name}' into '#{existing_pull_request.base_branch_name}'"
|
92
89
|
|
93
90
|
update_destination(base_branch)
|
94
91
|
merge_feature_branch(feature_branch,
|
95
92
|
:destination_branch => base_branch,
|
96
93
|
:pull_request_number => existing_pull_request.number,
|
97
|
-
:lgtm_authors =>
|
94
|
+
:lgtm_authors => existing_pull_request.approvals,
|
98
95
|
:message => commit_message)
|
99
96
|
committed = run_command_with_label 'git commit', with_system: true
|
100
97
|
|
@@ -117,10 +114,10 @@ module GitReflow
|
|
117
114
|
else
|
118
115
|
say "There were problems commiting your feature... please check the errors above and try again.", :error
|
119
116
|
end
|
120
|
-
elsif !
|
121
|
-
say "#{
|
122
|
-
elsif
|
123
|
-
say "You still need a LGTM from: #{
|
117
|
+
elsif !existing_pull_request.build_status.nil? and existing_pull_request.build_status != "success"
|
118
|
+
say "#{existing_pull_request.build.description}: #{existing_pull_request.build.url}", :deliver_halted
|
119
|
+
elsif existing_pull_request.reviewers_pending_response.count > 0
|
120
|
+
say "You still need a LGTM from: #{existing_pull_request.reviewers_pending_response.join(', ')}", :deliver_halted
|
124
121
|
else
|
125
122
|
say "Your code has not been reviewed yet.", :deliver_halted
|
126
123
|
end
|
@@ -137,48 +134,4 @@ module GitReflow
|
|
137
134
|
@git_server ||= GitServer.connect provider: GitReflow::Config.get('reflow.git-server').strip, silent: true
|
138
135
|
end
|
139
136
|
|
140
|
-
def display_pull_request_summary(pull_request)
|
141
|
-
summary_data = {
|
142
|
-
"branches" => "#{pull_request.feature_branch_name} -> #{pull_request.base_branch_name}",
|
143
|
-
"number" => pull_request.number,
|
144
|
-
"url" => pull_request.html_url
|
145
|
-
}
|
146
|
-
|
147
|
-
notices = ""
|
148
|
-
reviewed_by = git_server.reviewers(pull_request).map {|author| author.colorize(:red) }
|
149
|
-
|
150
|
-
# check for CI build status
|
151
|
-
status = git_server.get_build_status pull_request.build_status
|
152
|
-
if status
|
153
|
-
notices << "[notice] Your build status is not successful: #{status.target_url}.\n" unless status.state == "success"
|
154
|
-
summary_data.merge!( "Build status" => git_server.colorized_build_description(status) )
|
155
|
-
end
|
156
|
-
|
157
|
-
# check for needed lgtm's
|
158
|
-
if git_server.reviewers(pull_request).any?
|
159
|
-
approvals = git_server.approvals(pull_request)
|
160
|
-
pending = git_server.reviewers_pending_response(pull_request)
|
161
|
-
last_comment = git_server.last_comment_for_pull_request(pull_request)
|
162
|
-
|
163
|
-
summary_data.merge!("Last comment" => last_comment)
|
164
|
-
|
165
|
-
if approvals.any?
|
166
|
-
reviewed_by.map! { |author| approvals.include?(author.uncolorize) ? author.colorize(:green) : author }
|
167
|
-
end
|
168
|
-
|
169
|
-
notices << "[notice] You still need a LGTM from: #{pending.join(', ')}\n" if pending.any?
|
170
|
-
else
|
171
|
-
notices << "[notice] No one has reviewed your pull request.\n"
|
172
|
-
end
|
173
|
-
|
174
|
-
summary_data['reviewed by'] = reviewed_by.join(', ')
|
175
|
-
|
176
|
-
padding_size = summary_data.keys.max_by(&:size).size + 2
|
177
|
-
summary_data.keys.sort.each do |name|
|
178
|
-
string_format = " %-#{padding_size}s %s\n"
|
179
|
-
printf string_format, "#{name}:", summary_data[name]
|
180
|
-
end
|
181
|
-
|
182
|
-
puts "\n#{notices}" unless notices.empty?
|
183
|
-
end
|
184
137
|
end
|
@@ -2,10 +2,9 @@ desc 'deliver your feature branch'
|
|
2
2
|
long_desc 'merge your feature branch down to your base branch, and cleanup your feature branch'
|
3
3
|
|
4
4
|
command :deliver do |c|
|
5
|
-
c.desc 'skip the lgtm checks and deliver your feature branch'
|
6
|
-
c.switch [:f, :'skip-lgtm']
|
7
5
|
c.desc 'merge your feature branch down to your base branch, and cleanup your feature branch'
|
8
6
|
c.arg_name 'base_branch - the branch you want to merge into'
|
7
|
+
c.switch [:f, :'skip-lgtm'], desc: 'skip the lgtm checks and deliver your feature branch'
|
9
8
|
c.action do |global_options,options,args|
|
10
9
|
deliver_options = {'base' => nil, 'head' => nil, 'skip_lgtm' => options[:'skip-lgtm']}
|
11
10
|
case args.length
|
@@ -7,12 +7,6 @@ long_desc <<LONGTIME
|
|
7
7
|
LONGTIME
|
8
8
|
arg_name '[new-feature-branch-name] - name of the new feature branch'
|
9
9
|
command :start do |c|
|
10
|
-
c.desc 'Describe a switch to list'
|
11
|
-
c.switch :s
|
12
|
-
|
13
|
-
c.desc 'Describe a flag to list'
|
14
|
-
c.default_value 'default'
|
15
|
-
c.flag :f
|
16
10
|
c.action do |global_options, options, args|
|
17
11
|
if args.empty?
|
18
12
|
raise "usage: git-reflow start [new-branch-name]"
|
data/lib/git_reflow/config.rb
CHANGED
@@ -2,39 +2,40 @@ module GitReflow
|
|
2
2
|
module Config
|
3
3
|
extend self
|
4
4
|
|
5
|
-
def get(key,
|
6
|
-
if
|
5
|
+
def get(key, reload: false, all: false, local: false)
|
6
|
+
if reload == false and cached_key_value = instance_variable_get(:"@#{key.tr('.-', '_')}")
|
7
7
|
cached_key_value
|
8
8
|
else
|
9
|
-
|
10
|
-
|
9
|
+
local = local ? '--local ' : ''
|
10
|
+
if all
|
11
|
+
new_value = GitReflow::Sandbox.run "git config #{local}--get-all #{key}", loud: false
|
11
12
|
else
|
12
|
-
new_value = GitReflow::Sandbox.run "git config --get #{key}", loud: false
|
13
|
+
new_value = GitReflow::Sandbox.run "git config #{local}--get #{key}", loud: false
|
13
14
|
end
|
14
15
|
instance_variable_set(:"@#{key.tr('.-', '_')}", new_value.strip)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
|
-
def set(key, value,
|
19
|
+
def set(key, value, local: false)
|
19
20
|
value = value.strip
|
20
|
-
if
|
21
|
+
if local
|
21
22
|
GitReflow::Sandbox.run "git config --replace-all #{key} \"#{value}\"", loud: false
|
22
23
|
else
|
23
24
|
GitReflow::Sandbox.run "git config --global --replace-all #{key} \"#{value}\"", loud: false
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
def unset(key,
|
28
|
-
value = (
|
29
|
-
if
|
30
|
-
GitReflow::Sandbox.run "git config --unset #{key} #{value}", loud: false
|
28
|
+
def unset(key, value: nil, local: false)
|
29
|
+
value = (value.nil?) ? "" : "\"#{value}\""
|
30
|
+
if local
|
31
|
+
GitReflow::Sandbox.run "git config --unset-all #{key} #{value}", loud: false
|
31
32
|
else
|
32
|
-
GitReflow::Sandbox.run "git config --global --unset #{key} #{value}", loud: false
|
33
|
+
GitReflow::Sandbox.run "git config --global --unset-all #{key} #{value}", loud: false
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
def add(key, value,
|
37
|
-
if
|
37
|
+
def add(key, value, local: false)
|
38
|
+
if local
|
38
39
|
GitReflow::Sandbox.run "git config --add #{key} \"#{value}\"", loud: false
|
39
40
|
else
|
40
41
|
GitReflow::Sandbox.run "git config --global --add #{key} \"#{value}\"", loud: false
|
@@ -1,14 +1,16 @@
|
|
1
1
|
module GitReflow
|
2
2
|
module GitServer
|
3
|
-
autoload :Base,
|
4
|
-
autoload :GitHub,
|
3
|
+
autoload :Base, 'git_reflow/git_server/base'
|
4
|
+
autoload :GitHub, 'git_reflow/git_server/git_hub'
|
5
|
+
autoload :PullRequest, 'git_reflow/git_server/pull_request'
|
5
6
|
|
6
7
|
extend self
|
7
8
|
|
8
9
|
class ConnectionError < StandardError; end
|
9
10
|
|
10
|
-
def connect(options =
|
11
|
-
options ||= {
|
11
|
+
def connect(options = {})
|
12
|
+
options ||= {}
|
13
|
+
options[:provider] = 'GitHub' if "#{options[:provider]}".length <= 0
|
12
14
|
begin
|
13
15
|
provider_name = options[:provider]
|
14
16
|
provider = provider_class_for(options.delete(:provider)).new(options)
|
@@ -42,6 +44,14 @@ module GitReflow
|
|
42
44
|
GitReflow::GitServer.const_defined?(provider)
|
43
45
|
end
|
44
46
|
|
47
|
+
def create_pull_request(options = {})
|
48
|
+
raise "#{self.class.to_s}#create_pull_request method must be implemented"
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_open_pull_request(options = {})
|
52
|
+
raise "#{self.class.to_s}#find_open_pull_request method must be implemented"
|
53
|
+
end
|
54
|
+
|
45
55
|
private
|
46
56
|
|
47
57
|
def provider_class_for(provider)
|
@@ -6,22 +6,6 @@ module GitReflow
|
|
6
6
|
|
7
7
|
@@connection = nil
|
8
8
|
|
9
|
-
class PullRequest
|
10
|
-
attr_accessor :description, :html_url, :feature_branch_name, :base_branch_name, :build_status, :source_object, :number
|
11
|
-
|
12
|
-
def initialize(attributes)
|
13
|
-
raise "PullRequest#initialize must be implemented"
|
14
|
-
end
|
15
|
-
|
16
|
-
def method_missing(method_sym, *arguments, &block)
|
17
|
-
if source_object and source_object.respond_to? method_sym
|
18
|
-
source_object.send method_sym
|
19
|
-
else
|
20
|
-
super
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
9
|
def initialize(options)
|
26
10
|
site_url = self.class.site_url
|
27
11
|
api_endpoint = self.class.api_endpoint
|
@@ -72,18 +56,6 @@ module GitReflow
|
|
72
56
|
raise "#{self.class.to_s}#find_open_pull_request(options) method must be implemented"
|
73
57
|
end
|
74
58
|
|
75
|
-
def pull_request_comments(pull_request)
|
76
|
-
raise "#{self.class.to_s}#pull_request_comments(pull_request) method must be implemented"
|
77
|
-
end
|
78
|
-
|
79
|
-
def has_pull_request_comments?(pull_request)
|
80
|
-
pull_request_comments(pull_request).count > 0
|
81
|
-
end
|
82
|
-
|
83
|
-
def last_comment_for_pull_request(pull_request)
|
84
|
-
raise "#{self.class.to_s}#last_comment_for_pull_request(pull_request) method must be implemented"
|
85
|
-
end
|
86
|
-
|
87
59
|
def get_build_status sha
|
88
60
|
raise "#{self.class.to_s}#get_build_status(sha) method must be implemented"
|
89
61
|
end
|
@@ -92,16 +64,5 @@ module GitReflow
|
|
92
64
|
raise "#{self.class.to_s}#colorized_build_description(status) method must be implemented"
|
93
65
|
end
|
94
66
|
|
95
|
-
def reviewers(pull_request)
|
96
|
-
raise "#{self.class.to_s}#reviewers(pull_request) method must be implemented"
|
97
|
-
end
|
98
|
-
|
99
|
-
def approvals(pull_request)
|
100
|
-
raise "#{self.class.to_s}#approvals(pull_request) method must be implemented"
|
101
|
-
end
|
102
|
-
|
103
|
-
def reviewers_pending_response(pull_request)
|
104
|
-
reviewers(pull_request) - approvals(pull_request)
|
105
|
-
end
|
106
67
|
end
|
107
68
|
end
|
@@ -4,31 +4,17 @@ require 'git_reflow/git_helpers'
|
|
4
4
|
module GitReflow
|
5
5
|
module GitServer
|
6
6
|
class BitBucket < Base
|
7
|
-
|
8
|
-
class PullRequest < Base::PullRequest
|
9
|
-
def initialize(attributes)
|
10
|
-
self.description = attributes.description
|
11
|
-
self.source_object = attributes
|
12
|
-
self.number = attributes.id
|
13
|
-
self.html_url = "#{attributes.source.repository.links.html.href}/pull-request/#{self.number}"
|
14
|
-
self.feature_branch_name = attributes.source.branch.name
|
15
|
-
self.base_branch_name = attributes.destination.branch.name
|
16
|
-
self.build_status = nil
|
17
|
-
end
|
18
|
-
end
|
7
|
+
require_relative 'bit_bucket/pull_request'
|
19
8
|
|
20
9
|
attr_accessor :connection
|
21
10
|
|
22
11
|
def initialize(config_options = {})
|
23
12
|
project_only = !!config_options.delete(:project_only)
|
24
13
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
GitReflow::Config.unset('reflow.local-projects', value: "#{self.class.remote_user}/#{self.class.remote_repo_name}")
|
30
|
-
GitReflow::Config.set('reflow.git-server', 'BitBucket')
|
31
|
-
end
|
14
|
+
# We remove any existing setup first, then setup our required config settings
|
15
|
+
GitReflow::Config.unset('reflow.local-projects', value: "#{self.class.remote_user}/#{self.class.remote_repo_name}")
|
16
|
+
GitReflow::Config.add('reflow.local-projects', "#{self.class.remote_user}/#{self.class.remote_repo_name}") if project_only
|
17
|
+
GitReflow::Config.set('reflow.git-server', 'BitBucket', local: project_only)
|
32
18
|
end
|
33
19
|
|
34
20
|
def self.connection
|
@@ -38,17 +24,17 @@ module GitReflow
|
|
38
24
|
end
|
39
25
|
|
40
26
|
def self.api_endpoint
|
41
|
-
endpoint = GitReflow::Config.get("bitbucket.endpoint")
|
27
|
+
endpoint = GitReflow::Config.get("bitbucket.endpoint", local: project_only?)
|
42
28
|
(endpoint.length > 0) ? endpoint : ::BitBucket::Configuration::DEFAULT_ENDPOINT
|
43
29
|
end
|
44
30
|
|
45
31
|
def self.site_url
|
46
|
-
site_url = GitReflow::Config.get("bitbucket.site")
|
32
|
+
site_url = GitReflow::Config.get("bitbucket.site", local: project_only?)
|
47
33
|
(site_url.length > 0) ? site_url : 'https://bitbucket.org'
|
48
34
|
end
|
49
35
|
|
50
36
|
def self.api_key
|
51
|
-
GitReflow::Config.get("bitbucket.api-key", reload: true)
|
37
|
+
GitReflow::Config.get("bitbucket.api-key", reload: true, local: project_only?)
|
52
38
|
end
|
53
39
|
|
54
40
|
def self.api_key=(key)
|
@@ -59,7 +45,7 @@ module GitReflow
|
|
59
45
|
end
|
60
46
|
|
61
47
|
def self.user
|
62
|
-
GitReflow::Config.get('bitbucket.user')
|
48
|
+
GitReflow::Config.get('bitbucket.user', local: project_only?)
|
63
49
|
end
|
64
50
|
|
65
51
|
def self.user=(bitbucket_user)
|
@@ -92,73 +78,22 @@ module GitReflow
|
|
92
78
|
@connection ||= self.class.connection
|
93
79
|
end
|
94
80
|
|
95
|
-
def
|
96
|
-
PullRequest.new connection.repos.pull_requests.create(self.class.remote_user, self.class.remote_repo_name,
|
97
|
-
title: options[:title],
|
98
|
-
body: options[:body],
|
99
|
-
source: {
|
100
|
-
branch: { name: self.class.current_branch },
|
101
|
-
repository: { full_name: "#{self.class.remote_user}/#{self.class.remote_repo_name}" }
|
102
|
-
},
|
103
|
-
destination: {
|
104
|
-
branch: { name: options[:base] }
|
105
|
-
},
|
106
|
-
reviewers: [username: self.class.user])
|
107
|
-
end
|
108
|
-
|
109
|
-
def find_open_pull_request(options = {})
|
110
|
-
begin
|
111
|
-
matching_pull = connection.repos.pull_requests.all(self.class.remote_user, self.class.remote_repo_name, limit: 1).select do |pr|
|
112
|
-
pr.source.branch.name == options[:from] and
|
113
|
-
pr.destination.branch.name == options[:to]
|
114
|
-
end.first
|
115
|
-
|
116
|
-
if matching_pull
|
117
|
-
PullRequest.new matching_pull
|
118
|
-
end
|
119
|
-
rescue ::BitBucket::Error::NotFound => e
|
120
|
-
self.class.say "No BitBucket repo found for #{self.class.remote_user}/#{self.class.remote_repo_name}", :error
|
121
|
-
rescue ::BitBucket::Error::Forbidden => e
|
122
|
-
self.class.say "You don't have API access to this repo", :error
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def pull_request_comments(pull_request)
|
127
|
-
connection.repos.pull_requests.comments.all(self.class.remote_user, self.class.remote_repo_name, pull_request.id)
|
128
|
-
end
|
129
|
-
|
130
|
-
def last_comment_for_pull_request(pull_request)
|
131
|
-
last_comment = pull_request_comments(pull_request).first
|
132
|
-
return "" unless last_comment
|
133
|
-
"#{pull_request_comments(pull_request).first.content.raw}"
|
134
|
-
end
|
135
|
-
|
136
|
-
def get_build_status sha
|
81
|
+
def get_build_status(sha)
|
137
82
|
# BitBucket does not currently support build status via API
|
138
83
|
# for updates: https://bitbucket.org/site/master/issue/8548/better-ci-integration-add-a-build-status
|
139
84
|
return nil
|
140
85
|
end
|
141
86
|
|
142
|
-
def colorized_build_description
|
87
|
+
def colorized_build_description(state, description)
|
143
88
|
""
|
144
89
|
end
|
145
90
|
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
return [] unless comments.size > 0
|
150
|
-
comments.map {|c| c.user.username } - [self.class.user]
|
91
|
+
def create_pull_request(options = {})
|
92
|
+
PullRequest.create(options)
|
151
93
|
end
|
152
94
|
|
153
|
-
def
|
154
|
-
|
155
|
-
|
156
|
-
connection.repos.pull_requests.activity(self.class.remote_user, self.class.remote_repo_name, pull_request.id).each do |activity|
|
157
|
-
break unless activity.respond_to?(:approval) and activity.approval.user.username != self.class.user
|
158
|
-
approved |= [activity.approval.user.username]
|
159
|
-
end
|
160
|
-
|
161
|
-
approved
|
95
|
+
def find_open_pull_request(options = {})
|
96
|
+
PullRequest.find_open(options)
|
162
97
|
end
|
163
98
|
|
164
99
|
end
|