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.
Files changed (58) hide show
  1. data/CHANGELOG.md +14 -1
  2. data/LICENSE +193 -22
  3. data/README.md +212 -71
  4. data/man/git-process.1 +371 -0
  5. metadata +52 -140
  6. data/Gemfile +0 -20
  7. data/Gemfile.lock +0 -53
  8. data/Rakefile +0 -16
  9. data/bin/git-new-fb +0 -58
  10. data/bin/git-pull-request +0 -107
  11. data/bin/git-sync +0 -73
  12. data/bin/git-to-master +0 -133
  13. data/git-process.gemspec +0 -25
  14. data/lib/git-process/abstract_error_builder.rb +0 -53
  15. data/lib/git-process/changed_file_helper.rb +0 -115
  16. data/lib/git-process/git_abstract_merge_error_builder.rb +0 -146
  17. data/lib/git-process/git_branch.rb +0 -105
  18. data/lib/git-process/git_branches.rb +0 -73
  19. data/lib/git-process/git_config.rb +0 -153
  20. data/lib/git-process/git_lib.rb +0 -512
  21. data/lib/git-process/git_logger.rb +0 -84
  22. data/lib/git-process/git_merge_error.rb +0 -28
  23. data/lib/git-process/git_process.rb +0 -172
  24. data/lib/git-process/git_process_error.rb +0 -18
  25. data/lib/git-process/git_process_options.rb +0 -99
  26. data/lib/git-process/git_rebase_error.rb +0 -30
  27. data/lib/git-process/git_remote.rb +0 -256
  28. data/lib/git-process/git_status.rb +0 -108
  29. data/lib/git-process/github_configuration.rb +0 -298
  30. data/lib/git-process/github_pull_request.rb +0 -151
  31. data/lib/git-process/new_fb.rb +0 -50
  32. data/lib/git-process/parked_changes_error.rb +0 -41
  33. data/lib/git-process/pull_request.rb +0 -134
  34. data/lib/git-process/pull_request_error.rb +0 -25
  35. data/lib/git-process/rebase_to_master.rb +0 -148
  36. data/lib/git-process/sync.rb +0 -136
  37. data/lib/git-process/uncommitted_changes_error.rb +0 -23
  38. data/lib/git-process/version.rb +0 -22
  39. data/spec/FileHelpers.rb +0 -19
  40. data/spec/GitRepoHelper.rb +0 -123
  41. data/spec/changed_file_helper_spec.rb +0 -127
  42. data/spec/git_abstract_merge_error_builder_spec.rb +0 -126
  43. data/spec/git_branch_spec.rb +0 -123
  44. data/spec/git_config_spec.rb +0 -45
  45. data/spec/git_lib_spec.rb +0 -176
  46. data/spec/git_logger_spec.rb +0 -66
  47. data/spec/git_process_spec.rb +0 -208
  48. data/spec/git_remote_spec.rb +0 -227
  49. data/spec/git_status_spec.rb +0 -122
  50. data/spec/github_configuration_spec.rb +0 -152
  51. data/spec/github_pull_request_spec.rb +0 -96
  52. data/spec/github_test_helper.rb +0 -49
  53. data/spec/new_fb_spec.rb +0 -130
  54. data/spec/pull_request_helper.rb +0 -94
  55. data/spec/pull_request_spec.rb +0 -128
  56. data/spec/rebase_to_master_spec.rb +0 -429
  57. data/spec/spec_helper.rb +0 -21
  58. 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