git-review 2.0.0.alpha → 2.0.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 +7 -0
- data/bin/git-review +18 -9
- data/lib/git-review.rb +35 -12
- data/lib/git-review/commands.rb +157 -172
- data/lib/git-review/errors.rb +6 -0
- data/lib/git-review/helpers.rb +38 -0
- data/lib/git-review/local.rb +157 -20
- data/lib/git-review/provider/base.rb +85 -0
- data/lib/git-review/provider/bitbucket.rb +25 -0
- data/lib/git-review/provider/github.rb +271 -0
- data/lib/git-review/server.rb +61 -0
- data/lib/git-review/settings.rb +26 -21
- data/lib/mixins/accessible.rb +35 -0
- data/lib/mixins/colorizable.rb +30 -0
- data/lib/mixins/nestable.rb +16 -0
- data/lib/mixins/string.rb +13 -0
- data/lib/mixins/time.rb +11 -0
- data/lib/models/commit.rb +14 -0
- data/lib/models/repository.rb +8 -0
- data/lib/models/request.rb +18 -0
- data/lib/models/user.rb +7 -0
- metadata +72 -47
- data/lib/git-review/github.rb +0 -289
- data/lib/git-review/internals.rb +0 -47
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 49d9d8f5c8209622227ccaecb90dbb9db6549f06
|
4
|
+
data.tar.gz: f8041155345b3f1afd104904a64401295fa4bb6f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5e6eca5b975528044e599608d58f4d90adb9d466fbe22e9d3da6b21ba53bbe16a49f21e85cd361d3bb3a804c4cacdb1af71b4d04f714fd98c99f4b0943f35b05
|
7
|
+
data.tar.gz: 05ac7231034a1b309e434b1257645c5df10f7a9dd8126a9efadcfba6b0808520860c28fc682b161c6fcf119adaf93d77a84eaeddf81ab6407cf69e85b7b5274c
|
data/bin/git-review
CHANGED
@@ -7,23 +7,23 @@ require 'git-review'
|
|
7
7
|
require 'gli'
|
8
8
|
|
9
9
|
include GLI::App
|
10
|
-
|
11
10
|
program_desc 'Manage review workflow for Github projects (using pull requests).'
|
12
11
|
|
13
12
|
# Pre-hook before a command is executed
|
14
13
|
pre do |global, cmd, opts, args|
|
15
|
-
|
16
|
-
if
|
17
|
-
|
14
|
+
server = ::GitReview::Server.instance
|
15
|
+
if server.configure_access && server.source_repo
|
16
|
+
server.update unless cmd == 'clean'
|
18
17
|
end
|
19
|
-
|
18
|
+
|
19
|
+
true # return true to explicitly pass precondition
|
20
20
|
end
|
21
21
|
|
22
22
|
desc 'List all pending requests'
|
23
23
|
command :list do |c|
|
24
24
|
c.switch [:r, :reverse]
|
25
25
|
c.action do |global, opts, args|
|
26
|
-
|
26
|
+
::GitReview::Commands.list(opts[:reverse])
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -46,7 +46,7 @@ end
|
|
46
46
|
|
47
47
|
desc 'Checkout a request\'s changes to local repo'
|
48
48
|
command :checkout do |c|
|
49
|
-
c.switch [:b, :branch]
|
49
|
+
c.switch [:b, :branch], default_value: true
|
50
50
|
c.action do |global, opts, args|
|
51
51
|
help_now!('Request number is required.') if args.empty?
|
52
52
|
::GitReview::Commands.checkout(args.shift, opts[:branch])
|
@@ -81,7 +81,7 @@ desc 'Create a new local branch for a request'
|
|
81
81
|
command :prepare do |c|
|
82
82
|
c.switch [:n, :new]
|
83
83
|
c.action do |global, opts, args|
|
84
|
-
::GitReview::Commands.prepare(opts[:new], args.
|
84
|
+
::GitReview::Commands.prepare(opts[:new], args.empty? ? nil : args.join(' '))
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -100,7 +100,16 @@ command :clean do |c|
|
|
100
100
|
c.action do |global, opts, args|
|
101
101
|
help_now!('Request number is required.') if args.empty? && !opts[:all]
|
102
102
|
number = args.empty? ? nil : args.shift
|
103
|
-
::GitReview::Commands.clean(
|
103
|
+
::GitReview::Commands.clean(args.shift, opts[:force], opts[:all])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
if ::GitReview::Settings.instance.review_mode == 'debug' || ENV['DEBUG']
|
108
|
+
desc 'Console session for debugging'
|
109
|
+
command :console do |c|
|
110
|
+
c.action do |global, opts, args|
|
111
|
+
::GitReview::Commands.console(args.shift)
|
112
|
+
end
|
104
113
|
end
|
105
114
|
end
|
106
115
|
|
data/lib/git-review.rb
CHANGED
@@ -1,28 +1,51 @@
|
|
1
|
+
### Dependencies
|
2
|
+
|
3
|
+
## External Dependencies
|
4
|
+
|
1
5
|
# Provide access to GitHub's API.
|
2
6
|
require 'octokit'
|
3
7
|
# Open a browser in 'browse' command.
|
4
8
|
require 'launchy'
|
5
9
|
# Parse time strings from git back into Time objects.
|
6
10
|
require 'time'
|
7
|
-
# Use temporary files to allow editing a request's
|
11
|
+
# Use temporary files to allow editing a request's.
|
8
12
|
require 'tempfile'
|
9
13
|
|
10
|
-
##
|
14
|
+
## Internal dependencies
|
11
15
|
|
12
|
-
# Include
|
13
|
-
require_relative 'git-review/
|
14
|
-
# Deal with current git repository.
|
15
|
-
require_relative 'git-review/local'
|
16
|
-
# Communicate with Github via API.
|
17
|
-
require_relative 'git-review/github'
|
18
|
-
# Read and write settings from/to the filesystem.
|
19
|
-
require_relative 'git-review/settings'
|
16
|
+
# Include helper functions to make it work as expected.
|
17
|
+
require_relative 'git-review/helpers'
|
20
18
|
# Provide available commands.
|
21
19
|
require_relative 'git-review/commands'
|
20
|
+
# Read and write settings from/to the filesystem.
|
21
|
+
require_relative 'git-review/settings'
|
22
|
+
# Deal with local git repository.
|
23
|
+
require_relative 'git-review/local'
|
22
24
|
# Include all kinds of custom-defined errors.
|
23
25
|
require_relative 'git-review/errors'
|
26
|
+
# Factory to get git API client..
|
27
|
+
require_relative 'git-review/server'
|
28
|
+
# Generic base class for shared provider methods.
|
29
|
+
require_relative 'git-review/provider/base'
|
30
|
+
# Communicate with Github via API.
|
31
|
+
require_relative 'git-review/provider/github'
|
32
|
+
# Communicate with Bitbucket via API.
|
33
|
+
require_relative 'git-review/provider/bitbucket'
|
24
34
|
|
35
|
+
# Allow easy string colorization in the console.
|
36
|
+
require_relative 'mixins/colorizable'
|
37
|
+
# Allow to access a model's attributes in various ways (feels railsy).
|
38
|
+
require_relative 'mixins/accessible'
|
39
|
+
# Allow to nest models in other model's attributes.
|
40
|
+
require_relative 'mixins/nestable'
|
25
41
|
|
26
|
-
|
42
|
+
# Include custom string helpers.
|
43
|
+
require_relative 'mixins/string'
|
44
|
+
# Include custom time helpers.
|
45
|
+
require_relative 'mixins/time'
|
27
46
|
|
28
|
-
|
47
|
+
# Add some POROs to get some structure into the entities git-review deals with.
|
48
|
+
require_relative 'models/repository'
|
49
|
+
require_relative 'models/user'
|
50
|
+
require_relative 'models/commit'
|
51
|
+
require_relative 'models/request'
|
data/lib/git-review/commands.rb
CHANGED
@@ -2,66 +2,81 @@ module GitReview
|
|
2
2
|
|
3
3
|
module Commands
|
4
4
|
|
5
|
-
include ::GitReview::
|
5
|
+
include ::GitReview::Helpers
|
6
6
|
extend self
|
7
7
|
|
8
8
|
# List all pending requests.
|
9
|
-
def list(reverse=false)
|
10
|
-
requests =
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
def list(reverse = false)
|
10
|
+
requests = server.current_requests_full.reject do |request|
|
11
|
+
# Find only pending (= unmerged) requests and output summary.
|
12
|
+
# Explicitly look for local changes git does not yet know about.
|
13
|
+
# TODO: Isn't this a bit confusing? Maybe display pending pushes?
|
14
|
+
local.merged? request.head.sha
|
15
|
+
end
|
16
16
|
source = local.source
|
17
17
|
if requests.empty?
|
18
18
|
puts "No pending requests for '#{source}'."
|
19
19
|
else
|
20
20
|
puts "Pending requests for '#{source}':"
|
21
|
-
puts "ID Updated Comments Title"
|
22
|
-
requests
|
21
|
+
puts "ID Updated Comments Title".pink
|
22
|
+
print_requests(requests, reverse)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
# Show details for a single request.
|
27
|
-
def show(number, full=false)
|
28
|
-
request = get_request_by_number(number)
|
29
|
-
#
|
27
|
+
def show(number, full = false)
|
28
|
+
request = server.get_request_by_number(number)
|
29
|
+
# Determine whether to show full diff or stats only.
|
30
30
|
option = full ? '' : '--stat '
|
31
31
|
diff = "diff --color=always #{option}HEAD...#{request.head.sha}"
|
32
|
-
|
32
|
+
# TODO: Refactor into using Request model.
|
33
|
+
print_request_details request
|
33
34
|
puts git_call(diff)
|
34
|
-
print_request_discussions
|
35
|
+
print_request_discussions request
|
35
36
|
end
|
36
37
|
|
37
38
|
# Open a browser window and review a specified request.
|
38
39
|
def browse(number)
|
39
|
-
request = get_request_by_number(number)
|
40
|
-
|
40
|
+
request = server.get_request_by_number(number)
|
41
|
+
# FIXME: Use request.html_url as soon as we are using our Request model.
|
42
|
+
Launchy.open request._links.html.href
|
41
43
|
end
|
42
44
|
|
43
45
|
# Checkout a specified request's changes to your local repository.
|
44
|
-
def checkout(number, branch=
|
45
|
-
request = get_request_by_number(number)
|
46
|
+
def checkout(number, branch = true)
|
47
|
+
request = server.get_request_by_number(number)
|
46
48
|
puts 'Checking out changes to your local repository.'
|
47
49
|
puts 'To get back to your original state, just run:'
|
48
50
|
puts
|
49
|
-
puts ' git checkout master'
|
51
|
+
puts ' git checkout master'.pink
|
50
52
|
puts
|
53
|
+
# Ensure we are looking at the right remote.
|
54
|
+
remote = local.remote_for_request(request)
|
55
|
+
git_call "fetch #{remote}"
|
56
|
+
# Checkout the right branch.
|
57
|
+
branch_name = request.head.ref
|
51
58
|
if branch
|
52
|
-
|
59
|
+
if local.branch_exists?(:local, branch_name)
|
60
|
+
if local.source_branch == branch_name
|
61
|
+
puts "On branch #{branch_name}."
|
62
|
+
else
|
63
|
+
git_call "checkout #{branch_name}"
|
64
|
+
end
|
65
|
+
else
|
66
|
+
git_call "checkout --track -b #{branch_name} #{remote}/#{branch_name}"
|
67
|
+
end
|
53
68
|
else
|
54
|
-
git_call
|
69
|
+
git_call "checkout #{remote}/#{branch_name}"
|
55
70
|
end
|
56
71
|
end
|
57
72
|
|
58
73
|
# Add an approving comment to the request.
|
59
74
|
def approve(number)
|
60
|
-
request = get_request_by_number(number)
|
61
|
-
repo =
|
75
|
+
request = server.get_request_by_number(number)
|
76
|
+
repo = server.source_repo
|
62
77
|
# TODO: Make this configurable.
|
63
78
|
comment = 'Reviewed and approved.'
|
64
|
-
response =
|
79
|
+
response = server.add_comment(repo, request.number, comment)
|
65
80
|
if response[:body] == comment
|
66
81
|
puts 'Successfully approved request.'
|
67
82
|
else
|
@@ -71,7 +86,7 @@ module GitReview
|
|
71
86
|
|
72
87
|
# Accept a specified request by merging it into master.
|
73
88
|
def merge(number)
|
74
|
-
request = get_request_by_number(number)
|
89
|
+
request = server.get_request_by_number(number)
|
75
90
|
if request.head.repo
|
76
91
|
message = "Accept request ##{request.number} " +
|
77
92
|
"and merge changes into \"#{local.target}\""
|
@@ -85,108 +100,144 @@ module GitReview
|
|
85
100
|
puts
|
86
101
|
puts git_call(command)
|
87
102
|
else
|
88
|
-
print_repo_deleted
|
103
|
+
print_repo_deleted request
|
89
104
|
end
|
90
105
|
end
|
91
106
|
|
92
107
|
# Close a specified request.
|
93
108
|
def close(number)
|
94
|
-
request = get_request_by_number(number)
|
95
|
-
repo =
|
96
|
-
|
97
|
-
unless
|
109
|
+
request = server.get_request_by_number(number)
|
110
|
+
repo = server.source_repo
|
111
|
+
server.close_issue(repo, request.number)
|
112
|
+
unless server.request_exists?('open', request.number)
|
98
113
|
puts 'Successfully closed request.'
|
99
114
|
end
|
100
115
|
end
|
101
116
|
|
102
117
|
# Prepare local repository to create a new request.
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
118
|
+
# NOTE:
|
119
|
+
# People should work on local branches, but especially for single commit
|
120
|
+
# changes, more often than not, they don't. Therefore this is called
|
121
|
+
# automatically before creating a pull request, such that we create a
|
122
|
+
# proper feature branch for them, to be able to use code review the way it
|
123
|
+
# is intended.
|
124
|
+
def prepare(force_new_branch = false, feature_name = nil)
|
125
|
+
current_branch = local.source_branch
|
126
|
+
if force_new_branch || !local.on_feature_branch?
|
127
|
+
feature_name ||= get_branch_name
|
128
|
+
feature_branch = move_local_changes(
|
129
|
+
current_branch, local.sanitize_branch_name(feature_name)
|
130
|
+
)
|
112
131
|
else
|
113
|
-
|
132
|
+
feature_branch = current_branch
|
114
133
|
end
|
115
|
-
[
|
134
|
+
[current_branch, feature_branch]
|
116
135
|
end
|
117
136
|
|
118
137
|
# Create a new request.
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
# prepare original_branch and local_branch
|
138
|
+
def create(upstream = false)
|
139
|
+
# Prepare original_branch and local_branch.
|
140
|
+
# TODO: Allow to use the same switches and parameters that prepare takes.
|
123
141
|
original_branch, local_branch = prepare
|
124
|
-
#
|
125
|
-
|
142
|
+
# Don't create request with uncommitted changes in current branch.
|
143
|
+
if local.uncommitted_changes?
|
126
144
|
puts 'You have uncommitted changes.'
|
127
145
|
puts 'Please stash or commit before creating the request.'
|
128
146
|
return
|
129
147
|
end
|
130
|
-
if
|
131
|
-
|
132
|
-
|
133
|
-
if github.request_exists_for_branch?(upstream)
|
148
|
+
if local.new_commits?(upstream)
|
149
|
+
# Feature branch differs from local or upstream master.
|
150
|
+
if server.request_exists_for_branch?(upstream)
|
134
151
|
puts 'A pull request already exists for this branch.'
|
135
152
|
puts 'Please update the request directly using `git push`.'
|
136
153
|
return
|
137
154
|
end
|
138
|
-
#
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
155
|
+
# Push latest commits to the remote branch (create if necessary).
|
156
|
+
remote = local.remote_for_branch(local_branch) || 'origin'
|
157
|
+
git_call(
|
158
|
+
"push --set-upstream #{remote} #{local_branch}", debug_mode, true
|
159
|
+
)
|
160
|
+
server.send_pull_request upstream
|
161
|
+
# Return to the user's original branch.
|
162
|
+
git_call "checkout #{original_branch}"
|
163
|
+
else
|
164
|
+
puts 'Nothing to push to remote yet. Commit something first.'
|
144
165
|
end
|
145
166
|
end
|
146
167
|
|
147
|
-
#
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
168
|
+
# Remove remotes with 'review' prefix (left over from previous reviews).
|
169
|
+
# Prune all existing remotes and delete obsolete branches (left over from
|
170
|
+
# already closed requests).
|
171
|
+
def clean(number = nil, force = false, all = false)
|
172
|
+
git_call "checkout #{local.target_branch}"
|
173
|
+
local.prune_remotes
|
174
|
+
# Determine strategy to clean.
|
152
175
|
if all
|
153
176
|
local.clean_all
|
154
177
|
else
|
155
178
|
local.clean_single(number, force)
|
156
179
|
end
|
180
|
+
# Remove al review remotes without existing local branches.
|
181
|
+
local.clean_remotes
|
157
182
|
end
|
158
183
|
|
159
184
|
# Start a console session (used for debugging)
|
160
|
-
def console
|
185
|
+
def console(number = nil)
|
161
186
|
puts 'Entering debug console.'
|
162
|
-
|
163
|
-
|
164
|
-
|
187
|
+
request = server.get_request_by_number(number) if number
|
188
|
+
|
189
|
+
if RUBY_VERSION.to_f >= 2
|
190
|
+
begin
|
191
|
+
require 'byebug'
|
192
|
+
byebug
|
193
|
+
rescue LoadError => e
|
194
|
+
puts
|
195
|
+
puts 'Missing debugger, please install byebug:'
|
196
|
+
puts ' gem install byebug'
|
197
|
+
puts
|
198
|
+
end
|
165
199
|
else
|
166
|
-
|
167
|
-
|
168
|
-
|
200
|
+
begin
|
201
|
+
require 'ruby-debug'
|
202
|
+
Debugger.start
|
203
|
+
debugger
|
204
|
+
rescue LoadError => e
|
205
|
+
puts
|
206
|
+
puts 'Missing debugger, please install ruby-debug:'
|
207
|
+
puts ' gem install ruby-debug'
|
208
|
+
puts
|
209
|
+
end
|
169
210
|
end
|
170
211
|
puts 'Leaving debug console.'
|
171
212
|
end
|
172
213
|
|
173
|
-
private
|
174
214
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
line =
|
179
|
-
line <<
|
180
|
-
line <<
|
181
|
-
line <<
|
182
|
-
|
215
|
+
private
|
216
|
+
|
217
|
+
def request_summary(request)
|
218
|
+
line = request.number.to_s.review_ljust(8)
|
219
|
+
line << request.updated_at.review_time.review_ljust(11)
|
220
|
+
line << server.comments_count(request).to_s.review_ljust(10)
|
221
|
+
line << request.title.review_ljust(91)
|
222
|
+
line
|
223
|
+
end
|
224
|
+
|
225
|
+
def print_requests(requests, reverse=false)
|
226
|
+
# put all output lines in a hash first, keyed by request number
|
227
|
+
# this is to make sure the order is still correct even if we use
|
228
|
+
# multi-threading to retrieve the requests
|
229
|
+
output = {}
|
230
|
+
requests.each { |req| output[req.number] = request_summary(req) }
|
231
|
+
numbers = output.keys.sort
|
232
|
+
numbers.reverse! if reverse
|
233
|
+
numbers.each { |n| puts output[n] }
|
183
234
|
end
|
184
235
|
|
185
236
|
def print_request_details(request)
|
186
|
-
comments_count =
|
237
|
+
comments_count = server.comments_count(request)
|
187
238
|
puts 'ID : ' + request.number.to_s
|
188
239
|
puts 'Label : ' + request.head.label
|
189
|
-
puts 'Updated : ' +
|
240
|
+
puts 'Updated : ' + request.updated_at.review_time
|
190
241
|
puts 'Comments : ' + comments_count.to_s
|
191
242
|
puts
|
192
243
|
puts request.title
|
@@ -200,7 +251,7 @@ module GitReview
|
|
200
251
|
def print_request_discussions(request)
|
201
252
|
puts 'Progress :'
|
202
253
|
puts
|
203
|
-
puts
|
254
|
+
puts server.discussion(request.number)
|
204
255
|
end
|
205
256
|
|
206
257
|
# someone deleted the source repo
|
@@ -221,111 +272,45 @@ module GitReview
|
|
221
272
|
# @return [String] sanitized branch name
|
222
273
|
def get_branch_name
|
223
274
|
puts 'Please provide a name for the branch:'
|
224
|
-
|
225
|
-
|
275
|
+
local.sanitize_branch_name gets.chomp
|
276
|
+
end
|
277
|
+
|
278
|
+
# @return [String] the complete feature branch name
|
279
|
+
def create_feature_name(new_branch)
|
280
|
+
"review_#{Time.now.strftime("%y%m%d")}_#{new_branch}"
|
226
281
|
end
|
227
282
|
|
228
|
-
#
|
283
|
+
# Move uncommitted changes from original_branch to a feature_branch.
|
229
284
|
# @return [String] the new local branch uncommitted changes are moved to
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
#
|
235
|
-
|
236
|
-
|
285
|
+
def move_local_changes(original_branch, feature_name)
|
286
|
+
feature_branch = create_feature_name(feature_name)
|
287
|
+
# By checking out the feature branch, the commits on the original branch
|
288
|
+
# are copied over. That way we only need to remove pending (local) commits
|
289
|
+
# from the original branch.
|
290
|
+
git_call "checkout -b #{feature_branch}"
|
291
|
+
if local.source_branch == feature_branch
|
292
|
+
# Save any uncommitted changes, to be able to reapply them later.
|
237
293
|
save_uncommitted_changes = local.uncommitted_changes?
|
238
294
|
git_call('stash') if save_uncommitted_changes
|
239
|
-
#
|
240
|
-
git_call("checkout #{
|
241
|
-
|
242
|
-
|
295
|
+
# Go back to original branch and get rid of pending (local) commits.
|
296
|
+
git_call("checkout #{original_branch}")
|
297
|
+
remote = local.remote_for_branch(original_branch)
|
298
|
+
remote += '/' if remote
|
299
|
+
git_call("reset --hard #{remote}#{original_branch}")
|
300
|
+
git_call("checkout #{feature_branch}")
|
243
301
|
git_call('stash pop') if save_uncommitted_changes
|
244
|
-
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
def create_pull_request(to_upstream=false)
|
249
|
-
target_repo = local.target_repo(to_upstream)
|
250
|
-
head = local.head
|
251
|
-
base = local.target_branch
|
252
|
-
title, body = create_title_and_body(base)
|
253
|
-
|
254
|
-
# gather information before creating pull request
|
255
|
-
lastest_number = github.latest_request_number(target_repo)
|
256
|
-
|
257
|
-
# create the actual pull request
|
258
|
-
github.create_pull_request(target_repo, base, head, title, body)
|
259
|
-
# switch back to target_branch and check for success
|
260
|
-
git_call("checkout #{base}")
|
261
|
-
|
262
|
-
# make sure the new pull request is indeed created
|
263
|
-
new_number = github.request_number_by_title(title, target_repo)
|
264
|
-
if new_number && new_number > lastest_number
|
265
|
-
puts "Successfully created new request ##{new_number}"
|
266
|
-
puts "https://github.com/#{target_repo}/pull/#{new_number}"
|
267
|
-
else
|
268
|
-
puts "Pull request was not created for #{target_repo}."
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
|
273
|
-
# @return [Array(String, String)] the title and the body of pull request
|
274
|
-
def create_title_and_body(target_branch)
|
275
|
-
source = local.source
|
276
|
-
login = github.github.login
|
277
|
-
commits = git_call("log --format='%H' HEAD...#{target_branch}").
|
278
|
-
lines.count
|
279
|
-
puts "commits: #{commits}"
|
280
|
-
if commits == 1
|
281
|
-
# we can create a really specific title and body
|
282
|
-
title = git_call("log --format='%s' HEAD...#{target_branch}").chomp
|
283
|
-
body = git_call("log --format='%b' HEAD...#{target_branch}").chomp
|
284
|
-
else
|
285
|
-
title = "[Review] Request from '#{login}' @ '#{source}'"
|
286
|
-
body = "Please review the following changes:\n"
|
287
|
-
body += git_call("log --oneline HEAD...#{target_branch}").
|
288
|
-
lines.map{|l| " * #{l.chomp}"}.join("\n")
|
302
|
+
feature_branch
|
289
303
|
end
|
290
|
-
edit_title_and_body(title, body)
|
291
304
|
end
|
292
305
|
|
293
|
-
|
294
|
-
|
295
|
-
tmpfile = Tempfile.new('git-review')
|
296
|
-
tmpfile.write(title + "\n\n" + body)
|
297
|
-
tmpfile.flush
|
298
|
-
editor = ENV['TERM_EDITOR'] || ENV['EDITOR']
|
299
|
-
unless editor
|
300
|
-
warn 'Please set $EDITOR or $TERM_EDITOR in your .bash_profile.'
|
301
|
-
end
|
302
|
-
|
303
|
-
system("#{editor || 'open'} #{tmpfile.path}")
|
304
|
-
|
305
|
-
tmpfile.rewind
|
306
|
-
lines = tmpfile.read.lines.to_a
|
307
|
-
puts lines.inspect
|
308
|
-
title = lines.shift.chomp
|
309
|
-
lines.shift if lines[0].chomp.empty?
|
310
|
-
body = lines.join
|
311
|
-
tmpfile.unlink
|
312
|
-
[title, body]
|
313
|
-
end
|
314
|
-
|
315
|
-
def github
|
316
|
-
@github ||= ::GitReview::Github.instance
|
306
|
+
def server
|
307
|
+
@server ||= ::GitReview::Server.instance
|
317
308
|
end
|
318
309
|
|
319
310
|
def local
|
320
311
|
@local ||= ::GitReview::Local.instance
|
321
312
|
end
|
322
313
|
|
323
|
-
def get_request_by_number(request_number)
|
324
|
-
request = github.request_exists?(request_number)
|
325
|
-
request || (raise ::GitReview::InvalidRequestIDError)
|
326
|
-
end
|
327
|
-
|
328
314
|
end
|
329
315
|
|
330
316
|
end
|
331
|
-
|