modulesync 2.2.0 → 2.3.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +18 -3
  3. data/.github/workflows/release.yml +2 -4
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +14 -8
  6. data/.rubocop_todo.yml +25 -17
  7. data/.simplecov +46 -0
  8. data/CHANGELOG.md +32 -0
  9. data/Gemfile +1 -1
  10. data/bin/msync +17 -1
  11. data/features/cli.feature +12 -6
  12. data/features/execute.feature +51 -0
  13. data/features/hook.feature +5 -8
  14. data/features/push.feature +46 -0
  15. data/features/reset.feature +57 -0
  16. data/features/step_definitions/git_steps.rb +29 -1
  17. data/features/support/env.rb +9 -0
  18. data/features/update/bump_version.feature +8 -12
  19. data/features/update/dot_sync.feature +52 -0
  20. data/features/update/pull_request.feature +180 -0
  21. data/features/update.feature +74 -103
  22. data/lib/modulesync/cli/thor.rb +12 -0
  23. data/lib/modulesync/cli.rb +122 -28
  24. data/lib/modulesync/git_service/base.rb +63 -0
  25. data/lib/modulesync/git_service/factory.rb +28 -0
  26. data/lib/modulesync/{pr → git_service}/github.rb +23 -21
  27. data/lib/modulesync/git_service/gitlab.rb +62 -0
  28. data/lib/modulesync/git_service.rb +96 -0
  29. data/lib/modulesync/hook.rb +11 -13
  30. data/lib/modulesync/renderer.rb +3 -6
  31. data/lib/modulesync/repository.rb +71 -25
  32. data/lib/modulesync/settings.rb +0 -1
  33. data/lib/modulesync/source_code.rb +28 -2
  34. data/lib/modulesync/util.rb +4 -4
  35. data/lib/modulesync.rb +104 -66
  36. data/modulesync.gemspec +7 -4
  37. data/spec/helpers/faker/puppet_module_remote_repo.rb +16 -1
  38. data/spec/spec_helper.rb +1 -23
  39. data/spec/unit/modulesync/git_service/factory_spec.rb +16 -0
  40. data/spec/unit/modulesync/git_service/github_spec.rb +81 -0
  41. data/spec/unit/modulesync/git_service/gitlab_spec.rb +90 -0
  42. data/spec/unit/modulesync/git_service_spec.rb +201 -0
  43. data/spec/unit/modulesync/source_code_spec.rb +22 -0
  44. data/spec/unit/modulesync_spec.rb +0 -12
  45. metadata +74 -12
  46. data/lib/modulesync/pr/gitlab.rb +0 -54
  47. data/spec/unit/modulesync/pr/github_spec.rb +0 -49
  48. data/spec/unit/modulesync/pr/gitlab_spec.rb +0 -81
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ require 'modulesync/git_service/github'
4
+
5
+ describe ModuleSync::GitService::GitHub do
6
+ context '::open_pull_request' do
7
+ before(:each) do
8
+ @client = double()
9
+ allow(Octokit::Client).to receive(:new).and_return(@client)
10
+ @it = ModuleSync::GitService::GitHub.new('test', 'https://api.github.com')
11
+ end
12
+
13
+ let(:args) do
14
+ {
15
+ repo_path: 'test/modulesync',
16
+ namespace: 'test',
17
+ title: 'Test PR is submitted',
18
+ message: 'Hello world',
19
+ source_branch: 'test',
20
+ target_branch: 'master',
21
+ labels: labels,
22
+ noop: false,
23
+ }
24
+ end
25
+
26
+ let(:labels) { [] }
27
+
28
+ it 'submits PR when --pr is set' do
29
+ allow(@client).to receive(:pull_requests)
30
+ .with(args[:repo_path],
31
+ :state => 'open',
32
+ :base => 'master',
33
+ :head => "#{args[:namespace]}:#{args[:source_branch]}"
34
+ ).and_return([])
35
+ expect(@client).to receive(:create_pull_request)
36
+ .with(args[:repo_path],
37
+ 'master',
38
+ args[:source_branch],
39
+ args[:title],
40
+ args[:message]
41
+ ).and_return({"html_url" => "http://example.com/pulls/22"})
42
+ expect { @it.open_pull_request(**args) }.to output(/Submitted PR/).to_stdout
43
+ end
44
+
45
+ it 'skips submitting PR if one has already been issued' do
46
+ pr = {
47
+ "title" => "Test title",
48
+ "html_url" => "https://example.com/pulls/44",
49
+ "number" => "44"
50
+ }
51
+
52
+ expect(@client).to receive(:pull_requests)
53
+ .with(args[:repo_path],
54
+ :state => 'open',
55
+ :base => 'master',
56
+ :head => "#{args[:namespace]}:#{args[:source_branch]}"
57
+ ).and_return([pr])
58
+ expect { @it.open_pull_request(**args) }.to output("Skipped! 1 PRs found for branch 'test'\n").to_stdout
59
+ end
60
+
61
+ context 'when labels are set' do
62
+ let(:labels) { %w{HELLO WORLD} }
63
+
64
+ it 'adds labels to PR' do
65
+ allow(@client).to receive(:create_pull_request).and_return({"html_url" => "http://example.com/pulls/22", "number" => "44"})
66
+ allow(@client).to receive(:pull_requests)
67
+ .with(args[:repo_path],
68
+ :state => 'open',
69
+ :base => 'master',
70
+ :head => "#{args[:namespace]}:#{args[:source_branch]}"
71
+ ).and_return([])
72
+ expect(@client).to receive(:add_labels_to_an_issue)
73
+ .with(args[:repo_path],
74
+ "44",
75
+ ["HELLO", "WORLD"]
76
+ )
77
+ expect { @it.open_pull_request(**args) }.to output(/Attaching the following labels to PR 44: HELLO, WORLD/).to_stdout
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ require 'modulesync/git_service/gitlab'
4
+
5
+ describe ModuleSync::GitService::GitLab do
6
+ context '::open_pull_request' do
7
+ before(:each) do
8
+ @client = double()
9
+ allow(Gitlab::Client).to receive(:new).and_return(@client)
10
+ @it = ModuleSync::GitService::GitLab.new('test', 'https://gitlab.com/api/v4')
11
+ end
12
+
13
+ let(:args) do
14
+ {
15
+ repo_path: 'test/modulesync',
16
+ namespace: 'test',
17
+ title: 'Test MR is submitted',
18
+ message: 'Hello world',
19
+ source_branch: 'test',
20
+ target_branch: 'master',
21
+ labels: labels,
22
+ noop: false,
23
+ }
24
+ end
25
+
26
+ let(:labels) { [] }
27
+
28
+ it 'submits MR when --pr is set' do
29
+ allow(@client).to receive(:merge_requests)
30
+ .with(args[:repo_path],
31
+ :state => 'opened',
32
+ :source_branch => args[:source_branch],
33
+ :target_branch => 'master',
34
+ ).and_return([])
35
+
36
+ expect(@client).to receive(:create_merge_request)
37
+ .with(args[:repo_path],
38
+ args[:title],
39
+ :labels => [],
40
+ :source_branch => args[:source_branch],
41
+ :target_branch => 'master',
42
+ ).and_return({"html_url" => "http://example.com/pulls/22"})
43
+
44
+ expect { @it.open_pull_request(**args) }.to output(/Submitted MR/).to_stdout
45
+ end
46
+
47
+ it 'skips submitting MR if one has already been issued' do
48
+ mr = {
49
+ "title" => "Test title",
50
+ "html_url" => "https://example.com/pulls/44",
51
+ "iid" => "44"
52
+ }
53
+
54
+ expect(@client).to receive(:merge_requests)
55
+ .with(args[:repo_path],
56
+ :state => 'opened',
57
+ :source_branch => args[:source_branch],
58
+ :target_branch => 'master',
59
+ ).and_return([mr])
60
+
61
+ expect { @it.open_pull_request(**args) }.to output("Skipped! 1 MRs found for branch 'test'\n").to_stdout
62
+ end
63
+
64
+ context 'when labels are set' do
65
+ let(:labels) { %w{HELLO WORLD} }
66
+
67
+ it 'adds labels to MR' do
68
+ mr = double()
69
+ allow(mr).to receive(:iid).and_return("42")
70
+
71
+ expect(@client).to receive(:create_merge_request)
72
+ .with(args[:repo_path],
73
+ args[:title],
74
+ :labels => ["HELLO", "WORLD"],
75
+ :source_branch => args[:source_branch],
76
+ :target_branch => 'master',
77
+ ).and_return(mr)
78
+
79
+ allow(@client).to receive(:merge_requests)
80
+ .with(args[:repo_path],
81
+ :state => 'opened',
82
+ :source_branch => args[:source_branch],
83
+ :target_branch => 'master',
84
+ ).and_return([])
85
+
86
+ expect { @it.open_pull_request(**args) }.to output(/Attached the following labels to MR 42: HELLO, WORLD/).to_stdout
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,201 @@
1
+ require 'modulesync'
2
+ require 'modulesync/git_service'
3
+
4
+ describe ModuleSync::GitService do
5
+ before do
6
+ options = ModuleSync.config_defaults.merge({
7
+ git_base: 'file:///tmp/dummy',
8
+ })
9
+ ModuleSync.instance_variable_set '@options', options
10
+ end
11
+
12
+ context 'when guessing the git service configuration' do
13
+ before do
14
+ allow(ENV).to receive(:[])
15
+ .and_return(nil)
16
+ end
17
+
18
+ let(:sourcecode) do
19
+ ModuleSync::SourceCode.new 'puppet-test', sourcecode_options
20
+ end
21
+
22
+ context 'when using a complete git service configuration entry' do
23
+ let(:sourcecode_options) do
24
+ {
25
+ gitlab: {
26
+ base_url: 'https://vcs.example.com/api/v4',
27
+ token: 'secret',
28
+ },
29
+ }
30
+ end
31
+
32
+ it 'build git service arguments from configuration entry' do
33
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
34
+ type: :gitlab,
35
+ endpoint: 'https://vcs.example.com/api/v4',
36
+ token: 'secret',
37
+ })
38
+ end
39
+ end
40
+
41
+ context 'when using a simple git service key entry' do
42
+ let(:sourcecode_options) do
43
+ {
44
+ gitlab: {},
45
+ remote: 'git@git.example.com:namespace/puppet-test',
46
+ }
47
+ end
48
+
49
+ context 'with GITLAB_BASE_URL and GITLAB_TOKEN environment variables sets' do
50
+ it 'build git service arguments from environment variables' do
51
+ allow(ENV).to receive(:[])
52
+ .with('GITLAB_BASE_URL')
53
+ .and_return('https://vcs.example.com/api/v4')
54
+ allow(ENV).to receive(:[])
55
+ .with('GITLAB_TOKEN')
56
+ .and_return('secret')
57
+
58
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
59
+ type: :gitlab,
60
+ endpoint: 'https://vcs.example.com/api/v4',
61
+ token: 'secret',
62
+ })
63
+ end
64
+ end
65
+
66
+ context 'with only GITLAB_TOKEN environment variable sets' do
67
+ it 'guesses the endpoint based on repository remote' do
68
+ allow(ENV).to receive(:[])
69
+ .with('GITLAB_TOKEN')
70
+ .and_return('secret')
71
+
72
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
73
+ type: :gitlab,
74
+ endpoint: 'https://git.example.com/api/v4',
75
+ token: 'secret',
76
+ })
77
+ end
78
+ end
79
+
80
+ context 'without any environment variable sets' do
81
+ it 'returns a nil token' do
82
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
83
+ type: :gitlab,
84
+ endpoint: 'https://git.example.com/api/v4',
85
+ token: nil,
86
+ })
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'without git service configuration entry' do
92
+ context 'with a guessable endpoint based on repository remote' do
93
+ let(:sourcecode_options) do
94
+ {
95
+ remote: 'git@gitlab.example.com:namespace/puppet-test',
96
+ }
97
+ end
98
+
99
+ context 'with a GITLAB_TOKEN environment variable sets' do
100
+ it 'guesses git service configuration' do
101
+ allow(ENV).to receive(:[])
102
+ .with('GITLAB_TOKEN')
103
+ .and_return('secret')
104
+
105
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
106
+ type: :gitlab,
107
+ endpoint: 'https://gitlab.example.com/api/v4',
108
+ token: 'secret',
109
+ })
110
+ end
111
+ end
112
+
113
+ context 'without a GITLAB_TOKEN environment variable sets' do
114
+ it 'returns a nil token' do
115
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
116
+ type: :gitlab,
117
+ endpoint: 'https://gitlab.example.com/api/v4',
118
+ token: nil,
119
+ })
120
+ end
121
+ end
122
+ end
123
+
124
+ context 'with a unguessable endpoint' do
125
+ let(:sourcecode_options) do
126
+ {
127
+ remote: 'git@vcs.example.com:namespace/puppet-test',
128
+ }
129
+ end
130
+
131
+ context 'with GITHUB_TOKEN environments variable sets' do
132
+ it 'guesses git service configuration' do
133
+ allow(ENV).to receive(:[])
134
+ .with('GITHUB_TOKEN')
135
+ .and_return('secret')
136
+
137
+ expect(ModuleSync::GitService.configuration_for(sourcecode: sourcecode)).to eq({
138
+ type: :github,
139
+ endpoint: 'https://vcs.example.com',
140
+ token: 'secret',
141
+ })
142
+ end
143
+ end
144
+
145
+ context 'with GITLAB_TOKEN and GITHUB_TOKEN environments variables sets' do
146
+ it 'raises an error' do
147
+ allow(ENV).to receive(:[])
148
+ .with('GITHUB_TOKEN')
149
+ .and_return('secret')
150
+
151
+ allow(ENV).to receive(:[])
152
+ .with('GITLAB_TOKEN')
153
+ .and_return('secret')
154
+
155
+ expect{ModuleSync::GitService.configuration_for(sourcecode: sourcecode)}
156
+ .to raise_error ModuleSync::Error
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ RSpec.shared_examples 'hostname_extractor' do |url, hostname|
164
+ context "with '#{url}' URL" do
165
+ subject { ModuleSync::GitService::Base.extract_hostname(url) }
166
+ it "should extract #{hostname.nil? ? 'nil' : "'#{hostname}'"} as hostname" do
167
+ expect(subject).to eq(hostname)
168
+ end
169
+ end
170
+ end
171
+
172
+ context '#extract_hostname' do
173
+ [
174
+ %w[ssh://user@host.xz:4444/path/to/repo.git/ host.xz],
175
+ %w[ssh://user@host.xz:/path/to/repo.git/ host.xz],
176
+ %w[ssh://host.xz/path/to/repo.git/ host.xz],
177
+
178
+ %w[git://host.xz/path/to/repo.git/ host.xz],
179
+ %w[git://host.xz/path/to/repo/ host.xz],
180
+ %w[git://host.xz/path/to/repo host.xz],
181
+
182
+ %w[user@host.xz:path/to/repo.git/ host.xz],
183
+ %w[user@host.xz:path/to/repo.git host.xz],
184
+ %w[user@host.xz:path/to/repo host.xz],
185
+ %w[host.xz:path/to/repo.git/ host.xz],
186
+
187
+ %w[https://host.xz:8443/path/to/repo.git/ host.xz],
188
+ %w[https://host.xz/path/to/repo.git/ host.xz],
189
+
190
+ %w[ftp://host.xz/path/to/repo/ host.xz],
191
+
192
+ ['/path/to/repo.git/', nil],
193
+
194
+ ['file:///path/to/repo.git/', nil],
195
+
196
+ ['something-invalid', nil],
197
+ ].each do |url, hostname|
198
+ it_should_behave_like 'hostname_extractor', url, hostname
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe ModuleSync::SourceCode do
4
+ before do
5
+ options = ModuleSync.config_defaults.merge({
6
+ git_base: 'file:///tmp/dummy',
7
+ })
8
+ ModuleSync.instance_variable_set '@options', options
9
+ end
10
+
11
+ subject do
12
+ ModuleSync::SourceCode.new('namespace/name', nil)
13
+ end
14
+
15
+ it 'has a repository namespace sets to "namespace"' do
16
+ expect(subject.repository_namespace).to eq 'namespace'
17
+ end
18
+
19
+ it 'has a repository name sets to "name"' do
20
+ expect(subject.repository_name).to eq 'name'
21
+ end
22
+ end
@@ -11,16 +11,4 @@ describe ModuleSync do
11
11
  ModuleSync.update(options)
12
12
  end
13
13
  end
14
-
15
- context '::pr' do
16
- describe "Raise Error" do
17
- let(:puppet_module) do
18
- ModuleSync::PuppetModule.new 'puppet-test', remote: 'dummy'
19
- end
20
-
21
- it 'raises an error when neither GITHUB_TOKEN nor GITLAB_TOKEN are set for PRs' do
22
- expect { ModuleSync.pr(puppet_module) }.to raise_error(RuntimeError).and output(/No GitHub or GitLab token specified for --pr/).to_stderr
23
- end
24
- end
25
- end
26
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modulesync
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vox Pupuli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-24 00:00:00.000000000 Z
11
+ date: 2022-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aruba
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: cucumber
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: rake
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -78,16 +92,44 @@ dependencies:
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: 0.50.0
95
+ version: '1.2'
82
96
  type: :development
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: 0.50.0
102
+ version: '1.2'
89
103
  - !ruby/object:Gem::Dependency
90
- name: cucumber
104
+ name: rubocop-rake
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop-rspec
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: simplecov
91
133
  requirement: !ruby/object:Gem::Requirement
92
134
  requirements:
93
135
  - - ">="
@@ -191,6 +233,7 @@ files:
191
233
  - ".rspec"
192
234
  - ".rubocop.yml"
193
235
  - ".rubocop_todo.yml"
236
+ - ".simplecov"
194
237
  - CHANGELOG.md
195
238
  - Gemfile
196
239
  - HISTORY.md
@@ -200,19 +243,27 @@ files:
200
243
  - bin/msync
201
244
  - contrib/openstack-commit-msg-hook.sh
202
245
  - features/cli.feature
246
+ - features/execute.feature
203
247
  - features/hook.feature
248
+ - features/push.feature
249
+ - features/reset.feature
204
250
  - features/step_definitions/git_steps.rb
205
251
  - features/support/env.rb
206
252
  - features/update.feature
207
253
  - features/update/bad_context.feature
208
254
  - features/update/bump_version.feature
255
+ - features/update/dot_sync.feature
256
+ - features/update/pull_request.feature
209
257
  - lib/modulesync.rb
210
258
  - lib/modulesync/cli.rb
211
259
  - lib/modulesync/cli/thor.rb
212
260
  - lib/modulesync/constants.rb
261
+ - lib/modulesync/git_service.rb
262
+ - lib/modulesync/git_service/base.rb
263
+ - lib/modulesync/git_service/factory.rb
264
+ - lib/modulesync/git_service/github.rb
265
+ - lib/modulesync/git_service/gitlab.rb
213
266
  - lib/modulesync/hook.rb
214
- - lib/modulesync/pr/github.rb
215
- - lib/modulesync/pr/gitlab.rb
216
267
  - lib/modulesync/puppet_module.rb
217
268
  - lib/modulesync/renderer.rb
218
269
  - lib/modulesync/repository.rb
@@ -224,9 +275,12 @@ files:
224
275
  - spec/helpers/faker.rb
225
276
  - spec/helpers/faker/puppet_module_remote_repo.rb
226
277
  - spec/spec_helper.rb
227
- - spec/unit/modulesync/pr/github_spec.rb
228
- - spec/unit/modulesync/pr/gitlab_spec.rb
278
+ - spec/unit/modulesync/git_service/factory_spec.rb
279
+ - spec/unit/modulesync/git_service/github_spec.rb
280
+ - spec/unit/modulesync/git_service/gitlab_spec.rb
281
+ - spec/unit/modulesync/git_service_spec.rb
229
282
  - spec/unit/modulesync/settings_spec.rb
283
+ - spec/unit/modulesync/source_code_spec.rb
230
284
  - spec/unit/modulesync_spec.rb
231
285
  homepage: https://github.com/voxpupuli/modulesync
232
286
  licenses:
@@ -247,22 +301,30 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
301
  - !ruby/object:Gem::Version
248
302
  version: '0'
249
303
  requirements: []
250
- rubygems_version: 3.2.22
304
+ rubygems_version: 3.3.7
251
305
  signing_key:
252
306
  specification_version: 4
253
307
  summary: Puppet Module Synchronizer
254
308
  test_files:
255
309
  - features/cli.feature
310
+ - features/execute.feature
256
311
  - features/hook.feature
312
+ - features/push.feature
313
+ - features/reset.feature
257
314
  - features/step_definitions/git_steps.rb
258
315
  - features/support/env.rb
259
316
  - features/update.feature
260
317
  - features/update/bad_context.feature
261
318
  - features/update/bump_version.feature
319
+ - features/update/dot_sync.feature
320
+ - features/update/pull_request.feature
262
321
  - spec/helpers/faker.rb
263
322
  - spec/helpers/faker/puppet_module_remote_repo.rb
264
323
  - spec/spec_helper.rb
265
- - spec/unit/modulesync/pr/github_spec.rb
266
- - spec/unit/modulesync/pr/gitlab_spec.rb
324
+ - spec/unit/modulesync/git_service/factory_spec.rb
325
+ - spec/unit/modulesync/git_service/github_spec.rb
326
+ - spec/unit/modulesync/git_service/gitlab_spec.rb
327
+ - spec/unit/modulesync/git_service_spec.rb
267
328
  - spec/unit/modulesync/settings_spec.rb
329
+ - spec/unit/modulesync/source_code_spec.rb
268
330
  - spec/unit/modulesync_spec.rb
@@ -1,54 +0,0 @@
1
- require 'gitlab'
2
- require 'modulesync/util'
3
-
4
- module ModuleSync
5
- module PR
6
- # GitLab creates and manages merge requests on gitlab.com or private GitLab
7
- # installations.
8
- class GitLab
9
- def initialize(token, endpoint)
10
- @api = Gitlab::Client.new(
11
- :endpoint => endpoint,
12
- :private_token => token
13
- )
14
- end
15
-
16
- def manage(namespace, module_name, options)
17
- repo_path = File.join(namespace, module_name)
18
- branch = options[:remote_branch] || options[:branch]
19
- head = "#{namespace}:#{branch}"
20
- target_branch = options[:pr_target_branch] || 'master'
21
-
22
- if options[:noop]
23
- $stdout.puts \
24
- "Using no-op. Would submit MR '#{options[:pr_title]}' to #{repo_path} " \
25
- "- merges #{branch} into #{target_branch}"
26
- return
27
- end
28
-
29
- merge_requests = @api.merge_requests(repo_path,
30
- :state => 'opened',
31
- :source_branch => head,
32
- :target_branch => target_branch)
33
- unless merge_requests.empty?
34
- # Skip creating the MR if it exists already.
35
- $stdout.puts "Skipped! #{merge_requests.length} MRs found for branch #{branch}"
36
- return
37
- end
38
-
39
- mr_labels = ModuleSync::Util.parse_list(options[:pr_labels])
40
- mr = @api.create_merge_request(repo_path,
41
- options[:pr_title],
42
- :source_branch => branch,
43
- :target_branch => target_branch,
44
- :labels => mr_labels)
45
- $stdout.puts \
46
- "Submitted MR '#{options[:pr_title]}' to #{repo_path} " \
47
- "- merges #{branch} into #{target_branch}"
48
-
49
- return if mr_labels.empty?
50
- $stdout.puts "Attached the following labels to MR #{mr.iid}: #{mr_labels.join(', ')}"
51
- end
52
- end
53
- end
54
- end
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
- require 'modulesync/pr/github'
3
-
4
- describe ModuleSync::PR::GitHub do
5
- context '::manage' do
6
- before(:each) do
7
- @git_repo = 'test/modulesync'
8
- @namespace, @repo_name = @git_repo.split('/')
9
- @options = {
10
- :pr => true,
11
- :pr_title => 'Test PR is submitted',
12
- :branch => 'test',
13
- :message => 'Hello world',
14
- :pr_auto_merge => false,
15
- }
16
-
17
- @client = double()
18
- allow(Octokit::Client).to receive(:new).and_return(@client)
19
- @it = ModuleSync::PR::GitHub.new('test', 'https://api.github.com')
20
- end
21
-
22
- it 'submits PR when --pr is set' do
23
- allow(@client).to receive(:pull_requests).with(@git_repo, :state => 'open', :base => 'master', :head => "#{@namespace}:#{@options[:branch]}").and_return([])
24
- expect(@client).to receive(:create_pull_request).with(@git_repo, 'master', @options[:branch], @options[:pr_title], @options[:message]).and_return({"html_url" => "http://example.com/pulls/22"})
25
- expect { @it.manage(@namespace, @repo_name, @options) }.to output(/Submitted PR/).to_stdout
26
- end
27
-
28
- it 'skips submitting PR if one has already been issued' do
29
- pr = {
30
- "title" => "Test title",
31
- "html_url" => "https://example.com/pulls/44",
32
- "number" => "44"
33
- }
34
-
35
- expect(@client).to receive(:pull_requests).with(@git_repo, :state => 'open', :base => 'master', :head => "#{@namespace}:#{@options[:branch]}").and_return([pr])
36
- expect { @it.manage(@namespace, @repo_name, @options) }.to output(/Skipped! 1 PRs found for branch test/).to_stdout
37
- end
38
-
39
- it 'adds labels to PR when --pr-labels is set' do
40
- @options[:pr_labels] = "HELLO,WORLD"
41
-
42
- allow(@client).to receive(:create_pull_request).and_return({"html_url" => "http://example.com/pulls/22", "number" => "44"})
43
- allow(@client).to receive(:pull_requests).with(@git_repo, :state => 'open', :base => 'master', :head => "#{@namespace}:#{@options[:branch]}").and_return([])
44
-
45
- expect(@client).to receive(:add_labels_to_an_issue).with(@git_repo, "44", ["HELLO", "WORLD"])
46
- expect { @it.manage(@namespace, @repo_name, @options) }.to output(/Attaching the following labels to PR 44: HELLO, WORLD/).to_stdout
47
- end
48
- end
49
- end