git_helper 1.2.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +17 -13
  3. data/README.md +27 -33
  4. data/Rakefile +1 -37
  5. data/bin/git-helper +10 -28
  6. data/lib/git_helper.rb +3 -5
  7. data/lib/git_helper/change_remote.rb +53 -40
  8. data/lib/git_helper/checkout_default.rb +1 -1
  9. data/lib/git_helper/clean_branches.rb +1 -4
  10. data/lib/git_helper/code_request.rb +95 -0
  11. data/lib/git_helper/empty_commit.rb +1 -1
  12. data/lib/git_helper/forget_local_commits.rb +7 -0
  13. data/lib/git_helper/gitlab_client.rb +0 -1
  14. data/lib/git_helper/highline_cli.rb +72 -6
  15. data/lib/git_helper/local_code.rb +124 -0
  16. data/lib/git_helper/merge_request.rb +57 -126
  17. data/lib/git_helper/new_branch.rb +2 -11
  18. data/lib/git_helper/octokit_client.rb +0 -1
  19. data/lib/git_helper/pull_request.rb +45 -110
  20. data/lib/git_helper/version.rb +1 -1
  21. data/spec/git_helper/change_remote_spec.rb +173 -0
  22. data/spec/git_helper/checkout_default_spec.rb +19 -0
  23. data/spec/git_helper/clean_branches_spec.rb +19 -0
  24. data/spec/git_helper/code_request_spec.rb +259 -0
  25. data/spec/git_helper/empty_commit_spec.rb +19 -0
  26. data/spec/git_helper/forget_local_commits_spec.rb +19 -0
  27. data/spec/git_helper/git_config_reader_spec.rb +60 -0
  28. data/spec/git_helper/gitlab_client_spec.rb +26 -0
  29. data/spec/git_helper/highline_cli_spec.rb +215 -0
  30. data/spec/git_helper/local_code_spec.rb +231 -0
  31. data/spec/git_helper/merge_request_spec.rb +234 -0
  32. data/spec/git_helper/new_branch_spec.rb +44 -0
  33. data/spec/git_helper/octokit_client_spec.rb +26 -0
  34. data/spec/git_helper/pull_request_spec.rb +246 -0
  35. data/spec/spec_helper.rb +0 -7
  36. metadata +41 -24
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+ require 'git_helper'
3
+
4
+ describe GitHelper::LocalCode do
5
+ let(:response) { double(:response, readline: true, to_i: 5) }
6
+ let(:local_codeent) { double(:local_code, ask: response) }
7
+ let(:ssh_remote) { 'origin\tgit@github.com:emmasax4/git_helper.git (fetch)' }
8
+ let(:https_remote) { 'origin\thttps://github.com/emmasax4/git_helper.git (fetch)' }
9
+ let(:github_remotes) { ['origin\tgit@github.com:emmasax4/git_helper.git (fetch)', 'origin\thttps://github.com/emmasax4/git_helper.git (fetch)' ] }
10
+ let(:gitlab_remotes) { ['origin\tgit@gitlab.com:emmasax4/git_helper.git (fetch)', 'origin\thttps://gitlab.com/emmasax4/git_helper.git (fetch)' ] }
11
+
12
+
13
+ subject { GitHelper::LocalCode.new }
14
+
15
+ before do
16
+ allow(subject).to receive(:system).and_return(nil)
17
+ end
18
+
19
+ describe '#checkout_default' do
20
+ it 'should make a system call' do
21
+ expect(subject).to receive(:system)
22
+ subject.checkout_default
23
+ end
24
+ end
25
+
26
+ describe '#forget_local_commits' do
27
+ it 'should make a system call' do
28
+ expect(subject).to receive(:system).exactly(2).times
29
+ subject.forget_local_commits
30
+ end
31
+
32
+ it 'should return nil' do
33
+ expect(subject.forget_local_commits).to eq(nil)
34
+ end
35
+ end
36
+
37
+ describe '#empty_commit' do
38
+ it 'should make a system call' do
39
+ expect(subject).to receive(:system)
40
+ subject.empty_commit
41
+ end
42
+ end
43
+
44
+ describe '#clean_branches' do
45
+ it 'should make a system call' do
46
+ expect(subject).to receive(:system).exactly(4).times
47
+ subject.clean_branches
48
+ end
49
+ end
50
+
51
+ describe '#new_branch' do
52
+ it 'should make a system call' do
53
+ expect(subject).to receive(:system).exactly(4).times
54
+ subject.new_branch('branch_name')
55
+ end
56
+ end
57
+
58
+ describe '#change_remote' do
59
+ it 'should return a string' do
60
+ expect(subject.change_remote('name', 'url')).to be_a(String)
61
+ end
62
+ end
63
+
64
+ describe '#remotes' do
65
+ it 'should return an array of strings' do
66
+ expect(subject.remotes).to be_a(Array)
67
+ expect(subject.remotes.first).to be_a(String)
68
+ end
69
+ end
70
+
71
+ describe '#remote_name' do
72
+ it 'should be a string' do
73
+ expect(subject.remote_name(ssh_remote)).to be_a(String)
74
+ end
75
+ end
76
+
77
+ describe '#ssh_remote' do
78
+ it 'should come out true if ssh' do
79
+ expect(subject.ssh_remote?(ssh_remote)).to eq(true)
80
+ end
81
+
82
+ it 'should come out false if https' do
83
+ expect(subject.ssh_remote?(https_remote)).to eq(false)
84
+ end
85
+ end
86
+
87
+ describe '#https_remote' do
88
+ it 'should come out false if ssh' do
89
+ expect(subject.https_remote?(ssh_remote)).to eq(false)
90
+ end
91
+
92
+ it 'should come out true if https' do
93
+ expect(subject.https_remote?(https_remote)).to eq(true)
94
+ end
95
+ end
96
+
97
+ describe '#remote_project' do
98
+ it 'should return just the plain project if ssh' do
99
+ expect(subject.remote_project(ssh_remote)).to eq('git_helper')
100
+ end
101
+
102
+ it 'should return just the plain project if https' do
103
+ expect(subject.remote_project(https_remote)).to eq('git_helper')
104
+ end
105
+ end
106
+
107
+ describe '#remote_source' do
108
+ it 'should return just the plain project if ssh' do
109
+ expect(subject.remote_source(ssh_remote)).to eq('github.com')
110
+ end
111
+
112
+ it 'should return just the plain project if https' do
113
+ expect(subject.remote_source(https_remote)).to eq('github.com')
114
+ end
115
+ end
116
+
117
+ describe '#github_repo' do
118
+ it 'should return true if github' do
119
+ allow(subject).to receive(:remotes).and_return(github_remotes)
120
+ expect(subject.github_repo?).to eq(true)
121
+ end
122
+
123
+ it 'should return false if gitlab' do
124
+ allow(subject).to receive(:remotes).and_return(gitlab_remotes)
125
+ expect(subject.github_repo?).to eq(false)
126
+ end
127
+ end
128
+
129
+ describe '#gitlab_project' do
130
+ it 'should return true if gitlab' do
131
+ allow(subject).to receive(:remotes).and_return(gitlab_remotes)
132
+ expect(subject.gitlab_project?).to eq(true)
133
+ end
134
+
135
+ it 'should return false if github' do
136
+ allow(subject).to receive(:remotes).and_return(github_remotes)
137
+ expect(subject.gitlab_project?).to eq(false)
138
+ end
139
+ end
140
+
141
+ describe '#project_name' do
142
+ it 'should return a string' do
143
+ expect(subject.project_name).to be_a(String)
144
+ end
145
+
146
+ it 'should equal this project name' do
147
+ allow_any_instance_of(String).to receive(:scan).and_return([['emmasax4/git_helper']])
148
+ expect(subject.project_name).to eq('emmasax4/git_helper')
149
+ end
150
+ end
151
+
152
+ describe '#branch' do
153
+ it 'should return a string' do
154
+ expect(subject.branch).to be_a(String)
155
+ end
156
+ end
157
+
158
+ describe '#default_branch' do
159
+ it 'should return a string' do
160
+ expect(subject.default_branch).to be_a(String)
161
+ end
162
+ end
163
+
164
+ describe '#template_options' do
165
+ let(:template_identifiers) do
166
+ {
167
+ nested_directory_name: 'PULL_REQUEST_TEMPLATE',
168
+ non_nested_file_name: 'pull_request_template'
169
+ }
170
+ end
171
+
172
+ it 'should return an array' do
173
+ expect(subject.template_options(template_identifiers)).to be_a(Array)
174
+ end
175
+
176
+ it 'should call Dir.glob and File.join' do
177
+ expect(Dir).to receive(:glob).and_return(['.github/pull_request_template.md']).at_least(:once)
178
+ expect(File).to receive(:join).at_least(:once)
179
+ subject.template_options(template_identifiers)
180
+ end
181
+ end
182
+
183
+ describe '#read_template' do
184
+ it 'should call File.open' do
185
+ expect(File).to receive(:open).and_return(double(read: true))
186
+ subject.read_template('.gitignore')
187
+ end
188
+ end
189
+
190
+ describe '#generate_title' do
191
+ it 'should return a title based on the branch' do
192
+ branch = 'jira-123-test-branch'
193
+ expect(subject.generate_title(branch)).to eq('JIRA-123 Test branch')
194
+ end
195
+
196
+ it 'should return a title based on the branch' do
197
+ branch = 'jira_123_test_branch'
198
+ expect(subject.generate_title(branch)).to eq('JIRA-123 Test branch')
199
+ end
200
+
201
+ it 'should return a title based on the branch' do
202
+ branch = 'jira-123_test_branch'
203
+ expect(subject.generate_title(branch)).to eq('JIRA-123 Test branch')
204
+ end
205
+
206
+ it 'should return a title based on the branch' do
207
+ branch = 'test_branch'
208
+ expect(subject.generate_title(branch)).to eq('Test branch')
209
+ end
210
+
211
+ it 'should return a title based on the branch' do
212
+ branch = 'test-branch'
213
+ expect(subject.generate_title(branch)).to eq('Test branch')
214
+ end
215
+
216
+ it 'should return a title based on the branch' do
217
+ branch = 'test'
218
+ expect(subject.generate_title(branch)).to eq('Test')
219
+ end
220
+
221
+ it 'should return a title based on the branch' do
222
+ branch = 'some_other_words_in_this_test_branch'
223
+ expect(subject.generate_title(branch)).to eq('Some other words in this test branch')
224
+ end
225
+
226
+ it 'should return a title based on the branch' do
227
+ branch = 'some-other-words-in-this-test-branch'
228
+ expect(subject.generate_title(branch)).to eq('Some other words in this test branch')
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,234 @@
1
+ require 'spec_helper'
2
+ require 'git_helper'
3
+
4
+ describe GitHelper::GitLabMergeRequest do
5
+ let(:local_code) { double(:local_code, read_template: 'template') }
6
+ let(:highline_cli) { double(:highline_cli) }
7
+ let(:gitlab_client_client) { double(:gitlab_client_client, project: :project, merge_request: :merge_request, create_merge_request: :created) }
8
+ let(:gitlab_client) { double(:gitlab_client, client: gitlab_client_client) }
9
+ let(:options) do
10
+ {
11
+ local_project: 'emmasax4/git_helper',
12
+ local_branch: 'main',
13
+ local_code: local_code,
14
+ cli: highline_cli
15
+ }
16
+ end
17
+
18
+ subject { GitHelper::GitLabMergeRequest.new(options) }
19
+
20
+ before do
21
+ allow(GitHelper::GitLabClient).to receive(:new).and_return(gitlab_client)
22
+ end
23
+
24
+ describe '#create' do
25
+ it 'should call the gitlab client to create' do
26
+ allow(subject).to receive(:squash_merge_request).and_return(true)
27
+ allow(subject).to receive(:remove_source_branch).and_return(false)
28
+ allow(subject).to receive(:new_mr_body).and_return('')
29
+ expect(gitlab_client_client).to receive(:create_merge_request)
30
+ subject.create({base_branch: 'base', new_title: 'title'})
31
+ end
32
+
33
+ it 'should call various other methods' do
34
+ expect(subject).to receive(:squash_merge_request).and_return(true)
35
+ expect(subject).to receive(:remove_source_branch).and_return(false)
36
+ expect(subject).to receive(:new_mr_body).and_return('')
37
+ allow(gitlab_client_client).to receive(:create_merge_request)
38
+ subject.create({base_branch: 'base', new_title: 'title'})
39
+ end
40
+
41
+ it 'should catch the raised error if the creation does not work' do
42
+ allow(subject).to receive(:squash_merge_request).and_return(true)
43
+ allow(subject).to receive(:remove_source_branch).and_return(false)
44
+ allow(subject).to receive(:new_mr_body).and_return('')
45
+ allow(gitlab_client_client).to receive(:create_merge_request).and_raise(StandardError)
46
+ expect(subject.create({base_branch: 'base', new_title: 'title'})).to eq(nil)
47
+ end
48
+ end
49
+
50
+ describe '#merge' do
51
+ it 'should call the gitlab client to merge' do
52
+ allow(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title'))
53
+ allow(subject).to receive(:mr_id).and_return(123)
54
+ expect(gitlab_client_client).to receive(:accept_merge_request)
55
+ subject.merge
56
+ end
57
+
58
+ it 'should call various other methods' do
59
+ expect(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title')).at_least(:once)
60
+ expect(subject).to receive(:mr_id).and_return(123).at_least(:once)
61
+ allow(gitlab_client_client).to receive(:accept_merge_request)
62
+ subject.merge
63
+ end
64
+
65
+ it 'should catch the raised error if the merge does not work' do
66
+ allow(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title'))
67
+ allow(subject).to receive(:mr_id).and_return(123)
68
+ allow(gitlab_client_client).to receive(:accept_merge_request).and_raise(StandardError)
69
+ expect(subject.merge).to eq(nil)
70
+ end
71
+
72
+ it 'should try to merge multiple times if the first merge errors' do
73
+ allow(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title'))
74
+ allow(subject).to receive(:mr_id).and_return(123)
75
+ expect(gitlab_client_client).to receive(:accept_merge_request).and_return(double(merge_commit_sha: nil)).exactly(2).times
76
+ expect(subject.merge).to eq(nil)
77
+ end
78
+ end
79
+
80
+ describe '#new_mr_body' do
81
+ it 'should call the local code if the template to apply exists' do
82
+ allow(subject).to receive(:template_name_to_apply).and_return('')
83
+ expect(local_code).to receive(:read_template)
84
+ subject.send(:new_mr_body)
85
+ end
86
+
87
+ it 'should not call the local code if the template is nil' do
88
+ allow(subject).to receive(:template_name_to_apply).and_return(nil)
89
+ expect(local_code).not_to receive(:read_template)
90
+ subject.send(:new_mr_body)
91
+ end
92
+
93
+ it 'should return an empty string if the template is nil' do
94
+ allow(subject).to receive(:template_name_to_apply).and_return(nil)
95
+ expect(subject.send(:new_mr_body)).to eq('')
96
+ end
97
+ end
98
+
99
+ describe '#template_name_to_apply' do
100
+ context 'if MR template options are empty' do
101
+ it 'should return nil' do
102
+ allow(subject).to receive(:mr_template_options).and_return([])
103
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
104
+ end
105
+ end
106
+
107
+ context 'if there is one template option' do
108
+ it 'should call the CLI to ask about a single template' do
109
+ allow(subject).to receive(:mr_template_options).and_return(['template1'])
110
+ expect(highline_cli).to receive(:apply_template?).and_return(true)
111
+ subject.send(:template_name_to_apply)
112
+ end
113
+
114
+ it 'should return the single template if the user says yes' do
115
+ allow(subject).to receive(:mr_template_options).and_return(['template1'])
116
+ allow(highline_cli).to receive(:apply_template?).and_return(true)
117
+ expect(subject.send(:template_name_to_apply)).to eq('template1')
118
+ end
119
+
120
+ it 'should return nil if the user says no' do
121
+ allow(subject).to receive(:mr_template_options).and_return(['template1'])
122
+ allow(highline_cli).to receive(:apply_template?).and_return(false)
123
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
124
+ end
125
+ end
126
+
127
+ context 'if there are multiple template options' do
128
+ it 'should call the CLI to ask which of multiple templates to apply' do
129
+ allow(subject).to receive(:mr_template_options).and_return(['template1', 'template2'])
130
+ expect(highline_cli).to receive(:template_to_apply).and_return('template1')
131
+ subject.send(:template_name_to_apply)
132
+ end
133
+
134
+ it 'should return the answer template if the user says yes' do
135
+ allow(subject).to receive(:mr_template_options).and_return(['template1', 'template2'])
136
+ allow(highline_cli).to receive(:template_to_apply).and_return('template1')
137
+ expect(subject.send(:template_name_to_apply)).to eq('template1')
138
+ end
139
+
140
+ it 'should return nil if the user says no' do
141
+ allow(subject).to receive(:mr_template_options).and_return(['template1', 'template2'])
142
+ allow(highline_cli).to receive(:template_to_apply).and_return('None')
143
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#mr_template_options' do
149
+ it 'should call the local code' do
150
+ expect(local_code).to receive(:template_options)
151
+ subject.send(:mr_template_options)
152
+ end
153
+ end
154
+
155
+ describe '#mr_id' do
156
+ it 'should ask the CLI for the code request ID' do
157
+ expect(highline_cli).to receive(:code_request_id).and_return(123)
158
+ subject.send(:mr_id)
159
+ end
160
+
161
+ it 'should equal an integer' do
162
+ expect(highline_cli).to receive(:code_request_id).and_return(123)
163
+ expect(subject.send(:mr_id)).to eq(123)
164
+ end
165
+ end
166
+
167
+ describe '#squash_merge_request' do
168
+ it 'should ask the CLI for the code request ID' do
169
+ expect(highline_cli).to receive(:squash_merge_request?).and_return(true)
170
+ subject.send(:squash_merge_request)
171
+ end
172
+
173
+ it 'should be a boolean' do
174
+ expect(highline_cli).to receive(:squash_merge_request?).and_return(false)
175
+ expect([true, false]).to include(subject.send(:squash_merge_request))
176
+ end
177
+ end
178
+
179
+ describe '#remove_source_branch' do
180
+ before do
181
+ allow(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: nil))
182
+ end
183
+
184
+ context 'when the existing project has no setting' do
185
+ it 'should ask the CLI for the code request ID' do
186
+ expect(highline_cli).to receive(:remove_source_branch?).and_return(true)
187
+ subject.send(:remove_source_branch)
188
+ end
189
+
190
+ it 'should be a boolean' do
191
+ allow(highline_cli).to receive(:remove_source_branch?).and_return(false)
192
+ expect([true, false]).to include(subject.send(:remove_source_branch))
193
+ end
194
+ end
195
+
196
+ it 'should ask the existing project' do
197
+ expect(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: true))
198
+ subject.send(:remove_source_branch)
199
+ end
200
+
201
+ it "should return the existing project's setting if it exists" do
202
+ allow(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: true))
203
+ expect(subject.send(:remove_source_branch)).to eq(true)
204
+ end
205
+
206
+ it "should return the existing project's setting if it exists" do
207
+ allow(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: false))
208
+ allow(highline_cli).to receive(:remove_source_branch?).and_return(true)
209
+ expect(subject.send(:remove_source_branch)).to eq(true)
210
+ end
211
+ end
212
+
213
+ describe '#existing_project' do
214
+ it 'should call the gitlab client' do
215
+ expect(gitlab_client_client).to receive(:project).and_return(:project)
216
+ subject.send(:existing_project)
217
+ end
218
+ end
219
+
220
+ describe '#existing_mr' do
221
+ it 'should call the gitlab client' do
222
+ allow(highline_cli).to receive(:code_request_id).and_return(123)
223
+ expect(gitlab_client_client).to receive(:merge_request).and_return(:merge_request)
224
+ subject.send(:existing_mr)
225
+ end
226
+ end
227
+
228
+ describe '#gitlab_client' do
229
+ it 'should call the gitlab client' do
230
+ expect(GitHelper::GitLabClient).to receive(:new).and_return(gitlab_client)
231
+ subject.send(:gitlab_client)
232
+ end
233
+ end
234
+ end