modulesync 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.travis.yml +8 -5
- data/CHANGELOG.md +8 -0
- data/Gemfile +1 -1
- data/README.md +17 -0
- data/Rakefile +1 -0
- data/features/update.feature +33 -0
- data/lib/modulesync.rb +49 -32
- data/lib/modulesync/cli.rb +1 -0
- data/lib/modulesync/renderer.rb +4 -3
- data/modulesync.gemspec +2 -2
- data/spec/unit/modulesync_spec.rb +55 -0
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 139a0b0b011d17ff31b014560eb02ce6a57e62f2e45ffaa06c9acf778240b047
|
4
|
+
data.tar.gz: f1696a42bcf9cf44719ea8f7c5f5580481672e9c3dd920463f77f2f72d54a82a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22bf21a62e3c6e3c8df65bed7b1356af3dc656ba85ae885338b0f35b501c1217c5159918d2c21fcbe3c92c52d14ab2f561b876004eabec99ecaa81521c875c88
|
7
|
+
data.tar.gz: 751fdcd7d6ee62611f90659e21eb94a103ac6473c98b6907342441675232e1c946dc69ed925dff5e1f708dd4e5f8dca68e039b38600d7c73c9f919dc837a9aee
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -6,10 +6,13 @@ dist: trusty
|
|
6
6
|
script: 'bundle exec rake test'
|
7
7
|
rvm:
|
8
8
|
- 2.0
|
9
|
-
- 2.1
|
10
|
-
- 2.2
|
11
|
-
- 2.3
|
12
|
-
- 2.4
|
9
|
+
- 2.1
|
10
|
+
- 2.2
|
11
|
+
- 2.3
|
12
|
+
- 2.4
|
13
|
+
- 2.5
|
14
|
+
- 2.6
|
15
|
+
- 2.7
|
13
16
|
notifications:
|
14
17
|
email: false
|
15
18
|
deploy:
|
@@ -18,7 +21,7 @@ deploy:
|
|
18
21
|
secure: "Tbf1EbLEobIIox+fftJZADZsfQQ6kl0urcMNetK7NJzFo/negD/WyJIUj3kro/B7buyYADEjTui/JR4o8EPbugfM3ie5vYOd5k3AesSzbdr4BSwGe/cGbGOB7/PZuGfFLkb94/FiCU2mIwibkbh1rHWGlBoPj7ntL0+5ZtdvsM4="
|
19
22
|
gem: modulesync
|
20
23
|
on:
|
21
|
-
rvm: 2.
|
24
|
+
rvm: 2.7
|
22
25
|
tags: true
|
23
26
|
all_branches: true
|
24
27
|
repo: voxpupuli/modulesync
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2020-05-01 - 1.1.0
|
4
|
+
|
5
|
+
This release provides metadata in the ERB template scope which makes it easy to read files from inside the module. A possible application is reading metadata.json and generating CI configs based on that.
|
6
|
+
|
7
|
+
* Add metadata to ERB template scope - [#168](https://github.com/voxpupuli/modulesync/pull/168)
|
8
|
+
* Skip issuing a PR if one already exists for -b option - [#171](https://github.com/voxpupuli/modulesync/pull/171)
|
9
|
+
* Correct the type on the pr-labels option to prevent a deprecation warning - [#173](https://github.com/voxpupuli/modulesync/pull/173)
|
10
|
+
|
3
11
|
## 2019-09-19 - 1.0.0
|
4
12
|
|
5
13
|
This is the first stable release! 🎉
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -389,6 +389,23 @@ As mentioned, files in the moduleroot directory must be ERB templates (they must
|
|
389
389
|
<%= @configs[:puppet_module] %>
|
390
390
|
```
|
391
391
|
|
392
|
+
Alternatively some meta data is passed to the template. This will allow you to add custom Ruby extensions inside the
|
393
|
+
template, reading other files from the module, to make the template system more adaptive.
|
394
|
+
|
395
|
+
```erb
|
396
|
+
module: <%= @metadata[:module_name] %>
|
397
|
+
target: <%= @metadata[:target_file] %>
|
398
|
+
workdir: <%= @metadata[:workdir] %>
|
399
|
+
```
|
400
|
+
|
401
|
+
Will result in something like:
|
402
|
+
|
403
|
+
```
|
404
|
+
module: puppet-test
|
405
|
+
target: modules/github-org/puppet-test/test
|
406
|
+
workdir: modules/github-org/puppet-test
|
407
|
+
```
|
408
|
+
|
392
409
|
The Templates
|
393
410
|
-------------
|
394
411
|
|
data/Rakefile
CHANGED
data/features/update.feature
CHANGED
@@ -922,3 +922,36 @@ Feature: update
|
|
922
922
|
When I run `msync update -m "Update Gemfile"`
|
923
923
|
Then the exit status should be 0
|
924
924
|
Then the output should contain "Using repository's default branch: develop"
|
925
|
+
|
926
|
+
Scenario: Adding a new file from a template using meta data
|
927
|
+
And a file named "config_defaults.yml" with:
|
928
|
+
"""
|
929
|
+
---
|
930
|
+
"""
|
931
|
+
Given a file named "managed_modules.yml" with:
|
932
|
+
"""
|
933
|
+
---
|
934
|
+
- puppet-test
|
935
|
+
"""
|
936
|
+
And a file named "modulesync.yml" with:
|
937
|
+
"""
|
938
|
+
---
|
939
|
+
namespace: maestrodev
|
940
|
+
git_base: https://github.com/
|
941
|
+
"""
|
942
|
+
And a directory named "moduleroot"
|
943
|
+
And a file named "moduleroot/test.erb" with:
|
944
|
+
"""
|
945
|
+
module: <%= @metadata[:module_name] %>
|
946
|
+
target: <%= @metadata[:target_file] %>
|
947
|
+
workdir: <%= @metadata[:workdir] %>
|
948
|
+
"""
|
949
|
+
When I run `msync update --noop`
|
950
|
+
Then the exit status should be 0
|
951
|
+
Given I run `cat modules/maestrodev/puppet-test/test`
|
952
|
+
Then the output should contain:
|
953
|
+
"""
|
954
|
+
module: puppet-test
|
955
|
+
target: modules/maestrodev/puppet-test/test
|
956
|
+
workdir: modules/maestrodev/puppet-test
|
957
|
+
"""
|
data/lib/modulesync.rb
CHANGED
@@ -16,7 +16,7 @@ Octokit.configure do |c|
|
|
16
16
|
c.api_endpoint = ENV.fetch('GITHUB_BASE_URL', 'https://api.github.com')
|
17
17
|
end
|
18
18
|
|
19
|
-
module ModuleSync
|
19
|
+
module ModuleSync # rubocop:disable Metrics/ModuleLength
|
20
20
|
include Constants
|
21
21
|
|
22
22
|
def self.config_defaults
|
@@ -32,8 +32,8 @@ module ModuleSync
|
|
32
32
|
File.join(config_path, MODULE_FILES_DIR, file)
|
33
33
|
end
|
34
34
|
|
35
|
-
def self.module_file(project_root, namespace, puppet_module,
|
36
|
-
File.join(project_root, namespace, puppet_module,
|
35
|
+
def self.module_file(project_root, namespace, puppet_module, *parts)
|
36
|
+
File.join(project_root, namespace, puppet_module, *parts)
|
37
37
|
end
|
38
38
|
|
39
39
|
# List all template files.
|
@@ -46,7 +46,7 @@ module ModuleSync
|
|
46
46
|
.collect { |p| p.chomp('.erb') }
|
47
47
|
.to_a
|
48
48
|
else
|
49
|
-
puts "#{local_template_dir} does not exist." \
|
49
|
+
$stdout.puts "#{local_template_dir} does not exist." \
|
50
50
|
' Check that you are working in your module configs directory or' \
|
51
51
|
' that you have passed in the correct directory with -c.'
|
52
52
|
exit
|
@@ -60,7 +60,7 @@ module ModuleSync
|
|
60
60
|
def self.managed_modules(config_file, filter, negative_filter)
|
61
61
|
managed_modules = Util.parse_config(config_file)
|
62
62
|
if managed_modules.empty?
|
63
|
-
puts "No modules found in #{config_file}." \
|
63
|
+
$stdout.puts "No modules found in #{config_file}." \
|
64
64
|
' Check that you specified the right :configs directory and :managed_modules_conf file.'
|
65
65
|
exit
|
66
66
|
end
|
@@ -89,27 +89,29 @@ module ModuleSync
|
|
89
89
|
namespace = settings.additional_settings[:namespace]
|
90
90
|
module_name = settings.additional_settings[:puppet_module]
|
91
91
|
configs = settings.build_file_configs(filename)
|
92
|
+
target_file = module_file(options[:project_root], namespace, module_name, filename)
|
92
93
|
if configs['delete']
|
93
|
-
Renderer.remove(
|
94
|
+
Renderer.remove(target_file)
|
94
95
|
else
|
95
96
|
templatename = local_file(options[:configs], filename)
|
96
97
|
begin
|
97
98
|
erb = Renderer.build(templatename)
|
98
|
-
template
|
99
|
-
|
99
|
+
# Meta data passed to the template as @metadata[:name]
|
100
|
+
metadata = {
|
101
|
+
:module_name => module_name,
|
102
|
+
:workdir => module_file(options[:project_root], namespace, module_name),
|
103
|
+
:target_file => target_file,
|
104
|
+
}
|
105
|
+
template = Renderer.render(erb, configs, metadata)
|
106
|
+
Renderer.sync(template, target_file)
|
100
107
|
rescue # rubocop:disable Lint/RescueWithoutErrorClass
|
101
|
-
|
108
|
+
$stderr.puts "Error while rendering #{filename}"
|
102
109
|
raise
|
103
110
|
end
|
104
111
|
end
|
105
112
|
end
|
106
113
|
|
107
114
|
def self.manage_module(puppet_module, module_files, module_options, defaults, options)
|
108
|
-
if options[:pr] && !GITHUB_TOKEN
|
109
|
-
STDERR.puts 'Environment variable GITHUB_TOKEN must be set to use --pr!'
|
110
|
-
raise unless options[:skip_broken]
|
111
|
-
end
|
112
|
-
|
113
115
|
namespace, module_name = module_name(puppet_module, options[:namespace])
|
114
116
|
git_repo = File.join(namespace, module_name)
|
115
117
|
unless options[:offline]
|
@@ -125,7 +127,7 @@ module ModuleSync
|
|
125
127
|
:git_base => options[:git_base],
|
126
128
|
:namespace => namespace)
|
127
129
|
settings.unmanaged_files(module_files).each do |filename|
|
128
|
-
puts "Not managing #{filename} in #{module_name}"
|
130
|
+
$stdout.puts "Not managing #{filename} in #{module_name}"
|
129
131
|
end
|
130
132
|
|
131
133
|
files_to_manage = settings.managed_files(module_files)
|
@@ -138,24 +140,39 @@ module ModuleSync
|
|
138
140
|
pushed = Git.update(git_repo, files_to_manage, options)
|
139
141
|
return nil unless pushed && options[:pr]
|
140
142
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
143
|
+
manage_pr(namespace, module_name, options)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.manage_pr(namespace, module_name, options)
|
148
|
+
if options[:pr] && GITHUB_TOKEN.empty?
|
149
|
+
$stderr.puts 'Environment variable GITHUB_TOKEN must be set to use --pr!'
|
150
|
+
raise unless options[:skip_broken]
|
151
|
+
end
|
147
152
|
|
148
|
-
|
149
|
-
|
150
|
-
|
153
|
+
# We only do GitHub PR work if the GITHUB_TOKEN variable is set in the environment.
|
154
|
+
repo_path = File.join(namespace, module_name)
|
155
|
+
github = Octokit::Client.new(:access_token => GITHUB_TOKEN)
|
151
156
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
157
|
+
# Skip creating the PR if it exists already.
|
158
|
+
head = "#{namespace}:#{options[:branch]}"
|
159
|
+
pull_requests = github.pull_requests(repo_path, :state => 'open', :base => 'master', :head => head)
|
160
|
+
if pull_requests.empty?
|
161
|
+
pr = github.create_pull_request(repo_path, 'master', options[:branch], options[:pr_title], options[:message])
|
162
|
+
$stdout.puts "Submitted PR '#{options[:pr_title]}' to #{repo_path} - merges #{options[:branch]} into master"
|
163
|
+
else
|
164
|
+
$stdout.puts "Skipped! #{pull_requests.length} PRs found for branch #{options[:branch]}"
|
158
165
|
end
|
166
|
+
|
167
|
+
# PR labels can either be a list in the YAML file or they can pass in a comma
|
168
|
+
# separated list via the command line argument.
|
169
|
+
pr_labels = Util.parse_list(options[:pr_labels])
|
170
|
+
|
171
|
+
# We only assign labels to the PR if we've discovered a list > 1. The labels MUST
|
172
|
+
# already exist. We DO NOT create missing labels.
|
173
|
+
return if pr_labels.empty?
|
174
|
+
$stdout.puts "Attaching the following labels to PR #{pr['number']}: #{pr_labels.join(', ')}"
|
175
|
+
github.add_labels_to_an_issue(repo_path, pr['number'], pr_labels)
|
159
176
|
end
|
160
177
|
|
161
178
|
def self.update(options)
|
@@ -176,10 +193,10 @@ module ModuleSync
|
|
176
193
|
begin
|
177
194
|
manage_module(puppet_module, module_files, module_options, defaults, options)
|
178
195
|
rescue # rubocop:disable Lint/RescueWithoutErrorClass
|
179
|
-
|
196
|
+
$stderr.puts "Error while updating #{puppet_module}"
|
180
197
|
raise unless options[:skip_broken]
|
181
198
|
errors = true
|
182
|
-
puts "Skipping #{puppet_module} as update process failed"
|
199
|
+
$stdout.puts "Skipping #{puppet_module} as update process failed"
|
183
200
|
end
|
184
201
|
end
|
185
202
|
exit 1 if errors && options[:fail_on_warnings]
|
data/lib/modulesync/cli.rb
CHANGED
@@ -96,6 +96,7 @@ module ModuleSync
|
|
96
96
|
:desc => 'Title of GitHub PR',
|
97
97
|
:default => CLI.defaults[:pr_title] || 'Update to module template files'
|
98
98
|
option :pr_labels,
|
99
|
+
:type => :array,
|
99
100
|
:desc => 'Labels to add to the GitHub PR',
|
100
101
|
:default => CLI.defaults[:pr_labels] || []
|
101
102
|
option :offline,
|
data/lib/modulesync/renderer.rb
CHANGED
@@ -4,8 +4,9 @@ require 'find'
|
|
4
4
|
module ModuleSync
|
5
5
|
module Renderer
|
6
6
|
class ForgeModuleFile
|
7
|
-
def initialize(configs = {})
|
7
|
+
def initialize(configs = {}, metadata = {})
|
8
8
|
@configs = configs
|
9
|
+
@metadata = metadata
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
@@ -26,8 +27,8 @@ module ModuleSync
|
|
26
27
|
File.delete(file) if File.exist?(file)
|
27
28
|
end
|
28
29
|
|
29
|
-
def self.render(_template, configs = {})
|
30
|
-
ForgeModuleFile.new(configs).render
|
30
|
+
def self.render(_template, configs = {}, metadata = {})
|
31
|
+
ForgeModuleFile.new(configs, metadata).render
|
31
32
|
end
|
32
33
|
|
33
34
|
def self.sync(template, target_name)
|
data/modulesync.gemspec
CHANGED
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = 'modulesync'
|
6
|
-
spec.version = '1.
|
6
|
+
spec.version = '1.1.0'
|
7
7
|
spec.authors = ['Vox Pupuli']
|
8
8
|
spec.email = ['voxpupuli@groups.io']
|
9
9
|
spec.summary = 'Puppet Module Synchronizer'
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
|
-
spec.add_development_dependency 'aruba'
|
20
|
+
spec.add_development_dependency 'aruba', '~> 0.14'
|
21
21
|
spec.add_development_dependency 'bundler'
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
spec.add_development_dependency 'rspec'
|
@@ -11,4 +11,59 @@ describe ModuleSync do
|
|
11
11
|
ModuleSync.update(options)
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
context '::manage_pr' do
|
16
|
+
before(:each) do
|
17
|
+
stub_const('GITHUB_TOKEN', 'test')
|
18
|
+
@git_repo = 'test/modulesync'
|
19
|
+
@namespace, @repo_name = @git_repo.split('/')
|
20
|
+
@options = {
|
21
|
+
:pr => true,
|
22
|
+
:pr_title => 'Test PR is submitted',
|
23
|
+
:branch => 'test',
|
24
|
+
:message => 'Hello world',
|
25
|
+
:pr_auto_merge => false,
|
26
|
+
}
|
27
|
+
|
28
|
+
@client = double()
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'rasies an error when GITHUB_TOKEN not set for PRs' do
|
32
|
+
stub_const('GITHUB_TOKEN', '')
|
33
|
+
options = {:pr => true, :skip_broken => false}
|
34
|
+
|
35
|
+
expect { ModuleSync.manage_pr(@namespace, @repo_name, options) }.to raise_error(RuntimeError).and output(/GITHUB_TOKEN/).to_stderr
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'submits PR when --pr is set' do
|
39
|
+
allow(Octokit::Client).to receive(:new).and_return(@client)
|
40
|
+
allow(@client).to receive(:pull_requests).with(@git_repo, :state => 'open', :base => 'master', :head => "#{@namespace}:#{@options[:branch]}").and_return([])
|
41
|
+
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"})
|
42
|
+
expect { ModuleSync.manage_pr(@namespace, @repo_name, @options) }.to output(/Submitted PR/).to_stdout
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'skips submitting PR if one has already been issued' do
|
46
|
+
allow(Octokit::Client).to receive(:new).and_return(@client)
|
47
|
+
|
48
|
+
pr = {
|
49
|
+
"title" => "Test title",
|
50
|
+
"html_url" => "https://example.com/pulls/44",
|
51
|
+
"number" => "44"
|
52
|
+
}
|
53
|
+
|
54
|
+
expect(@client).to receive(:pull_requests).with(@git_repo, :state => 'open', :base => 'master', :head => "#{@namespace}:#{@options[:branch]}").and_return([pr])
|
55
|
+
expect { ModuleSync.manage_pr(@namespace, @repo_name, @options) }.to output(/Skipped! 1 PRs found for branch test/).to_stdout
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'adds labels to PR when --pr-labels is set' do
|
59
|
+
@options[:pr_labels] = "HELLO,WORLD"
|
60
|
+
|
61
|
+
allow(Octokit::Client).to receive(:new).and_return(@client)
|
62
|
+
allow(@client).to receive(:create_pull_request).and_return({"html_url" => "http://example.com/pulls/22", "number" => "44"})
|
63
|
+
allow(@client).to receive(:pull_requests).with(@git_repo, :state => 'open', :base => 'master', :head => "#{@namespace}:#{@options[:branch]}").and_return([])
|
64
|
+
|
65
|
+
expect(@client).to receive(:add_labels_to_an_issue).with(@git_repo, "44", ["HELLO", "WORLD"])
|
66
|
+
expect { ModuleSync.manage_pr(@namespace, @repo_name, @options) }.to output(/Attaching the following labels to PR 44: HELLO, WORLD/).to_stdout
|
67
|
+
end
|
68
|
+
end
|
14
69
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modulesync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.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:
|
11
|
+
date: 2020-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aruba
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '0.14'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '0.14'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -193,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
195
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
196
|
+
rubygems_version: 3.1.2
|
197
197
|
signing_key:
|
198
198
|
specification_version: 4
|
199
199
|
summary: Puppet Module Synchronizer
|