modulesync 0.8.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +8 -3
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +0 -5
- data/.travis.yml +8 -8
- data/CHANGELOG.md +44 -0
- data/Gemfile +3 -0
- data/README.md +63 -15
- data/Rakefile +1 -0
- data/features/step_definitions/git_steps.rb +23 -0
- data/features/update.feature +152 -28
- data/lib/modulesync.rb +79 -34
- data/lib/modulesync/cli.rb +28 -6
- data/lib/modulesync/git.rb +29 -8
- data/lib/modulesync/pr/github.rb +41 -0
- data/lib/modulesync/pr/gitlab.rb +40 -0
- data/lib/modulesync/renderer.rb +4 -3
- data/lib/modulesync/settings.rb +1 -2
- data/lib/modulesync/util.rb +10 -0
- data/lib/monkey_patches.rb +15 -0
- data/modulesync.gemspec +4 -2
- data/spec/unit/modulesync/pr/github_spec.rb +49 -0
- data/spec/unit/modulesync/pr/gitlab_spec.rb +81 -0
- data/spec/unit/modulesync_spec.rb +22 -0
- metadata +43 -8
data/lib/modulesync.rb
CHANGED
@@ -9,7 +9,7 @@ require 'modulesync/settings'
|
|
9
9
|
require 'modulesync/util'
|
10
10
|
require 'monkey_patches'
|
11
11
|
|
12
|
-
module ModuleSync
|
12
|
+
module ModuleSync # rubocop:disable Metrics/ModuleLength
|
13
13
|
include Constants
|
14
14
|
|
15
15
|
def self.config_defaults
|
@@ -22,31 +22,39 @@ module ModuleSync
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.local_file(config_path, file)
|
25
|
-
|
25
|
+
File.join(config_path, MODULE_FILES_DIR, file)
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.module_file(project_root, puppet_module,
|
29
|
-
|
28
|
+
def self.module_file(project_root, namespace, puppet_module, *parts)
|
29
|
+
File.join(project_root, namespace, puppet_module, *parts)
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
# List all template files.
|
33
|
+
#
|
34
|
+
# Only select *.erb files, and strip the extension. This way all the code will only have to handle bare paths,
|
35
|
+
# except when reading the actual ERB text
|
36
|
+
def self.find_template_files(local_template_dir)
|
37
|
+
if File.exist?(local_template_dir)
|
38
|
+
Find.find(local_template_dir).find_all { |p| p =~ /.erb$/ && !File.directory?(p) }
|
39
|
+
.collect { |p| p.chomp('.erb') }
|
40
|
+
.to_a
|
36
41
|
else
|
37
|
-
puts "#{
|
42
|
+
$stdout.puts "#{local_template_dir} does not exist." \
|
43
|
+
' Check that you are working in your module configs directory or' \
|
44
|
+
' that you have passed in the correct directory with -c.'
|
38
45
|
exit
|
39
46
|
end
|
40
47
|
end
|
41
48
|
|
42
|
-
def self.
|
43
|
-
|
49
|
+
def self.relative_names(file_list, path)
|
50
|
+
file_list.map { |file| file.sub(/#{path}/, '') }
|
44
51
|
end
|
45
52
|
|
46
|
-
def self.managed_modules(
|
47
|
-
managed_modules = Util.parse_config(
|
53
|
+
def self.managed_modules(config_file, filter, negative_filter)
|
54
|
+
managed_modules = Util.parse_config(config_file)
|
48
55
|
if managed_modules.empty?
|
49
|
-
puts "No modules found
|
56
|
+
$stdout.puts "No modules found in #{config_file}." \
|
57
|
+
' Check that you specified the right :configs directory and :managed_modules_conf file.'
|
50
58
|
exit
|
51
59
|
end
|
52
60
|
managed_modules.select! { |m| m =~ Regexp.new(filter) } unless filter.nil?
|
@@ -71,72 +79,109 @@ module ModuleSync
|
|
71
79
|
end
|
72
80
|
|
73
81
|
def self.manage_file(filename, settings, options)
|
82
|
+
namespace = settings.additional_settings[:namespace]
|
74
83
|
module_name = settings.additional_settings[:puppet_module]
|
75
84
|
configs = settings.build_file_configs(filename)
|
85
|
+
target_file = module_file(options[:project_root], namespace, module_name, filename)
|
76
86
|
if configs['delete']
|
77
|
-
Renderer.remove(
|
87
|
+
Renderer.remove(target_file)
|
78
88
|
else
|
79
89
|
templatename = local_file(options[:configs], filename)
|
80
90
|
begin
|
81
91
|
erb = Renderer.build(templatename)
|
82
|
-
template
|
83
|
-
|
92
|
+
# Meta data passed to the template as @metadata[:name]
|
93
|
+
metadata = {
|
94
|
+
:module_name => module_name,
|
95
|
+
:workdir => module_file(options[:project_root], namespace, module_name),
|
96
|
+
:target_file => target_file,
|
97
|
+
}
|
98
|
+
template = Renderer.render(erb, configs, metadata)
|
99
|
+
Renderer.sync(template, target_file)
|
84
100
|
rescue # rubocop:disable Lint/RescueWithoutErrorClass
|
85
|
-
|
101
|
+
$stderr.puts "Error while rendering #{filename}"
|
86
102
|
raise
|
87
103
|
end
|
88
104
|
end
|
89
105
|
end
|
90
106
|
|
91
107
|
def self.manage_module(puppet_module, module_files, module_options, defaults, options)
|
92
|
-
puts "Syncing #{puppet_module}"
|
93
108
|
namespace, module_name = module_name(puppet_module, options[:namespace])
|
109
|
+
git_repo = File.join(namespace, module_name)
|
94
110
|
unless options[:offline]
|
95
|
-
git_base
|
96
|
-
git_uri = "#{git_base}#{namespace}"
|
97
|
-
Git.pull(git_uri, module_name, options[:branch], options[:project_root], module_options || {})
|
111
|
+
Git.pull(options[:git_base], git_repo, options[:branch], options[:project_root], module_options || {})
|
98
112
|
end
|
99
|
-
|
113
|
+
|
114
|
+
module_configs = Util.parse_config(module_file(options[:project_root], namespace, module_name, MODULE_CONF_FILE))
|
100
115
|
settings = Settings.new(defaults[GLOBAL_DEFAULTS_KEY] || {},
|
101
116
|
defaults,
|
102
117
|
module_configs[GLOBAL_DEFAULTS_KEY] || {},
|
103
118
|
module_configs,
|
104
119
|
:puppet_module => module_name,
|
105
|
-
:git_base => git_base,
|
120
|
+
:git_base => options[:git_base],
|
106
121
|
:namespace => namespace)
|
107
122
|
settings.unmanaged_files(module_files).each do |filename|
|
108
|
-
puts "Not managing #{filename} in #{module_name}"
|
123
|
+
$stdout.puts "Not managing #{filename} in #{module_name}"
|
109
124
|
end
|
110
125
|
|
111
126
|
files_to_manage = settings.managed_files(module_files)
|
112
127
|
files_to_manage.each { |filename| manage_file(filename, settings, options) }
|
113
128
|
|
114
129
|
if options[:noop]
|
115
|
-
Git.update_noop(
|
130
|
+
Git.update_noop(git_repo, options)
|
116
131
|
elsif !options[:offline]
|
117
|
-
Git.update(
|
132
|
+
pushed = Git.update(git_repo, files_to_manage, options)
|
133
|
+
pushed && options[:pr] && @pr.manage(namespace, module_name, options)
|
118
134
|
end
|
119
135
|
end
|
120
136
|
|
121
137
|
def self.update(options)
|
122
138
|
options = config_defaults.merge(options)
|
123
|
-
defaults = Util.parse_config(
|
139
|
+
defaults = Util.parse_config(File.join(options[:configs], CONF_FILE))
|
140
|
+
if options[:pr]
|
141
|
+
unless options[:branch]
|
142
|
+
$stderr.puts 'A branch must be specified with --branch to use --pr!'
|
143
|
+
raise
|
144
|
+
end
|
145
|
+
|
146
|
+
@pr = create_pr_manager if options[:pr]
|
147
|
+
end
|
124
148
|
|
125
|
-
|
126
|
-
local_files =
|
127
|
-
module_files =
|
149
|
+
local_template_dir = File.join(options[:configs], MODULE_FILES_DIR)
|
150
|
+
local_files = find_template_files(local_template_dir)
|
151
|
+
module_files = relative_names(local_files, local_template_dir)
|
128
152
|
|
129
|
-
managed_modules = self.managed_modules(
|
153
|
+
managed_modules = self.managed_modules(File.join(options[:configs], options[:managed_modules_conf]),
|
154
|
+
options[:filter],
|
155
|
+
options[:negative_filter])
|
130
156
|
|
157
|
+
errors = false
|
131
158
|
# managed_modules is either an array or a hash
|
132
159
|
managed_modules.each do |puppet_module, module_options|
|
133
160
|
begin
|
134
161
|
manage_module(puppet_module, module_files, module_options, defaults, options)
|
135
162
|
rescue # rubocop:disable Lint/RescueWithoutErrorClass
|
136
|
-
|
163
|
+
$stderr.puts "Error while updating #{puppet_module}"
|
137
164
|
raise unless options[:skip_broken]
|
138
|
-
|
165
|
+
errors = true
|
166
|
+
$stdout.puts "Skipping #{puppet_module} as update process failed"
|
139
167
|
end
|
140
168
|
end
|
169
|
+
exit 1 if errors && options[:fail_on_warnings]
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.create_pr_manager
|
173
|
+
github_token = ENV.fetch('GITHUB_TOKEN', '')
|
174
|
+
gitlab_token = ENV.fetch('GITLAB_TOKEN', '')
|
175
|
+
|
176
|
+
if !github_token.empty?
|
177
|
+
require 'modulesync/pr/github'
|
178
|
+
ModuleSync::PR::GitHub.new(github_token, ENV.fetch('GITHUB_BASE_URL', 'https://api.github.com'))
|
179
|
+
elsif !gitlab_token.empty?
|
180
|
+
require 'modulesync/pr/github'
|
181
|
+
ModuleSync::PR::GitLab.new(gitlab_token, ENV.fetch('GITLAB_BASE_URL', 'https://gitlab.com/api/v4'))
|
182
|
+
else
|
183
|
+
$stderr.puts 'Environment variables GITHUB_TOKEN or GITLAB_TOKEN must be set to use --pr!'
|
184
|
+
raise
|
185
|
+
end
|
141
186
|
end
|
142
187
|
end
|
data/lib/modulesync/cli.rb
CHANGED
@@ -43,7 +43,8 @@ module ModuleSync
|
|
43
43
|
:default => CLI.defaults[:git_base] || 'git@github.com:'
|
44
44
|
class_option :namespace,
|
45
45
|
:aliases => '-n',
|
46
|
-
:desc => 'Remote github namespace (user or organization) to clone from and push to.
|
46
|
+
:desc => 'Remote github namespace (user or organization) to clone from and push to.' \
|
47
|
+
' Defaults to puppetlabs',
|
47
48
|
:default => CLI.defaults[:namespace] || 'puppetlabs'
|
48
49
|
class_option :filter,
|
49
50
|
:aliases => '-f',
|
@@ -53,8 +54,9 @@ module ModuleSync
|
|
53
54
|
:desc => 'A regular expression to skip repositories.'
|
54
55
|
class_option :branch,
|
55
56
|
:aliases => '-b',
|
56
|
-
:desc => 'Branch name to make the changes in.
|
57
|
-
|
57
|
+
:desc => 'Branch name to make the changes in.' \
|
58
|
+
' Defaults to the default branch of the upstream repository, but falls back to "master".',
|
59
|
+
:default => CLI.defaults[:branch]
|
58
60
|
|
59
61
|
desc 'update', 'Update the modules in managed_modules.yml'
|
60
62
|
option :message,
|
@@ -63,7 +65,8 @@ module ModuleSync
|
|
63
65
|
:default => CLI.defaults[:message]
|
64
66
|
option :configs,
|
65
67
|
:aliases => '-c',
|
66
|
-
:desc => 'The local directory or remote repository to define the list of managed modules,
|
68
|
+
:desc => 'The local directory or remote repository to define the list of managed modules,' \
|
69
|
+
' the file templates, and the default values for template variables.'
|
67
70
|
option :remote_branch,
|
68
71
|
:aliases => '-r',
|
69
72
|
:desc => 'Remote branch name to push the changes to. Defaults to the branch name.',
|
@@ -85,6 +88,17 @@ module ModuleSync
|
|
85
88
|
:type => :boolean,
|
86
89
|
:desc => 'No-op mode',
|
87
90
|
:default => false
|
91
|
+
option :pr,
|
92
|
+
:type => :boolean,
|
93
|
+
:desc => 'Submit pull/merge request',
|
94
|
+
:default => false
|
95
|
+
option :pr_title,
|
96
|
+
:desc => 'Title of pull/merge request',
|
97
|
+
:default => CLI.defaults[:pr_title] || 'Update to module template files'
|
98
|
+
option :pr_labels,
|
99
|
+
:type => :array,
|
100
|
+
:desc => 'Labels to add to the pull/merge request',
|
101
|
+
:default => CLI.defaults[:pr_labels] || []
|
88
102
|
option :offline,
|
89
103
|
:type => :boolean,
|
90
104
|
:desc => 'Do not run any Git commands. Allows the user to manage Git outside of ModuleSync.',
|
@@ -104,13 +118,21 @@ module ModuleSync
|
|
104
118
|
option :tag_pattern,
|
105
119
|
:desc => 'The pattern to use when tagging releases.'
|
106
120
|
option :pre_commit_script,
|
107
|
-
:desc => 'A script to be run before
|
121
|
+
:desc => 'A script to be run before committing',
|
108
122
|
:default => CLI.defaults[:pre_commit_script]
|
123
|
+
option :fail_on_warnings,
|
124
|
+
:type => :boolean,
|
125
|
+
:aliases => '-F',
|
126
|
+
:desc => 'Produce a failure exit code when there are warnings' \
|
127
|
+
' (only has effect when --skip_broken is enabled)',
|
128
|
+
:default => false
|
109
129
|
|
110
130
|
def update
|
111
131
|
config = { :command => 'update' }.merge(options)
|
112
132
|
config = Util.symbolize_keys(config)
|
113
|
-
raise Thor::Error, 'No value provided for required option "--message"' unless config[:noop]
|
133
|
+
raise Thor::Error, 'No value provided for required option "--message"' unless config[:noop] \
|
134
|
+
|| config[:message] \
|
135
|
+
|| config[:offline]
|
114
136
|
config[:git_opts] = { 'amend' => config[:amend], 'force' => config[:force] }
|
115
137
|
ModuleSync.update(config)
|
116
138
|
end
|
data/lib/modulesync/git.rb
CHANGED
@@ -2,7 +2,7 @@ require 'git'
|
|
2
2
|
require 'puppet_blacksmith'
|
3
3
|
|
4
4
|
module ModuleSync
|
5
|
-
module Git
|
5
|
+
module Git # rubocop:disable Metrics/ModuleLength
|
6
6
|
include Constants
|
7
7
|
|
8
8
|
def self.remote_branch_exists?(repo, branch)
|
@@ -18,7 +18,17 @@ module ModuleSync
|
|
18
18
|
repo.diff("#{local_branch}..origin/#{remote_branch}").any?
|
19
19
|
end
|
20
20
|
|
21
|
+
def self.default_branch(repo)
|
22
|
+
symbolic_ref = repo.branches.find { |b| b.full =~ %r{remotes/origin/HEAD} }
|
23
|
+
return unless symbolic_ref
|
24
|
+
%r{remotes/origin/HEAD\s+->\s+origin/(?<branch>.+?)$}.match(symbolic_ref.full)[:branch]
|
25
|
+
end
|
26
|
+
|
21
27
|
def self.switch_branch(repo, branch)
|
28
|
+
unless branch
|
29
|
+
branch = default_branch(repo)
|
30
|
+
puts "Using repository's default branch: #{branch}"
|
31
|
+
end
|
22
32
|
return if repo.current_branch == branch
|
23
33
|
|
24
34
|
if local_branch_exists?(repo, branch)
|
@@ -36,12 +46,13 @@ module ModuleSync
|
|
36
46
|
end
|
37
47
|
|
38
48
|
def self.pull(git_base, name, branch, project_root, opts)
|
49
|
+
puts "Syncing #{name}"
|
39
50
|
Dir.mkdir(project_root) unless Dir.exist?(project_root)
|
40
51
|
|
41
52
|
# Repo needs to be cloned in the cwd
|
42
53
|
if !Dir.exist?("#{project_root}/#{name}") || !Dir.exist?("#{project_root}/#{name}/.git")
|
43
54
|
puts 'Cloning repository fresh'
|
44
|
-
remote = opts[:remote] || (git_base.start_with?('file://') ? "#{git_base}
|
55
|
+
remote = opts[:remote] || (git_base.start_with?('file://') ? "#{git_base}#{name}" : "#{git_base}#{name}.git")
|
45
56
|
local = "#{project_root}/#{name}"
|
46
57
|
puts "Cloning from #{remote}"
|
47
58
|
repo = ::Git.clone(remote, local)
|
@@ -95,12 +106,19 @@ module ModuleSync
|
|
95
106
|
repo.push('origin', tag)
|
96
107
|
end
|
97
108
|
|
109
|
+
def self.checkout_branch(repo, branch)
|
110
|
+
selected_branch = branch || repo.current_branch || 'master'
|
111
|
+
repo.branch(selected_branch).checkout
|
112
|
+
selected_branch
|
113
|
+
end
|
114
|
+
private_class_method :checkout_branch
|
115
|
+
|
98
116
|
# Git add/rm, git commit, git push
|
99
117
|
def self.update(name, files, options)
|
100
118
|
module_root = "#{options[:project_root]}/#{name}"
|
101
119
|
message = options[:message]
|
102
120
|
repo = ::Git.open(module_root)
|
103
|
-
|
121
|
+
branch = checkout_branch(repo, options[:branch])
|
104
122
|
files.each do |file|
|
105
123
|
if repo.status.deleted.include?(file)
|
106
124
|
repo.remove(file)
|
@@ -119,11 +137,11 @@ module ModuleSync
|
|
119
137
|
end
|
120
138
|
repo.commit(message, opts_commit)
|
121
139
|
if options[:remote_branch]
|
122
|
-
if remote_branch_differ?(repo,
|
123
|
-
repo.push('origin', "#{
|
140
|
+
if remote_branch_differ?(repo, branch, options[:remote_branch])
|
141
|
+
repo.push('origin', "#{branch}:#{options[:remote_branch]}", opts_push)
|
124
142
|
end
|
125
143
|
else
|
126
|
-
repo.push('origin',
|
144
|
+
repo.push('origin', branch, opts_push)
|
127
145
|
end
|
128
146
|
# Only bump/tag if pushing didn't fail (i.e. there were changes)
|
129
147
|
m = Blacksmith::Modulefile.new("#{module_root}/metadata.json")
|
@@ -134,11 +152,14 @@ module ModuleSync
|
|
134
152
|
rescue ::Git::GitExecuteError => git_error
|
135
153
|
if git_error.message =~ /working (directory|tree) clean/
|
136
154
|
puts "There were no files to update in #{name}. Not committing."
|
155
|
+
return false
|
137
156
|
else
|
138
157
|
puts git_error
|
139
|
-
|
158
|
+
raise
|
140
159
|
end
|
141
160
|
end
|
161
|
+
|
162
|
+
true
|
142
163
|
end
|
143
164
|
|
144
165
|
# Needed because of a bug in the git gem that lists ignored files as
|
@@ -154,7 +175,7 @@ module ModuleSync
|
|
154
175
|
puts "Using no-op. Files in #{name} may be changed but will not be committed."
|
155
176
|
|
156
177
|
repo = ::Git.open("#{options[:project_root]}/#{name}")
|
157
|
-
repo
|
178
|
+
checkout_branch(repo, options[:branch])
|
158
179
|
|
159
180
|
puts 'Files changed:'
|
160
181
|
repo.diff('HEAD', '--').each do |diff|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
require 'modulesync/util'
|
3
|
+
|
4
|
+
module ModuleSync
|
5
|
+
module PR
|
6
|
+
# GitHub creates and manages pull requests on github.com or GitHub
|
7
|
+
# Enterprise installations.
|
8
|
+
class GitHub
|
9
|
+
def initialize(token, endpoint)
|
10
|
+
Octokit.configure do |c|
|
11
|
+
c.api_endpoint = endpoint
|
12
|
+
end
|
13
|
+
@api = Octokit::Client.new(:access_token => token)
|
14
|
+
end
|
15
|
+
|
16
|
+
def manage(namespace, module_name, options)
|
17
|
+
repo_path = File.join(namespace, module_name)
|
18
|
+
head = "#{namespace}:#{options[:branch]}"
|
19
|
+
|
20
|
+
pull_requests = @api.pull_requests(repo_path, :state => 'open', :base => 'master', :head => head)
|
21
|
+
if pull_requests.empty?
|
22
|
+
pr = @api.create_pull_request(repo_path, 'master', options[:branch], options[:pr_title], options[:message])
|
23
|
+
$stdout.puts "Submitted PR '#{options[:pr_title]}' to #{repo_path} - merges #{options[:branch]} into master"
|
24
|
+
else
|
25
|
+
# Skip creating the PR if it exists already.
|
26
|
+
$stdout.puts "Skipped! #{pull_requests.length} PRs found for branch #{options[:branch]}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# PR labels can either be a list in the YAML file or they can pass in a comma
|
30
|
+
# separated list via the command line argument.
|
31
|
+
pr_labels = ModuleSync::Util.parse_list(options[:pr_labels])
|
32
|
+
|
33
|
+
# We only assign labels to the PR if we've discovered a list > 1. The labels MUST
|
34
|
+
# already exist. We DO NOT create missing labels.
|
35
|
+
return if pr_labels.empty?
|
36
|
+
$stdout.puts "Attaching the following labels to PR #{pr['number']}: #{pr_labels.join(', ')}"
|
37
|
+
@api.add_labels_to_an_issue(repo_path, pr['number'], pr_labels)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
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
|
+
|
19
|
+
head = "#{namespace}:#{options[:branch]}"
|
20
|
+
merge_requests = @api.merge_requests(repo_path,
|
21
|
+
:state => 'opened',
|
22
|
+
:source_branch => head,
|
23
|
+
:target_branch => 'master')
|
24
|
+
if merge_requests.empty?
|
25
|
+
mr_labels = ModuleSync::Util.parse_list(options[:pr_labels])
|
26
|
+
mr = @api.create_merge_request(repo_path, options[:pr_title],
|
27
|
+
:source_branch => options[:branch],
|
28
|
+
:target_branch => 'master',
|
29
|
+
:labels => mr_labels)
|
30
|
+
$stdout.puts "Submitted MR '#{options[:pr_title]}' to #{repo_path} - merges #{options[:branch]} into master"
|
31
|
+
return if mr_labels.empty?
|
32
|
+
$stdout.puts "Attached the following labels to MR #{mr.iid}: #{mr_labels.join(', ')}"
|
33
|
+
else
|
34
|
+
# Skip creating the MR if it exists already.
|
35
|
+
$stdout.puts "Skipped! #{merge_requests.length} MRs found for branch #{options[:branch]}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
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)
|