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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +134 -0
  4. data/Guardfile +3 -1
  5. data/README.md +10 -5
  6. data/Rakefile +2 -0
  7. data/bin/git-helper +24 -12
  8. data/lib/git_helper.rb +6 -2
  9. data/lib/git_helper/change_remote.rb +15 -6
  10. data/lib/git_helper/checkout_default.rb +2 -0
  11. data/lib/git_helper/clean_branches.rb +2 -0
  12. data/lib/git_helper/code_request.rb +33 -19
  13. data/lib/git_helper/empty_commit.rb +2 -0
  14. data/lib/git_helper/forget_local_commits.rb +2 -0
  15. data/lib/git_helper/git_config_reader.rb +12 -6
  16. data/lib/git_helper/gitlab_client.rb +2 -0
  17. data/lib/git_helper/local_code.rb +18 -8
  18. data/lib/git_helper/merge_request.rb +90 -70
  19. data/lib/git_helper/new_branch.rb +4 -2
  20. data/lib/git_helper/octokit_client.rb +2 -0
  21. data/lib/git_helper/pull_request.rb +97 -66
  22. data/lib/git_helper/setup.rb +116 -0
  23. data/lib/git_helper/version.rb +3 -1
  24. data/spec/git_helper/change_remote_spec.rb +24 -24
  25. data/spec/git_helper/checkout_default_spec.rb +2 -0
  26. data/spec/git_helper/clean_branches_spec.rb +2 -0
  27. data/spec/git_helper/code_request_spec.rb +31 -28
  28. data/spec/git_helper/empty_commit_spec.rb +2 -0
  29. data/spec/git_helper/forget_local_commits_spec.rb +2 -0
  30. data/spec/git_helper/git_config_reader_spec.rb +32 -4
  31. data/spec/git_helper/gitlab_client_spec.rb +2 -0
  32. data/spec/git_helper/local_code_spec.rb +2 -0
  33. data/spec/git_helper/merge_request_spec.rb +24 -23
  34. data/spec/git_helper/new_branch_spec.rb +10 -8
  35. data/spec/git_helper/octokit_client_spec.rb +2 -0
  36. data/spec/git_helper/pull_request_spec.rb +20 -18
  37. data/spec/git_helper/setup_spec.rb +183 -0
  38. data/spec/spec_helper.rb +4 -1
  39. metadata +38 -9
  40. data/lib/git_helper/highline_cli.rb +0 -33
  41. 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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GitHelper
2
- VERSION = '3.2.2'
4
+ VERSION = '3.3.4'
3
5
  end
@@ -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(:cli) { double(:highline_cli, ask_yes_no: true) }
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) { [ '.', '..', project, Faker::Lorem.word, Faker::Lorem.word ] }
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
- remotes: [remote1],
15
- remote_name: Faker::Lorem.word,
16
- ssh_remote?: true,
17
- https_remote?: false,
18
- remote_project: project,
19
- remote_source: 'github.com',
20
- change_remote: true
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(GitHelper::HighlineCli).to receive(:new).and_return(cli)
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(:cli) { double(:highline_cli, ask_yes_no: false) }
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
- remotes: [remote1],
142
- remote_name: Faker::Lorem.word,
143
- ssh_remote?: false,
144
- https_remote?: false,
145
- remote_project: project,
146
- remote_source: 'github.com',
147
- change_remote: true
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 '#cli' do
171
- it 'should create a new highline CLI instance' do
172
- expect(GitHelper::HighlineCli).to receive(:new)
173
- subject.send(:cli)
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'git_helper'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'git_helper'
3
5
 
@@ -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(:highline_cli) { double(:highline_cli) }
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(GitHelper::HighlineCli).to receive(:new).and_return(highline_cli)
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(highline_cli).to receive(:ask).and_return('github')
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(highline_cli).to receive(:ask).and_return('github')
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(highline_cli).to receive(:ask).and_return('Github')
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(highline_cli).to receive(:ask).and_return('gitlab')
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(highline_cli).to receive(:ask).and_return('Gitlab')
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(highline_cli).to receive(:ask).and_return(Faker::Lorem.word)
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(highline_cli).to receive(:ask_yes_no).at_least(:once)
177
- allow(highline_cli).to receive(:ask).at_least(:once).and_return(base_branch)
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(highline_cli).to receive(:ask_yes_no).at_least(:once)
184
- allow(highline_cli).to receive(:ask).at_least(:once).and_return(base_branch)
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(highline_cli).to receive(:ask_yes_no).at_least(:once).and_return(false)
192
- expect(highline_cli).to receive(:ask).at_least(:once).and_return(base_branch)
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(highline_cli).to receive(:ask_yes_no).at_least(:once).and_return(true)
201
- expect(highline_cli).not_to receive(:base_branch)
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(highline_cli).to receive(:ask_yes_no).at_least(:once)
219
- allow(highline_cli).to receive(:ask).at_least(:once).and_return(title)
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(highline_cli).to receive(:ask_yes_no).at_least(:once)
226
- allow(highline_cli).to receive(:ask).at_least(:once).and_return(title)
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(highline_cli).to receive(:ask_yes_no).at_least(:once).and_return(false)
234
- expect(highline_cli).to receive(:ask).at_least(:once).and_return(title)
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(highline_cli).to receive(:ask_yes_no).at_least(:once).and_return(true)
243
- expect(highline_cli).not_to receive(:ask)
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 '#cli' do
257
- it 'should call the octokit client' do
258
- expect(GitHelper::HighlineCli).to receive(:new).and_return(highline_cli)
259
- subject.send(:cli)
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'git_helper'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'git_helper'
3
5
 
@@ -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: Faker::Internet.username,
14
+ github_user: github_user,
11
15
  github_token: github_token,
12
- gitlab_user: Faker::Internet.username,
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)