git-process 1.0.11 → 1.1.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 (54) hide show
  1. data/CHANGELOG.md +37 -9
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +17 -17
  4. data/README.md +14 -7
  5. data/bin/git-new-fb +10 -2
  6. data/bin/git-pull-request +30 -6
  7. data/bin/git-sync +5 -2
  8. data/bin/git-to-master +62 -11
  9. data/git-process.gemspec +15 -15
  10. data/lib/git-process/abstract_error_builder.rb +0 -3
  11. data/lib/git-process/changed_file_helper.rb +30 -24
  12. data/lib/git-process/git_abstract_merge_error_builder.rb +31 -11
  13. data/lib/git-process/git_branch.rb +5 -0
  14. data/lib/git-process/git_config.rb +153 -0
  15. data/lib/git-process/git_lib.rb +212 -164
  16. data/lib/git-process/git_logger.rb +84 -0
  17. data/lib/git-process/git_merge_error.rb +3 -14
  18. data/lib/git-process/git_process.rb +44 -73
  19. data/lib/git-process/git_process_options.rb +6 -6
  20. data/lib/git-process/git_rebase_error.rb +4 -13
  21. data/lib/git-process/git_remote.rb +254 -0
  22. data/lib/git-process/github_configuration.rb +298 -0
  23. data/lib/git-process/github_pull_request.rb +65 -27
  24. data/lib/git-process/new_fb.rb +14 -4
  25. data/lib/git-process/parked_changes_error.rb +1 -1
  26. data/lib/git-process/pull_request.rb +100 -13
  27. data/lib/git-process/pull_request_error.rb +25 -0
  28. data/lib/git-process/rebase_to_master.rb +47 -27
  29. data/lib/git-process/sync.rb +48 -33
  30. data/lib/git-process/uncommitted_changes_error.rb +1 -1
  31. data/lib/git-process/version.rb +2 -2
  32. data/spec/GitRepoHelper.rb +48 -25
  33. data/spec/changed_file_helper_spec.rb +39 -58
  34. data/spec/git_abstract_merge_error_builder_spec.rb +42 -33
  35. data/spec/git_branch_spec.rb +30 -30
  36. data/spec/git_config_spec.rb +45 -0
  37. data/spec/git_lib_spec.rb +103 -122
  38. data/spec/git_logger_spec.rb +66 -0
  39. data/spec/git_process_spec.rb +81 -81
  40. data/spec/git_remote_spec.rb +188 -0
  41. data/spec/git_status_spec.rb +36 -36
  42. data/spec/github_configuration_spec.rb +152 -0
  43. data/spec/github_pull_request_spec.rb +39 -35
  44. data/spec/github_test_helper.rb +49 -0
  45. data/spec/new_fb_spec.rb +65 -24
  46. data/spec/pull_request_helper.rb +94 -0
  47. data/spec/pull_request_spec.rb +128 -0
  48. data/spec/rebase_to_master_spec.rb +241 -145
  49. data/spec/spec_helper.rb +20 -0
  50. data/spec/sync_spec.rb +115 -109
  51. metadata +34 -20
  52. data/lib/git-process/github_client.rb +0 -83
  53. data/lib/git-process/github_service.rb +0 -174
  54. data/spec/github_service_spec.rb +0 -211
@@ -1,83 +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 'octokit'
14
-
15
- module Octokit
16
-
17
- module Connection
18
-
19
- #
20
- # Unfortunately, there's no way to change the URL except by completely replacing
21
- # this method.
22
- #
23
- def connection(authenticate=true, raw=false, version=3, force_urlencoded=false)
24
- if site
25
- url = site
26
- elsif version == 2
27
- url = "https://github.com"
28
- else
29
- url = "https://api.github.com"
30
- end
31
-
32
- options = {
33
- :proxy => proxy,
34
- :ssl => {:verify => false},
35
- :url => url,
36
- }
37
-
38
- options.merge!(:params => {:access_token => oauth_token}) if oauthed? && !authenticated?
39
-
40
- connection = Faraday.new(options) do |builder|
41
- if version >= 3 && !force_urlencoded
42
- builder.request :json
43
- else
44
- builder.request :url_encoded
45
- end
46
- builder.use Faraday::Response::RaiseOctokitError
47
- unless raw
48
- builder.use FaradayMiddleware::Mashify
49
- builder.use FaradayMiddleware::ParseJson
50
- end
51
- builder.adapter(adapter)
52
- end
53
- connection.basic_auth authentication[:login], authentication[:password] if authenticate and authenticated?
54
- connection
55
- end
56
- end
57
-
58
- end
59
-
60
-
61
- class GitHubClient < Octokit::Client
62
-
63
- def site
64
- @site
65
- end
66
-
67
-
68
- def site=(new_site)
69
- @site = new_site
70
- end
71
-
72
-
73
- alias :old_request :request
74
-
75
-
76
- def request(method, path, options={})
77
- if /api.github.com/ !~ site
78
- path = "/api/v3/#{path}"
79
- end
80
- old_request(method, path, options)
81
- end
82
-
83
- end
@@ -1,174 +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 'highline/import'
14
- require 'git-process/github_client'
15
- require 'uri'
16
-
17
-
18
- module GitHubService
19
-
20
- def client
21
- if @client.nil?
22
- auth_token
23
- logger.debug { "Creating GitHub client for user #{user} using token '#{auth_token}'" }
24
- @client = GitHubClient.new(:login => user, :oauth_token => auth_token)
25
- @client.site = site
26
- end
27
- @client
28
- end
29
-
30
-
31
- def site(opts = {})
32
- @site ||= compute_site(opts)
33
- end
34
-
35
-
36
- def compute_site(opts = {})
37
- origin_url = lib.config('remote.origin.url')
38
-
39
- raise GitHubService::NoRemoteRepository.new("There is no value set for 'remote.origin.url'") if origin_url.empty?
40
-
41
- if /^git@/ =~ origin_url
42
- host = origin_url.sub(/^git@(.*?):.*$/, '\1')
43
- site = host_to_site(host, true)
44
- else
45
- uri = URI.parse(origin_url)
46
- host = uri.host
47
- scheme = uri.scheme
48
-
49
- raise URI::InvalidURIError.new("Need a scheme in URI: '#{origin_url}'") unless scheme
50
-
51
- if host.nil?
52
- # assume that the 'scheme' is the named configuration in ~/.ssh/config
53
- host = hostname_from_ssh_config(scheme, opts[:ssh_config_file] ||= "#{ENV['HOME']}/.ssh/config")
54
- end
55
-
56
- raise GitHubService::NoRemoteRepository.new("Could not determine a host from #{origin_url}") if host.nil?
57
-
58
- site = host_to_site(host, !(scheme == 'http'))
59
- end
60
- site
61
- end
62
-
63
-
64
- def hostname_from_ssh_config(host_alias, config_file)
65
- if File.exists?(config_file)
66
- config_lines = File.new(config_file).readlines
67
-
68
- in_host_section = false
69
- host_name = nil
70
-
71
- config_lines.each do |line|
72
- line.chop!
73
- if /^\s*Host\s+#{host_alias}\s*$/ =~ line
74
- in_host_section = true
75
- next
76
- end
77
- if in_host_section and (/^\s*HostName\s+\S+\s*$/ =~ line)
78
- host_name = line.sub(/^\s*HostName\s+(\S+)\s*$/, '\1')
79
- break
80
- end
81
- end
82
- host_name
83
- else
84
- nil
85
- end
86
- end
87
-
88
-
89
- def host_to_site(host, ssl)
90
- if /github.com$/ =~ host
91
- 'https://api.github.com'
92
- else
93
- "http#{ssl ? 's' : ''}://#{host}"
94
- end
95
- end
96
-
97
-
98
- private :host_to_site, :compute_site
99
-
100
-
101
- def pw_client
102
- unless @pw_client
103
- logger.debug { "Creating GitHub client for user #{user} using password #{password}" }
104
- @pw_client = GitHubClient.new(:login => user, :password => password)
105
- @pw_client.site = site
106
- end
107
- @pw_client
108
- end
109
-
110
-
111
- def user
112
- unless @user
113
- user = lib.config('github.user')
114
- if user.nil? or user.empty?
115
- user = ask("Your <%= color('GitHub', [:bold, :blue]) %> username: ") do |q|
116
- q.validate = /^\w\w+$/
117
- end
118
- lib.config('github.user', user)
119
- end
120
- @user = user
121
- end
122
- @user
123
- end
124
-
125
-
126
- def password
127
- unless @password
128
- @password = ask("Your <%= color('GitHub', [:bold, :blue]) %> password: ") do |q|
129
- q.validate = /^\S\S+$/
130
- q.echo = 'x'
131
- end
132
- end
133
- @password
134
- end
135
-
136
-
137
- def auth_token
138
- @auth_token ||= config_auth_token || create_authorization
139
- end
140
-
141
-
142
- def create_authorization
143
- logger.info("Authorizing #{user} to work with #{site}.")
144
- auth = pw_client.create_authorization(:scopes => %w(repo user gist),
145
- :note => 'Git-Process',
146
- :note_url => 'http://jdigger.github.com/git-process')
147
- config_auth_token = auth['token']
148
- lib.config('gitProcess.github.authToken', config_auth_token)
149
- config_auth_token
150
- end
151
-
152
-
153
- def config_auth_token
154
- if @auth_token.nil?
155
- c_auth_token = lib.config('gitProcess.github.authToken')
156
- @auth_token = (c_auth_token.nil? or c_auth_token.empty?) ? nil : c_auth_token
157
- end
158
- @auth_token
159
- end
160
-
161
-
162
- def logger
163
- @lib.logger
164
- end
165
-
166
-
167
- class GithubServiceError < StandardError
168
- end
169
-
170
-
171
- class NoRemoteRepository < GithubServiceError
172
- end
173
-
174
- end
@@ -1,211 +0,0 @@
1
- require 'git-process/github_service'
2
- require 'webmock/rspec'
3
- require 'json'
4
- require 'octokit'
5
- require 'tempfile'
6
- require 'rspec/mocks/methods'
7
- require 'rspec/mocks/test_double'
8
- require 'rspec/mocks/mock'
9
-
10
-
11
- class GHS
12
- include GitHubService
13
-
14
-
15
- def initialize(user = nil, password = nil, site = nil)
16
- @user = user
17
- @password = password
18
- @site = site
19
-
20
- logger = RSpec::Mocks::Mock.new('logger')
21
- logger.stub(:debug)
22
- logger.stub(:info)
23
-
24
- @lib = RSpec::Mocks::Mock.new('lib')
25
- @lib.stub(:logger).and_return(logger)
26
- end
27
-
28
-
29
- def lib
30
- @lib
31
- end
32
- end
33
-
34
-
35
- describe GitHubService do
36
-
37
- def test_token
38
- 'hfgkdjfgksjhdfkls'
39
- end
40
-
41
-
42
- describe "create_authorization" do
43
-
44
- def ghs
45
- unless @ghs
46
- @ghs = GHS.new('tu', 'dfsdf')
47
- @ghs.lib.stub(:config).with('remote.origin.url').and_return('git@github.com:jdigger/git-process.git')
48
- end
49
- @ghs
50
- end
51
-
52
-
53
- it "should return an auth_token for a good request" do
54
- ghs.lib.should_receive(:config).with('gitProcess.github.authToken', anything).once
55
-
56
- stub_request(:post, /api.github.com\/authorizations/).
57
- to_return(:status => 200, :body => JSON({:token => test_token}))
58
-
59
- ghs.create_authorization().should == test_token
60
- end
61
-
62
-
63
- it "should 401 for bad password" do
64
- stub_request(:post, /api.github.com\/authorizations/).
65
- to_return(:status => 401)
66
-
67
- lambda { ghs.create_authorization() }.should raise_error Octokit::Unauthorized
68
- end
69
-
70
- end
71
-
72
-
73
- describe "auth_token" do
74
-
75
- it "should get the token from config if it exists" do
76
- ghs = GHS.new
77
- ghs.lib.stub(:config).with('github.user').and_return('test_user')
78
- ghs.lib.stub(:config).with('remote.origin.url').and_return('git@github.com:jdigger/git-process.git')
79
- ghs.lib.stub(:config).with('gitProcess.github.authToken').and_return(test_token)
80
-
81
- ghs.auth_token.should == test_token
82
- end
83
-
84
-
85
- it "should get the token from the server if it does not exist in config" do
86
- ghs = GHS.new(nil, 'dfsdf')
87
- ghs.lib.stub(:config).with('github.user').and_return('test_user')
88
- ghs.lib.stub(:config).with('remote.origin.url').and_return('git@github.com:jdigger/git-process.git')
89
- ghs.lib.stub(:config).with('gitProcess.github.authToken').and_return('')
90
- ghs.lib.should_receive(:config).with('gitProcess.github.authToken', anything).once
91
-
92
- stub_request(:post, /api.github.com\/authorizations/).
93
- to_return(:status => 200, :body => JSON({:token => test_token}))
94
-
95
- ghs.auth_token.should == test_token
96
- end
97
-
98
- end
99
-
100
-
101
- describe "user" do
102
-
103
- it "should get the value from config" do
104
- ghs = GHS.new(nil, 'dfsdf')
105
- ghs.lib.stub(:config).with('github.user').and_return('test_user')
106
-
107
- ghs.user.should == 'test_user'
108
- end
109
-
110
-
111
- it "should prompt the user and store it in the config" do
112
- ghs = GHS.new(nil, 'dfsdf')
113
- ghs.lib.stub(:config).with('github.user').and_return('')
114
- ghs.lib.stub(:config).with('github.user', anything).once
115
-
116
- ghs.stub(:ask).with(/username/).and_return('test_user')
117
- ghs.user.should == 'test_user'
118
- end
119
-
120
- end
121
-
122
-
123
- describe "using GHE instead of GitHub.com" do
124
-
125
- def ghs
126
- @ghs ||= GHS.new('tu', 'dfsdf', nil)
127
- end
128
-
129
-
130
- it "should use the correct server and path for a non-GitHub.com site" do
131
- ghs.lib.stub(:config).with('remote.origin.url').and_return('git@myco.com:jdigger/git-process.git')
132
- ghs.lib.should_receive(:config).with('gitProcess.github.authToken', anything).once
133
-
134
- stub_request(:post, /myco.com\/api\/v3\/authorizations/).
135
- to_return(:status => 200, :body => JSON({:token => test_token}))
136
-
137
- ghs.create_authorization().should == test_token
138
- end
139
-
140
-
141
- it "site should work for git@... ssh address" do
142
- ghs.lib.stub(:config).with('remote.origin.url').and_return('git@myco.com:jdigger/git-process.git')
143
-
144
- ghs.site.should == 'https://myco.com'
145
- end
146
-
147
-
148
- it "site should work for https address" do
149
- ghs.lib.stub(:config).with('remote.origin.url').and_return('https://myco.com/jdigger/git-process.git')
150
-
151
- ghs.site.should == 'https://myco.com'
152
- end
153
-
154
-
155
- it "site should work for http address" do
156
- ghs.lib.stub(:config).with('remote.origin.url').and_return('http://jdigger@myco.com/jdigger/git-process.git')
157
-
158
- ghs.site.should == 'http://myco.com'
159
- end
160
-
161
-
162
- it "site should work for git://myco.com/ address" do
163
- ghs.lib.stub(:config).with('remote.origin.url').and_return('git://myco.com/jdigger/git-process.git')
164
-
165
- ghs.site.should == 'https://myco.com'
166
- end
167
-
168
-
169
- it "site should raise an error if remote.origin.url not set" do
170
- ghs.lib.stub(:config).with('remote.origin.url').and_return('')
171
-
172
- lambda { ghs.site }.should raise_error GitHubService::NoRemoteRepository
173
- end
174
-
175
-
176
- it "site should not work for a garbase url address" do
177
- ghs.lib.stub(:config).with('remote.origin.url').and_return('garbage')
178
-
179
- lambda { ghs.site }.should raise_error URI::InvalidURIError
180
- end
181
-
182
-
183
- def in_tempfile(content, &block)
184
- file = Tempfile.new('ssh_config')
185
- file.puts content
186
- file.flush
187
-
188
- begin
189
- block.call(file)
190
- ensure
191
- file.close
192
- file.unlink
193
- end
194
- end
195
-
196
-
197
- it "site should work for an ssh-configged url address" do
198
- ghs.lib.stub(:config).with('remote.origin.url').and_return('mygithub:jdigger/git-process.git')
199
-
200
- content = "\nHost mygithub\n"+
201
- " User git\n"+
202
- " HostName github.myco.com\n"
203
-
204
- in_tempfile(content) do |file|
205
- ghs.site(:ssh_config_file => file.path).should == 'https://github.myco.com'
206
- end
207
- end
208
-
209
- end
210
-
211
- end