git-process 1.1.4 → 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.
- 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
|