git_helper 3.2.2 → 3.3.4

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 (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)