git-process 1.1.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +14 -1
- data/LICENSE +193 -22
- data/README.md +212 -71
- data/man/git-process.1 +371 -0
- metadata +52 -140
- data/Gemfile +0 -20
- data/Gemfile.lock +0 -53
- data/Rakefile +0 -16
- data/bin/git-new-fb +0 -58
- data/bin/git-pull-request +0 -107
- data/bin/git-sync +0 -73
- data/bin/git-to-master +0 -133
- data/git-process.gemspec +0 -25
- data/lib/git-process/abstract_error_builder.rb +0 -53
- data/lib/git-process/changed_file_helper.rb +0 -115
- data/lib/git-process/git_abstract_merge_error_builder.rb +0 -146
- data/lib/git-process/git_branch.rb +0 -105
- data/lib/git-process/git_branches.rb +0 -73
- data/lib/git-process/git_config.rb +0 -153
- data/lib/git-process/git_lib.rb +0 -512
- data/lib/git-process/git_logger.rb +0 -84
- data/lib/git-process/git_merge_error.rb +0 -28
- data/lib/git-process/git_process.rb +0 -172
- data/lib/git-process/git_process_error.rb +0 -18
- data/lib/git-process/git_process_options.rb +0 -99
- data/lib/git-process/git_rebase_error.rb +0 -30
- data/lib/git-process/git_remote.rb +0 -256
- data/lib/git-process/git_status.rb +0 -108
- data/lib/git-process/github_configuration.rb +0 -298
- data/lib/git-process/github_pull_request.rb +0 -151
- data/lib/git-process/new_fb.rb +0 -50
- data/lib/git-process/parked_changes_error.rb +0 -41
- data/lib/git-process/pull_request.rb +0 -134
- data/lib/git-process/pull_request_error.rb +0 -25
- data/lib/git-process/rebase_to_master.rb +0 -148
- data/lib/git-process/sync.rb +0 -136
- data/lib/git-process/uncommitted_changes_error.rb +0 -23
- data/lib/git-process/version.rb +0 -22
- data/spec/FileHelpers.rb +0 -19
- data/spec/GitRepoHelper.rb +0 -123
- data/spec/changed_file_helper_spec.rb +0 -127
- data/spec/git_abstract_merge_error_builder_spec.rb +0 -126
- data/spec/git_branch_spec.rb +0 -123
- data/spec/git_config_spec.rb +0 -45
- data/spec/git_lib_spec.rb +0 -176
- data/spec/git_logger_spec.rb +0 -66
- data/spec/git_process_spec.rb +0 -208
- data/spec/git_remote_spec.rb +0 -227
- data/spec/git_status_spec.rb +0 -122
- data/spec/github_configuration_spec.rb +0 -152
- data/spec/github_pull_request_spec.rb +0 -96
- data/spec/github_test_helper.rb +0 -49
- data/spec/new_fb_spec.rb +0 -130
- data/spec/pull_request_helper.rb +0 -94
- data/spec/pull_request_spec.rb +0 -128
- data/spec/rebase_to_master_spec.rb +0 -429
- data/spec/spec_helper.rb +0 -21
- data/spec/sync_spec.rb +0 -304
@@ -1,108 +0,0 @@
|
|
1
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
-
# you may not use this file except in compliance with the License.
|
3
|
-
# You may obtain a copy of the License at
|
4
|
-
#
|
5
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
7
|
-
# Unless required by applicable law or agreed to in writing, software
|
8
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
-
# See the License for the specific language governing permissions and
|
11
|
-
# limitations under the License.
|
12
|
-
|
13
|
-
module GitProc
|
14
|
-
|
15
|
-
#
|
16
|
-
# The status of the Git repository.
|
17
|
-
#
|
18
|
-
# @!attribute [r] unmerged
|
19
|
-
# @return [Enumerable] a sorted list of unmerged files
|
20
|
-
# @!attribute [r] modified
|
21
|
-
# @return [Enumerable] a sorted list of modified files
|
22
|
-
# @!attribute [r] deleted
|
23
|
-
# @return [Enumerable] a sorted list of deleted files
|
24
|
-
# @!attribute [r] added
|
25
|
-
# @return [Enumerable] a sorted list of files that have been added
|
26
|
-
# @!attribute [r] unknown
|
27
|
-
# @return [Enumerable] a sorted list of unknown files
|
28
|
-
class GitStatus
|
29
|
-
attr_reader :unmerged, :modified, :deleted, :added, :unknown
|
30
|
-
|
31
|
-
|
32
|
-
def initialize(lib)
|
33
|
-
unmerged = []
|
34
|
-
modified = []
|
35
|
-
deleted = []
|
36
|
-
added = []
|
37
|
-
unknown = []
|
38
|
-
|
39
|
-
stats = lib.porcelain_status.split("\n")
|
40
|
-
|
41
|
-
stats.each do |s|
|
42
|
-
stat = s[0..1]
|
43
|
-
file = s[3..-1]
|
44
|
-
#puts "stat #{stat} - #{file}"
|
45
|
-
f = unquote(file)
|
46
|
-
case stat
|
47
|
-
when 'U ', ' U'
|
48
|
-
unmerged << f
|
49
|
-
when 'UU'
|
50
|
-
unmerged << f
|
51
|
-
modified << f
|
52
|
-
when 'M ', ' M', 'MM'
|
53
|
-
modified << f
|
54
|
-
when 'MD'
|
55
|
-
modified << f
|
56
|
-
deleted << f
|
57
|
-
when 'D ', ' D', 'DD'
|
58
|
-
deleted << f
|
59
|
-
when 'DU', 'UD'
|
60
|
-
deleted << f
|
61
|
-
unmerged << f
|
62
|
-
when 'A ', ' A'
|
63
|
-
added << f
|
64
|
-
when 'AD'
|
65
|
-
added << f
|
66
|
-
deleted << f
|
67
|
-
when 'AA', 'AU', 'UA'
|
68
|
-
added << f
|
69
|
-
unmerged << f
|
70
|
-
when 'AM', 'MA'
|
71
|
-
added << f
|
72
|
-
modified << f
|
73
|
-
when '??', '!!'
|
74
|
-
unknown << f
|
75
|
-
when 'R '
|
76
|
-
old_file, new_file = file.split(' -> ')
|
77
|
-
deleted << unquote(old_file)
|
78
|
-
added << unquote(new_file)
|
79
|
-
when 'C '
|
80
|
-
old_file, new_file = file.split(' -> ')
|
81
|
-
added << unquote(old_file)
|
82
|
-
added << unquote(new_file)
|
83
|
-
else
|
84
|
-
raise "Do not know what to do with status #{stat} - #{file}"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
@unmerged = unmerged.sort.uniq.freeze
|
89
|
-
@modified = modified.sort.uniq.freeze
|
90
|
-
@deleted = deleted.sort.uniq.freeze
|
91
|
-
@added = added.sort.uniq.freeze
|
92
|
-
@unknown = unknown.sort.uniq.freeze
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
def unquote(file)
|
97
|
-
file.match(/^"?(.*?)"?$/)[1]
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
# @return [Boolean] are there any changes in the index or working directory?
|
102
|
-
def clean?
|
103
|
-
@unmerged.empty? and @modified.empty? and @deleted.empty? and @added.empty? and @unknown.empty?
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
@@ -1,298 +0,0 @@
|
|
1
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
-
# you may not use this file except in compliance with the License.
|
3
|
-
# You may obtain a copy of the License at
|
4
|
-
#
|
5
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
7
|
-
# Unless required by applicable law or agreed to in writing, software
|
8
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
-
# See the License for the specific language governing permissions and
|
11
|
-
# limitations under the License.
|
12
|
-
|
13
|
-
require 'git-process/git_lib'
|
14
|
-
require 'highline/import'
|
15
|
-
require 'octokit'
|
16
|
-
require 'uri'
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
# Provides methods related to GitHub configuration
|
21
|
-
#
|
22
|
-
module GitHubService
|
23
|
-
|
24
|
-
class Configuration
|
25
|
-
|
26
|
-
attr_reader :git_config
|
27
|
-
|
28
|
-
|
29
|
-
#
|
30
|
-
# @param [GitProc::GitConfig] git_config
|
31
|
-
# @param [Hash] opts
|
32
|
-
# @option opts [String] :remote_name (#remote_name) The "remote" name to use (e.g., 'origin')
|
33
|
-
# @option opts [String] :user the username to authenticate with
|
34
|
-
# @option opts [String] :password (#password) the password to authenticate with
|
35
|
-
#
|
36
|
-
# @return [String] the OAuth token
|
37
|
-
#
|
38
|
-
def initialize(git_config, opts = {})
|
39
|
-
@git_config = git_config
|
40
|
-
@user = opts[:user]
|
41
|
-
@password = opts[:password]
|
42
|
-
@remote_name = opts[:remote_name]
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
# @return [String]
|
47
|
-
def remote_name
|
48
|
-
unless @remote_name
|
49
|
-
@remote_name = gitlib.remote.name
|
50
|
-
raise NoRemoteRepository.new('No remote repository is defined') unless @remote_name
|
51
|
-
end
|
52
|
-
@remote_name
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
# @return [String]
|
57
|
-
def user
|
58
|
-
@user ||= Configuration.ask_for_user(gitlib)
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
# @return [String]
|
63
|
-
def password
|
64
|
-
@password ||= Configuration.ask_for_password
|
65
|
-
end
|
66
|
-
|
67
|
-
|
68
|
-
# @return [Octokit::Client]
|
69
|
-
def client
|
70
|
-
create_client
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
# @return [GitProc::GitLib]
|
75
|
-
def gitlib
|
76
|
-
@git_config.gitlib
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
# @return [Octokit::Client]
|
81
|
-
def create_client(opts = {})
|
82
|
-
logger.debug { "Creating GitHub client for user #{user} using token '#{auth_token}'" }
|
83
|
-
|
84
|
-
base_url = opts[:base_url] || base_github_api_url_for_remote
|
85
|
-
|
86
|
-
configure_octokit(:base_url => base_url)
|
87
|
-
|
88
|
-
Octokit::Client.new(:login => user, :oauth_token => auth_token)
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
|
-
#
|
93
|
-
# Configures Octokit to use the appropriate URLs for GitHub server.
|
94
|
-
#
|
95
|
-
# @param [Hash] opts the options to create a message with
|
96
|
-
# @option opts [String] :base_url The base URL to use for the GitHub server
|
97
|
-
#
|
98
|
-
# @return [void]
|
99
|
-
#
|
100
|
-
def configure_octokit(opts = {})
|
101
|
-
base_url = opts[:base_url] || base_github_api_url_for_remote
|
102
|
-
Octokit.configure do |c|
|
103
|
-
c.api_endpoint = api_endpoint(base_url)
|
104
|
-
c.web_endpoint = web_endpoint(base_url)
|
105
|
-
c.faraday_config do |f|
|
106
|
-
#f.response :logger
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
#
|
113
|
-
# Determines the URL used for using the GitHub REST interface based
|
114
|
-
# on a "base" URL.
|
115
|
-
#
|
116
|
-
# If the "base_url" is not provided, then it assumes that this object
|
117
|
-
# has a "remote_name" property that it can ask.
|
118
|
-
#
|
119
|
-
# @param [String] base_url the base GitHub URL
|
120
|
-
# @return [String] the GitHub REST API URL
|
121
|
-
#
|
122
|
-
def api_endpoint(base_url = nil)
|
123
|
-
base_url ||= base_github_api_url_for_remote
|
124
|
-
if /github.com/ !~ base_url
|
125
|
-
"#{base_url}/api/v3"
|
126
|
-
else
|
127
|
-
Octokit::Configuration::DEFAULT_API_ENDPOINT
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
|
132
|
-
#
|
133
|
-
# Determines the URL used for using the GitHub web interface based
|
134
|
-
# on a "base" URL.
|
135
|
-
#
|
136
|
-
# If the "base_url" is not provided, then it assumes that this object
|
137
|
-
# has a "remote_name" property that it can ask.
|
138
|
-
#
|
139
|
-
# @param [String] base_url the base GitHub URL
|
140
|
-
# @return [String] the GitHub web URL
|
141
|
-
#
|
142
|
-
def web_endpoint(base_url = nil)
|
143
|
-
base_url ||= base_github_api_url_for_remote
|
144
|
-
if /github.com/ !~ base_url
|
145
|
-
base_url
|
146
|
-
else
|
147
|
-
Octokit::Configuration::DEFAULT_WEB_ENDPOINT
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
#
|
153
|
-
# Determines the base URL for GitHub API calls.
|
154
|
-
#
|
155
|
-
# @return [String] the base GitHub API URL
|
156
|
-
#
|
157
|
-
def base_github_api_url_for_remote
|
158
|
-
url = gitlib.remote.expanded_url(remote_name)
|
159
|
-
Configuration.url_to_base_github_api_url(url)
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
#
|
164
|
-
# Translate any "git known" URL to the HTTP(S) URL needed for
|
165
|
-
# GitHub API calls.
|
166
|
-
#
|
167
|
-
# @param url [String] the URL to translate
|
168
|
-
# @return [String] the base GitHub API URL
|
169
|
-
#
|
170
|
-
def self.url_to_base_github_api_url(url)
|
171
|
-
uri = URI.parse(url)
|
172
|
-
host = uri.host
|
173
|
-
|
174
|
-
if /github.com$/ =~ host
|
175
|
-
'https://api.github.com'
|
176
|
-
else
|
177
|
-
scheme = uri.scheme
|
178
|
-
scheme = 'https' unless scheme.start_with?('http')
|
179
|
-
host = 'unknown-host' unless host
|
180
|
-
"#{scheme}://#{host}"
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
|
185
|
-
#
|
186
|
-
# Create a GitHub client using username and password specifically.
|
187
|
-
# Meant to be used to get an OAuth token for "regular" client calls.
|
188
|
-
#
|
189
|
-
# @param [Hash] opts the options to create a message with
|
190
|
-
# @option opts [String] :base_url The base URL to use for the GitHub server
|
191
|
-
# @option opts [String] :remote_name (#remote_name) The "remote" name to use (e.g., 'origin')
|
192
|
-
# @option opts [String] :user the username to authenticate with
|
193
|
-
# @option opts [String] :password (#password) the password to authenticate with
|
194
|
-
#
|
195
|
-
def create_pw_client(opts = {})
|
196
|
-
usr = opts[:user] || user()
|
197
|
-
pw = opts[:password] || password()
|
198
|
-
|
199
|
-
logger.debug { "Creating GitHub client for user #{usr} using BasicAuth w/ password" }
|
200
|
-
|
201
|
-
configure_octokit(opts)
|
202
|
-
|
203
|
-
Octokit::Client.new(:login => usr, :password => pw)
|
204
|
-
end
|
205
|
-
|
206
|
-
|
207
|
-
#
|
208
|
-
# Returns to OAuth token. If it's in .git/config, returns that.
|
209
|
-
# Otherwise it connects to GitHub to get the authorization token.
|
210
|
-
#
|
211
|
-
# @param [Hash] opts
|
212
|
-
# @option opts [String] :base_url The base URL to use for the GitHub server
|
213
|
-
# @option opts [String] :remote_name (#remote_name) The "remote" name to use (e.g., 'origin')
|
214
|
-
# @option opts [String] :user the username to authenticate with
|
215
|
-
# @option opts [String] :password (#password) the password to authenticate with
|
216
|
-
#
|
217
|
-
# @return [String]
|
218
|
-
#
|
219
|
-
def auth_token(opts = {})
|
220
|
-
get_config_auth_token() || create_authorization(opts)
|
221
|
-
end
|
222
|
-
|
223
|
-
|
224
|
-
#
|
225
|
-
# Connects to GitHub to get an OAuth token.
|
226
|
-
#
|
227
|
-
# @param [Hash] opts
|
228
|
-
# @option opts [String] :base_url The base URL to use for the GitHub server
|
229
|
-
# @option opts [String] :remote_name (#remote_name) The "remote" name to use (e.g., 'origin')
|
230
|
-
# @option opts [String] :user the username to authenticate with
|
231
|
-
# @option opts [String] :password (#password) the password to authenticate with
|
232
|
-
#
|
233
|
-
# @return [String] the OAuth token
|
234
|
-
#
|
235
|
-
def create_authorization(opts = {})
|
236
|
-
username = opts[:user] || self.user
|
237
|
-
remote = opts[:remote_name] || self.remote_name
|
238
|
-
logger.info("Authorizing #{username} to work with #{remote}.")
|
239
|
-
|
240
|
-
auth = create_pw_client(opts).create_authorization(
|
241
|
-
:scopes => %w(repo user gist),
|
242
|
-
:note => 'Git-Process',
|
243
|
-
:note_url => 'http://jdigger.github.com/git-process')
|
244
|
-
|
245
|
-
config_auth_token = auth['token']
|
246
|
-
|
247
|
-
# remember it for next time
|
248
|
-
gitlib.config['gitProcess.github.authToken'] = config_auth_token
|
249
|
-
|
250
|
-
config_auth_token
|
251
|
-
end
|
252
|
-
|
253
|
-
|
254
|
-
# @return [String]
|
255
|
-
def get_config_auth_token
|
256
|
-
c_auth_token = gitlib.config['gitProcess.github.authToken']
|
257
|
-
(c_auth_token.nil? or c_auth_token.empty?) ? nil : c_auth_token
|
258
|
-
end
|
259
|
-
|
260
|
-
|
261
|
-
def logger
|
262
|
-
gitlib.logger
|
263
|
-
end
|
264
|
-
|
265
|
-
|
266
|
-
private
|
267
|
-
|
268
|
-
|
269
|
-
def self.ask_for_user(gitlib)
|
270
|
-
user = gitlib.config['github.user']
|
271
|
-
if user.nil? or user.empty?
|
272
|
-
user = ask("Your <%= color('GitHub', [:bold, :blue]) %> username: ") do |q|
|
273
|
-
q.validate = /^\w\w+$/
|
274
|
-
end
|
275
|
-
gitlib.config['github.user'] = user
|
276
|
-
end
|
277
|
-
user
|
278
|
-
end
|
279
|
-
|
280
|
-
|
281
|
-
def self.ask_for_password
|
282
|
-
ask("Your <%= color('GitHub', [:bold, :blue]) %> password: ") do |q|
|
283
|
-
q.validate = /^\S\S+$/
|
284
|
-
q.echo = 'x'
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
end
|
289
|
-
|
290
|
-
|
291
|
-
class Error < ::StandardError
|
292
|
-
end
|
293
|
-
|
294
|
-
|
295
|
-
class NoRemoteRepository < Error
|
296
|
-
end
|
297
|
-
|
298
|
-
end
|
@@ -1,151 +0,0 @@
|
|
1
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
-
# you may not use this file except in compliance with the License.
|
3
|
-
# You may obtain a copy of the License at
|
4
|
-
#
|
5
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
7
|
-
# Unless required by applicable law or agreed to in writing, software
|
8
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
-
# See the License for the specific language governing permissions and
|
11
|
-
# limitations under the License.
|
12
|
-
|
13
|
-
require 'git-process/github_configuration'
|
14
|
-
require 'octokit'
|
15
|
-
require 'octokit/repository'
|
16
|
-
|
17
|
-
|
18
|
-
module GitHub
|
19
|
-
|
20
|
-
class PullRequest
|
21
|
-
attr_reader :gitlib, :repo, :remote_name, :client, :configuration
|
22
|
-
|
23
|
-
|
24
|
-
def initialize(lib, remote_name, repo, opts = {})
|
25
|
-
@gitlib = lib
|
26
|
-
@repo = repo
|
27
|
-
@remote_name = remote_name
|
28
|
-
@configuration = GitHubService::Configuration.new(gitlib.config, :user => opts[:user], :password => opts[:password])
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
def client
|
33
|
-
@client ||= @configuration.create_client
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
def pull_requests(state = 'open', opts = {})
|
38
|
-
@pull_requests ||= client.pull_requests(repo, state, opts)
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
def create(base, head, title, body)
|
43
|
-
logger.info { "Creating a pull request asking for '#{head}' to be merged into '#{base}' on #{repo}." }
|
44
|
-
begin
|
45
|
-
client.create_pull_request(repo, base, head, title, body)
|
46
|
-
rescue Octokit::UnprocessableEntity => exp
|
47
|
-
pull = pull_requests.find { |p| p[:head][:ref] == head and p[:base][:ref] == base }
|
48
|
-
if pull
|
49
|
-
logger.warn { "Pull request already exists. See #{pull[:html_url]}" }
|
50
|
-
else
|
51
|
-
logger.warn { "UnprocessableEntity: #{exp}" }
|
52
|
-
end
|
53
|
-
pull
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
def logger
|
59
|
-
@gitlib.logger
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
def pull_request(pr_number)
|
64
|
-
client.pull_request(repo, pr_number)
|
65
|
-
end
|
66
|
-
|
67
|
-
|
68
|
-
#
|
69
|
-
# Find the pull request (PR) that matches the 'head' and 'base'.
|
70
|
-
#
|
71
|
-
# @param [String] base what the PR is merging into
|
72
|
-
# @param [String] head the branch of the PR
|
73
|
-
#
|
74
|
-
# @return [Hash]
|
75
|
-
# @raise [NotFoundError] if the pull request does not exist
|
76
|
-
#
|
77
|
-
def get_pull_request(base, head)
|
78
|
-
find_pull_request(base, head, true)
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
#
|
83
|
-
# Find the pull request (PR) that matches the 'head' and 'base'.
|
84
|
-
#
|
85
|
-
# @param [String] base what the PR is merging into
|
86
|
-
# @param [String] head the branch of the PR
|
87
|
-
# @param [boolean] error_if_missing should this error-out if the PR is not found?
|
88
|
-
#
|
89
|
-
# @return [Hash, nil]
|
90
|
-
# @raise [NotFoundError] if the pull request does not exist and 'error_if_missing' is true
|
91
|
-
#
|
92
|
-
def find_pull_request(base, head, error_if_missing = false)
|
93
|
-
logger.info { "Looking for a pull request asking for '#{head}' to be merged into '#{base}' on #{repo}." }
|
94
|
-
|
95
|
-
json = pull_requests
|
96
|
-
pr = json.find { |p| p[:head][:ref] == head and p[:base][:ref] == base }
|
97
|
-
|
98
|
-
raise NotFoundError.new(base, head, repo, json) if error_if_missing && pr.nil?
|
99
|
-
|
100
|
-
pr
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
def close(*args)
|
105
|
-
pull_number = if args.size == 2
|
106
|
-
get_pull_request(args[0], args[1])[:number]
|
107
|
-
elsif args.size == 1
|
108
|
-
args[0]
|
109
|
-
else
|
110
|
-
raise ArgumentError.new('close(..) needs 1 or 2 arguments')
|
111
|
-
end
|
112
|
-
|
113
|
-
logger.info { "Closing a pull request \##{pull_number} on #{repo}." }
|
114
|
-
|
115
|
-
client.patch("repos/#{Octokit::Repository.new(repo)}/pulls/#{pull_number}", {:state => 'closed'})
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
class NotFoundError < StandardError
|
120
|
-
attr_reader :base, :head, :repo
|
121
|
-
|
122
|
-
|
123
|
-
def initialize(base, head, repo, pull_requests_json)
|
124
|
-
@base = base
|
125
|
-
@head = head
|
126
|
-
@repo = repo
|
127
|
-
|
128
|
-
@pull_requests = pull_requests_json.map do |p|
|
129
|
-
{:head => p[:head][:ref], :base => p[:base][:ref]}
|
130
|
-
end
|
131
|
-
|
132
|
-
msg = "Could not find a pull request for '#{head}' to be merged with '#{base}' on #{repo}."
|
133
|
-
msg += "\n\nExisting Pull Requests:"
|
134
|
-
msg = pull_requests.inject(msg) { |a, v| "#{a}\n #{v[:head]} -> #{v[:base]}" }
|
135
|
-
|
136
|
-
super(msg)
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
def pull_requests
|
141
|
-
@pull_requests
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
private
|
147
|
-
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|