git-process 1.0.11 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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