git_helper 3.2.2 → 3.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +134 -0
- data/Guardfile +3 -1
- data/README.md +10 -5
- data/Rakefile +2 -0
- data/bin/git-helper +24 -12
- data/lib/git_helper.rb +6 -2
- data/lib/git_helper/change_remote.rb +15 -6
- data/lib/git_helper/checkout_default.rb +2 -0
- data/lib/git_helper/clean_branches.rb +2 -0
- data/lib/git_helper/code_request.rb +33 -19
- data/lib/git_helper/empty_commit.rb +2 -0
- data/lib/git_helper/forget_local_commits.rb +2 -0
- data/lib/git_helper/git_config_reader.rb +12 -6
- data/lib/git_helper/gitlab_client.rb +2 -0
- data/lib/git_helper/local_code.rb +18 -8
- data/lib/git_helper/merge_request.rb +90 -70
- data/lib/git_helper/new_branch.rb +4 -2
- data/lib/git_helper/octokit_client.rb +2 -0
- data/lib/git_helper/pull_request.rb +97 -66
- data/lib/git_helper/setup.rb +116 -0
- data/lib/git_helper/version.rb +3 -1
- data/spec/git_helper/change_remote_spec.rb +24 -24
- data/spec/git_helper/checkout_default_spec.rb +2 -0
- data/spec/git_helper/clean_branches_spec.rb +2 -0
- data/spec/git_helper/code_request_spec.rb +31 -28
- data/spec/git_helper/empty_commit_spec.rb +2 -0
- data/spec/git_helper/forget_local_commits_spec.rb +2 -0
- data/spec/git_helper/git_config_reader_spec.rb +32 -4
- data/spec/git_helper/gitlab_client_spec.rb +2 -0
- data/spec/git_helper/local_code_spec.rb +2 -0
- data/spec/git_helper/merge_request_spec.rb +24 -23
- data/spec/git_helper/new_branch_spec.rb +10 -8
- data/spec/git_helper/octokit_client_spec.rb +2 -0
- data/spec/git_helper/pull_request_spec.rb +20 -18
- data/spec/git_helper/setup_spec.rb +183 -0
- data/spec/spec_helper.rb +4 -1
- metadata +38 -9
- data/lib/git_helper/highline_cli.rb +0 -33
- data/spec/git_helper/highline_cli_spec.rb +0 -51
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitHelper
|
4
|
+
class Setup
|
5
|
+
def execute
|
6
|
+
execute_config_file
|
7
|
+
execute_plugins
|
8
|
+
end
|
9
|
+
|
10
|
+
# rubocop:disable Style/ConditionalAssignment
|
11
|
+
private def execute_config_file
|
12
|
+
if config_file_exists?
|
13
|
+
answer = highline.ask_yes_no(
|
14
|
+
"It looks like the #{config_file} file already exists. Do you wish to replace it? (y/n)",
|
15
|
+
{ required: true }
|
16
|
+
)
|
17
|
+
else
|
18
|
+
answer = true
|
19
|
+
end
|
20
|
+
|
21
|
+
create_or_update_config_file if answer
|
22
|
+
end
|
23
|
+
# rubocop:enable Style/ConditionalAssignment
|
24
|
+
|
25
|
+
private def execute_plugins
|
26
|
+
answer = highline.ask_yes_no(
|
27
|
+
'Do you wish to set up the Git Helper plugins? (y/n) (This process will ' \
|
28
|
+
'attempt to use your GitHub personal access token to authenticate)',
|
29
|
+
{ required: true }
|
30
|
+
)
|
31
|
+
|
32
|
+
return unless answer
|
33
|
+
|
34
|
+
create_or_update_plugin_files
|
35
|
+
puts "\nNow add this line to your ~/.bash_profile:\n" \
|
36
|
+
' export PATH=/path/to/computer/home/.git_helper/plugins:$PATH'
|
37
|
+
puts "\nDone!"
|
38
|
+
end
|
39
|
+
|
40
|
+
private def create_or_update_config_file
|
41
|
+
contents = generate_file_contents
|
42
|
+
puts "Creating or updating your #{config_file} file..."
|
43
|
+
File.open(config_file, 'w') { |file| file.puts contents }
|
44
|
+
puts "\nDone!\n\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
private def config_file_exists?
|
48
|
+
File.exist?(config_file)
|
49
|
+
end
|
50
|
+
|
51
|
+
# rubocop:disable Metrics/MethodLength
|
52
|
+
private def generate_file_contents
|
53
|
+
file_contents = ''.dup
|
54
|
+
|
55
|
+
if highline.ask_yes_no('Do you wish to set up GitHub credentials? (y/n)', { required: true })
|
56
|
+
file_contents << ":github_user: #{ask_question('GitHub username?')}\n"
|
57
|
+
file_contents << ':github_token: ' \
|
58
|
+
"#{ask_question(
|
59
|
+
'GitHub personal access token? (Navigate to https://github.com/settings/tokens ' \
|
60
|
+
'to create a new personal access token)',
|
61
|
+
secret: true
|
62
|
+
)}\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
if highline.ask_yes_no('Do you wish to set up GitLab credentials? (y/n)', { required: true })
|
66
|
+
file_contents << ":gitlab_user: #{ask_question('GitLab username?')}\n"
|
67
|
+
file_contents << ':gitlab_token: ' \
|
68
|
+
"#{ask_question(
|
69
|
+
'GitLab personal access token? (Navigate to https://gitlab.com/-/profile/personal_access_tokens' \
|
70
|
+
' to create a new personal access token)',
|
71
|
+
secret: true
|
72
|
+
)}\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
file_contents.strip
|
76
|
+
end
|
77
|
+
# rubocop:enable Metrics/MethodLength
|
78
|
+
|
79
|
+
private def ask_question(prompt, secret: false)
|
80
|
+
highline.ask(prompt, { required: true, secret: secret })
|
81
|
+
end
|
82
|
+
|
83
|
+
# rubocop:disable Metrics/MethodLength
|
84
|
+
# rubocop:disable Metrics/AbcSize
|
85
|
+
private def create_or_update_plugin_files
|
86
|
+
plugins_dir = "#{Dir.pwd.scan(%r{\A/\w*/\w*/}).first}.git_helper/plugins"
|
87
|
+
plugins_url = 'https://api.github.com/repos/emmahsax/git_helper/contents/plugins'
|
88
|
+
header = 'Accept: application/vnd.github.v3.raw'
|
89
|
+
token = git_config_reader.github_token
|
90
|
+
user = git_config_reader.github_user
|
91
|
+
|
92
|
+
Dir.mkdir(plugins_dir) unless File.exist?(plugins_dir)
|
93
|
+
|
94
|
+
all_plugins = JSON.parse(`curl -s -u #{user}:#{token} -H "#{header}" -L "#{plugins_url}"`)
|
95
|
+
|
96
|
+
all_plugins.each do |plugin|
|
97
|
+
plugin_content = `curl -s -u #{user}:#{token} -H "#{header}" -L "#{plugins_url}/#{plugin['name']}"`
|
98
|
+
File.open("#{plugins_dir}/#{plugin['name']}", 'w') { |file| file.puts plugin_content }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
# rubocop:enable Metrics/MethodLength
|
102
|
+
# rubocop:enable Metrics/AbcSize
|
103
|
+
|
104
|
+
private def config_file
|
105
|
+
git_config_reader.git_config_file_path
|
106
|
+
end
|
107
|
+
|
108
|
+
private def git_config_reader
|
109
|
+
@git_config_reader ||= GitHelper::GitConfigReader.new
|
110
|
+
end
|
111
|
+
|
112
|
+
private def highline
|
113
|
+
@highline ||= HighlineWrapper.new
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/git_helper/version.rb
CHANGED
@@ -1,30 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'git_helper'
|
3
5
|
|
4
6
|
describe GitHelper::ChangeRemote do
|
5
7
|
let(:remote1) { "git@github.com:#{old_owner}/#{project}.git" }
|
6
8
|
let(:project) { Faker::Lorem.word }
|
7
|
-
let(:
|
9
|
+
let(:highline_wrapper) { double(:highline_wrapper, ask_yes_no: true) }
|
8
10
|
let(:old_owner) { Faker::Internet.username }
|
9
11
|
let(:new_owner) { Faker::Internet.username }
|
10
|
-
let(:directory_entries) { [
|
12
|
+
let(:directory_entries) { ['.', '..', project, Faker::Lorem.word, Faker::Lorem.word] }
|
11
13
|
|
12
14
|
let(:local_code) do
|
13
15
|
double(:local_code,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
)
|
16
|
+
remotes: [remote1],
|
17
|
+
remote_name: Faker::Lorem.word,
|
18
|
+
ssh_remote?: true,
|
19
|
+
https_remote?: false,
|
20
|
+
remote_project: project,
|
21
|
+
remote_source: 'github.com',
|
22
|
+
change_remote: true)
|
22
23
|
end
|
23
24
|
|
24
25
|
subject { GitHelper::ChangeRemote.new(old_owner, new_owner) }
|
25
26
|
|
26
27
|
before do
|
27
|
-
allow(
|
28
|
+
allow(HighlineWrapper).to receive(:new).and_return(highline_wrapper)
|
28
29
|
allow(GitHelper::LocalCode).to receive(:new).and_return(local_code)
|
29
30
|
allow(subject).to receive(:puts)
|
30
31
|
end
|
@@ -73,7 +74,7 @@ describe GitHelper::ChangeRemote do
|
|
73
74
|
end
|
74
75
|
|
75
76
|
context 'when the user says not to process the directory' do
|
76
|
-
let(:
|
77
|
+
let(:highline_wrapper) { double(:highline_wrapper, ask_yes_no: false) }
|
77
78
|
|
78
79
|
it 'should not call to process the directory' do
|
79
80
|
expect(subject).not_to receive(:process_git_repository)
|
@@ -138,14 +139,13 @@ describe GitHelper::ChangeRemote do
|
|
138
139
|
context 'https remote' do
|
139
140
|
let(:local_code) do
|
140
141
|
double(:local_code,
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
)
|
142
|
+
remotes: [remote1],
|
143
|
+
remote_name: Faker::Lorem.word,
|
144
|
+
ssh_remote?: false,
|
145
|
+
https_remote?: false,
|
146
|
+
remote_project: project,
|
147
|
+
remote_source: 'github.com',
|
148
|
+
change_remote: true)
|
149
149
|
end
|
150
150
|
|
151
151
|
it 'should ask if the remote is SSH' do
|
@@ -167,10 +167,10 @@ describe GitHelper::ChangeRemote do
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
describe '#
|
171
|
-
it 'should create a new
|
172
|
-
expect(
|
173
|
-
subject.send(:
|
170
|
+
describe '#highline' do
|
171
|
+
it 'should create a new highline_wrapper instance' do
|
172
|
+
expect(HighlineWrapper).to receive(:new)
|
173
|
+
subject.send(:highline)
|
174
174
|
end
|
175
175
|
end
|
176
176
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'git_helper'
|
3
5
|
|
4
6
|
describe GitHelper::CodeRequest do
|
5
|
-
let(:
|
7
|
+
let(:highline_wrapper) { double(:highline_wrapper) }
|
6
8
|
let(:local_code) { double(:local_code, project_name: Faker::Lorem.word, branch: Faker::Lorem.word) }
|
7
9
|
let(:process_project) { double(:process_project, create: :created, merge: :merged) }
|
8
10
|
let(:base_branch) { Faker::Lorem.word }
|
@@ -12,7 +14,7 @@ describe GitHelper::CodeRequest do
|
|
12
14
|
|
13
15
|
before do
|
14
16
|
allow(GitHelper::LocalCode).to receive(:new).and_return(local_code)
|
15
|
-
allow(
|
17
|
+
allow(HighlineWrapper).to receive(:new).and_return(highline_wrapper)
|
16
18
|
allow(subject).to receive(:puts)
|
17
19
|
end
|
18
20
|
|
@@ -101,19 +103,19 @@ describe GitHelper::CodeRequest do
|
|
101
103
|
|
102
104
|
describe '#ask_for_clarification' do
|
103
105
|
it 'should ask the CLI' do
|
104
|
-
expect(
|
106
|
+
expect(highline_wrapper).to receive(:ask).and_return('github')
|
105
107
|
subject.send(:ask_for_clarification)
|
106
108
|
end
|
107
109
|
|
108
110
|
context 'when response is github' do
|
109
111
|
it 'should return github_pull_request' do
|
110
|
-
allow(
|
112
|
+
allow(highline_wrapper).to receive(:ask).and_return('github')
|
111
113
|
expect(subject).to receive(:github_pull_request)
|
112
114
|
subject.send(:ask_for_clarification)
|
113
115
|
end
|
114
116
|
|
115
117
|
it 'should return github_pull_request' do
|
116
|
-
allow(
|
118
|
+
allow(highline_wrapper).to receive(:ask).and_return('Github')
|
117
119
|
expect(subject).to receive(:github_pull_request)
|
118
120
|
subject.send(:ask_for_clarification)
|
119
121
|
end
|
@@ -121,21 +123,22 @@ describe GitHelper::CodeRequest do
|
|
121
123
|
|
122
124
|
context 'when response is gitlab' do
|
123
125
|
it 'should return gitlab_merge_request' do
|
124
|
-
allow(
|
126
|
+
allow(highline_wrapper).to receive(:ask).and_return('gitlab')
|
125
127
|
expect(subject).to receive(:gitlab_merge_request)
|
126
128
|
subject.send(:ask_for_clarification)
|
127
129
|
end
|
128
130
|
|
129
131
|
it 'should return gitlab_merge_request' do
|
130
|
-
allow(
|
132
|
+
allow(highline_wrapper).to receive(:ask).and_return('Gitlab')
|
131
133
|
expect(subject).to receive(:gitlab_merge_request)
|
132
134
|
subject.send(:ask_for_clarification)
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
138
|
+
# Unfortunately this test sometimes fails... just rerun the tests if it does
|
136
139
|
context 'when response is neither' do
|
137
140
|
it 'should raise an error' do
|
138
|
-
allow(
|
141
|
+
allow(highline_wrapper).to receive(:ask).and_return(Faker::Lorem.word)
|
139
142
|
expect(subject).to receive(:exit)
|
140
143
|
subject.send(:ask_for_clarification)
|
141
144
|
end
|
@@ -173,23 +176,23 @@ describe GitHelper::CodeRequest do
|
|
173
176
|
describe '#base_branch' do
|
174
177
|
it 'should call the default branch' do
|
175
178
|
expect(subject).to receive(:default_branch)
|
176
|
-
allow(
|
177
|
-
allow(
|
179
|
+
allow(highline_wrapper).to receive(:ask_yes_no).at_least(:once)
|
180
|
+
allow(highline_wrapper).to receive(:ask).at_least(:once).and_return(base_branch)
|
178
181
|
subject.send(:base_branch)
|
179
182
|
end
|
180
183
|
|
181
184
|
it 'should ask the CLI to ask the user' do
|
182
185
|
allow(subject).to receive(:default_branch)
|
183
|
-
expect(
|
184
|
-
allow(
|
186
|
+
expect(highline_wrapper).to receive(:ask_yes_no).at_least(:once)
|
187
|
+
allow(highline_wrapper).to receive(:ask).at_least(:once).and_return(base_branch)
|
185
188
|
subject.send(:base_branch)
|
186
189
|
end
|
187
190
|
|
188
191
|
context 'if the user says no' do
|
189
192
|
it 'definitely asks for the users base branch' do
|
190
193
|
allow(subject).to receive(:default_branch)
|
191
|
-
expect(
|
192
|
-
expect(
|
194
|
+
expect(highline_wrapper).to receive(:ask_yes_no).at_least(:once).and_return(false)
|
195
|
+
expect(highline_wrapper).to receive(:ask).at_least(:once).and_return(base_branch)
|
193
196
|
subject.send(:base_branch)
|
194
197
|
end
|
195
198
|
end
|
@@ -197,8 +200,8 @@ describe GitHelper::CodeRequest do
|
|
197
200
|
context 'if the user says yes' do
|
198
201
|
it 'does not ask for the users base branch' do
|
199
202
|
allow(subject).to receive(:default_branch)
|
200
|
-
expect(
|
201
|
-
expect(
|
203
|
+
expect(highline_wrapper).to receive(:ask_yes_no).at_least(:once).and_return(true)
|
204
|
+
expect(highline_wrapper).not_to receive(:base_branch)
|
202
205
|
subject.send(:base_branch)
|
203
206
|
end
|
204
207
|
end
|
@@ -215,23 +218,23 @@ describe GitHelper::CodeRequest do
|
|
215
218
|
describe '#new_code_request_title' do
|
216
219
|
it 'should call autogenerated title method' do
|
217
220
|
expect(subject).to receive(:autogenerated_title)
|
218
|
-
allow(
|
219
|
-
allow(
|
221
|
+
allow(highline_wrapper).to receive(:ask_yes_no).at_least(:once)
|
222
|
+
allow(highline_wrapper).to receive(:ask).at_least(:once).and_return(title)
|
220
223
|
subject.send(:new_code_request_title)
|
221
224
|
end
|
222
225
|
|
223
226
|
it 'should ask the CLI to ask the user' do
|
224
227
|
allow(subject).to receive(:autogenerated_title).and_return(Faker::Lorem.sentence)
|
225
|
-
expect(
|
226
|
-
allow(
|
228
|
+
expect(highline_wrapper).to receive(:ask_yes_no).at_least(:once)
|
229
|
+
allow(highline_wrapper).to receive(:ask).at_least(:once).and_return(title)
|
227
230
|
subject.send(:new_code_request_title)
|
228
231
|
end
|
229
232
|
|
230
233
|
context 'if the user says no' do
|
231
234
|
it 'definitely asks for the users title' do
|
232
235
|
allow(subject).to receive(:autogenerated_title).and_return(Faker::Lorem.sentence)
|
233
|
-
expect(
|
234
|
-
expect(
|
236
|
+
expect(highline_wrapper).to receive(:ask_yes_no).at_least(:once).and_return(false)
|
237
|
+
expect(highline_wrapper).to receive(:ask).at_least(:once).and_return(title)
|
235
238
|
subject.send(:new_code_request_title)
|
236
239
|
end
|
237
240
|
end
|
@@ -239,8 +242,8 @@ describe GitHelper::CodeRequest do
|
|
239
242
|
context 'if the user says yes to original title' do
|
240
243
|
it 'does not ask for the users chosen title' do
|
241
244
|
allow(subject).to receive(:autogenerated_title).and_return(Faker::Lorem.sentence)
|
242
|
-
expect(
|
243
|
-
expect(
|
245
|
+
expect(highline_wrapper).to receive(:ask_yes_no).at_least(:once).and_return(true)
|
246
|
+
expect(highline_wrapper).not_to receive(:ask)
|
244
247
|
subject.send(:new_code_request_title)
|
245
248
|
end
|
246
249
|
end
|
@@ -253,10 +256,10 @@ describe GitHelper::CodeRequest do
|
|
253
256
|
end
|
254
257
|
end
|
255
258
|
|
256
|
-
describe '#
|
257
|
-
it 'should
|
258
|
-
expect(
|
259
|
-
subject.send(:
|
259
|
+
describe '#highline' do
|
260
|
+
it 'should create a highline_wrapper client' do
|
261
|
+
expect(HighlineWrapper).to receive(:new).and_return(highline_wrapper)
|
262
|
+
subject.send(:highline)
|
260
263
|
end
|
261
264
|
end
|
262
265
|
end
|
@@ -1,18 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'git_helper'
|
3
5
|
|
4
6
|
describe GitHelper::GitConfigReader do
|
7
|
+
let(:github_user) { Faker::Internet.username }
|
5
8
|
let(:github_token) { Faker::Internet.password(max_length: 10) }
|
9
|
+
let(:gitlab_user) { Faker::Internet.username }
|
6
10
|
let(:gitlab_token) { Faker::Internet.password(max_length: 10) }
|
7
11
|
|
8
|
-
let(:config_file)
|
12
|
+
let(:config_file) do
|
9
13
|
{
|
10
|
-
github_user:
|
14
|
+
github_user: github_user,
|
11
15
|
github_token: github_token,
|
12
|
-
gitlab_user:
|
16
|
+
gitlab_user: gitlab_user,
|
13
17
|
gitlab_token: gitlab_token
|
14
18
|
}
|
15
|
-
|
19
|
+
end
|
16
20
|
|
17
21
|
subject { GitHelper::GitConfigReader.new }
|
18
22
|
|
@@ -40,6 +44,30 @@ describe GitHelper::GitConfigReader do
|
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
47
|
+
describe '#github_user' do
|
48
|
+
it 'should locate the github_user' do
|
49
|
+
expect(subject).to receive(:config_file).and_return(config_file)
|
50
|
+
expect(subject.github_user).to eq(github_user)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should call the config file' do
|
54
|
+
expect(subject).to receive(:config_file).and_return(config_file)
|
55
|
+
subject.github_user
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#gitlab_user' do
|
60
|
+
it 'should locate the gitlab_user' do
|
61
|
+
expect(subject).to receive(:config_file).and_return(config_file)
|
62
|
+
expect(subject.gitlab_user).to eq(gitlab_user)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should call the config file' do
|
66
|
+
expect(subject).to receive(:config_file).and_return(config_file)
|
67
|
+
subject.gitlab_user
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
43
71
|
describe '#config_file' do
|
44
72
|
it 'should yaml load the file path' do
|
45
73
|
expect(YAML).to receive(:load_file)
|