git_reflow 0.6.7 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|