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.
- data/CHANGELOG.md +37 -9
- data/Gemfile +2 -2
- data/Gemfile.lock +17 -17
- data/README.md +14 -7
- data/bin/git-new-fb +10 -2
- data/bin/git-pull-request +30 -6
- data/bin/git-sync +5 -2
- data/bin/git-to-master +62 -11
- data/git-process.gemspec +15 -15
- data/lib/git-process/abstract_error_builder.rb +0 -3
- data/lib/git-process/changed_file_helper.rb +30 -24
- data/lib/git-process/git_abstract_merge_error_builder.rb +31 -11
- data/lib/git-process/git_branch.rb +5 -0
- data/lib/git-process/git_config.rb +153 -0
- data/lib/git-process/git_lib.rb +212 -164
- data/lib/git-process/git_logger.rb +84 -0
- data/lib/git-process/git_merge_error.rb +3 -14
- data/lib/git-process/git_process.rb +44 -73
- data/lib/git-process/git_process_options.rb +6 -6
- data/lib/git-process/git_rebase_error.rb +4 -13
- data/lib/git-process/git_remote.rb +254 -0
- data/lib/git-process/github_configuration.rb +298 -0
- data/lib/git-process/github_pull_request.rb +65 -27
- data/lib/git-process/new_fb.rb +14 -4
- data/lib/git-process/parked_changes_error.rb +1 -1
- data/lib/git-process/pull_request.rb +100 -13
- data/lib/git-process/pull_request_error.rb +25 -0
- data/lib/git-process/rebase_to_master.rb +47 -27
- data/lib/git-process/sync.rb +48 -33
- data/lib/git-process/uncommitted_changes_error.rb +1 -1
- data/lib/git-process/version.rb +2 -2
- data/spec/GitRepoHelper.rb +48 -25
- data/spec/changed_file_helper_spec.rb +39 -58
- data/spec/git_abstract_merge_error_builder_spec.rb +42 -33
- data/spec/git_branch_spec.rb +30 -30
- data/spec/git_config_spec.rb +45 -0
- data/spec/git_lib_spec.rb +103 -122
- data/spec/git_logger_spec.rb +66 -0
- data/spec/git_process_spec.rb +81 -81
- data/spec/git_remote_spec.rb +188 -0
- data/spec/git_status_spec.rb +36 -36
- data/spec/github_configuration_spec.rb +152 -0
- data/spec/github_pull_request_spec.rb +39 -35
- data/spec/github_test_helper.rb +49 -0
- data/spec/new_fb_spec.rb +65 -24
- data/spec/pull_request_helper.rb +94 -0
- data/spec/pull_request_spec.rb +128 -0
- data/spec/rebase_to_master_spec.rb +241 -145
- data/spec/spec_helper.rb +20 -0
- data/spec/sync_spec.rb +115 -109
- metadata +34 -20
- data/lib/git-process/github_client.rb +0 -83
- data/lib/git-process/github_service.rb +0 -174
- 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
|
data/spec/github_service_spec.rb
DELETED
@@ -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
|