pdk 0.6.0 → 1.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +50 -250
- data/lib/pdk/cli.rb +2 -1
- data/lib/pdk/cli/exec.rb +47 -38
- data/lib/pdk/cli/exec_group.rb +53 -0
- data/lib/pdk/cli/new/class.rb +1 -5
- data/lib/pdk/cli/util.rb +11 -0
- data/lib/pdk/cli/util/interview.rb +1 -0
- data/lib/pdk/cli/validate.rb +17 -5
- data/lib/pdk/generators/module.rb +36 -18
- data/lib/pdk/generators/puppet_class.rb +1 -4
- data/lib/pdk/generators/puppet_object.rb +1 -1
- data/lib/pdk/logger.rb +4 -0
- data/lib/pdk/module/metadata.rb +1 -0
- data/lib/pdk/module/templatedir.rb +9 -3
- data/lib/pdk/monkey_patches.rb +13 -0
- data/lib/pdk/report/event.rb +4 -2
- data/lib/pdk/util.rb +14 -0
- data/lib/pdk/util/bundler.rb +5 -11
- data/lib/pdk/validators/base_validator.rb +67 -6
- data/lib/pdk/validators/metadata/metadata_json_lint.rb +3 -3
- data/lib/pdk/validators/metadata/metadata_syntax.rb +33 -13
- data/lib/pdk/validators/puppet/puppet_lint.rb +1 -1
- data/lib/pdk/validators/puppet/puppet_syntax.rb +1 -1
- data/lib/pdk/validators/ruby/rubocop.rb +5 -1
- data/lib/pdk/version.rb +1 -1
- data/locales/pdk.pot +240 -117
- metadata +9 -8
- data/locales/de/pdk.po +0 -604
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'tty-spinner'
|
2
|
+
require 'tty-which'
|
3
|
+
|
4
|
+
require 'pdk/util'
|
5
|
+
|
6
|
+
module PDK
|
7
|
+
module CLI
|
8
|
+
class ExecGroup
|
9
|
+
attr_reader :commands
|
10
|
+
|
11
|
+
def initialize(message, opts = {})
|
12
|
+
@options = opts.merge(PDK::CLI::Util.spinner_opts_for_platform)
|
13
|
+
|
14
|
+
unless PDK.logger.debug?
|
15
|
+
@multi_spinner = TTY::Spinner::Multi.new("[:spinner] #{message}", @options)
|
16
|
+
@multi_spinner.auto_spin
|
17
|
+
end
|
18
|
+
|
19
|
+
@threads = []
|
20
|
+
@exit_codes = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def register
|
24
|
+
raise PDK::CLI::FatalError, 'No block registered' unless block_given?
|
25
|
+
|
26
|
+
@threads << Thread.new do
|
27
|
+
GettextSetup.initialize(File.absolute_path('../../../locales', File.dirname(__FILE__)))
|
28
|
+
GettextSetup.negotiate_locale!(GettextSetup.candidate_locales)
|
29
|
+
@exit_codes << yield
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_spinner(message, opts = {})
|
34
|
+
return if PDK.logger.debug?
|
35
|
+
@multi_spinner.register("[:spinner] #{message}", @options.merge(opts).merge(PDK::CLI::Util.spinner_opts_for_platform))
|
36
|
+
end
|
37
|
+
|
38
|
+
def exit_code
|
39
|
+
@threads.each(&:join)
|
40
|
+
|
41
|
+
exit_code = @exit_codes.max
|
42
|
+
|
43
|
+
if exit_code.zero? && @multi_spinner
|
44
|
+
@multi_spinner.success
|
45
|
+
elsif @multi_spinner
|
46
|
+
@multi_spinner.error
|
47
|
+
end
|
48
|
+
|
49
|
+
exit_code
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/pdk/cli/new/class.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module PDK::CLI
|
2
2
|
@new_class_cmd = @new_cmd.define_command do
|
3
3
|
name 'class'
|
4
|
-
usage _('class [options] <class_name>
|
4
|
+
usage _('class [options] <class_name>')
|
5
5
|
summary _('Create a new class named <class_name> using given options')
|
6
6
|
|
7
7
|
PDK::CLI.template_url_option(self)
|
@@ -23,10 +23,6 @@ module PDK::CLI
|
|
23
23
|
raise PDK::CLI::FatalError, _("'%{name}' is not a valid class name") % { name: class_name }
|
24
24
|
end
|
25
25
|
|
26
|
-
if args.length > 1
|
27
|
-
opts[:params] = args[1..-1].map { |r| Util::OptionNormalizer.parameter_specification(r) }
|
28
|
-
end
|
29
|
-
|
30
26
|
PDK::Generate::PuppetClass.new(module_dir, class_name, opts).run
|
31
27
|
end
|
32
28
|
end
|
data/lib/pdk/cli/util.rb
CHANGED
@@ -10,6 +10,17 @@ module PDK
|
|
10
10
|
raise PDK::CLI::FatalError, message if PDK::Util.module_root.nil?
|
11
11
|
end
|
12
12
|
module_function :ensure_in_module!
|
13
|
+
|
14
|
+
def spinner_opts_for_platform
|
15
|
+
windows_opts = {
|
16
|
+
success_mark: '*',
|
17
|
+
error_mark: 'X',
|
18
|
+
}
|
19
|
+
|
20
|
+
return windows_opts if Gem.win_platform?
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
module_function :spinner_opts_for_platform
|
13
24
|
end
|
14
25
|
end
|
15
26
|
end
|
data/lib/pdk/cli/validate.rb
CHANGED
@@ -15,6 +15,7 @@ module PDK::CLI
|
|
15
15
|
|
16
16
|
flag nil, :list, _('list all available validators')
|
17
17
|
flag :a, 'auto-correct', _('automatically correct problems (where possible)')
|
18
|
+
flag nil, :parallel, _('run validations in parallel')
|
18
19
|
|
19
20
|
run do |opts, args, _cmd|
|
20
21
|
if args == ['help']
|
@@ -76,14 +77,25 @@ module PDK::CLI
|
|
76
77
|
options = targets.empty? ? {} : { targets: targets }
|
77
78
|
options[:auto_correct] = true if opts.key?(:'auto-correct')
|
78
79
|
|
79
|
-
exit_code = 0
|
80
|
-
|
81
80
|
# Ensure that the bundle is installed and tools are available before running any validations.
|
82
81
|
PDK::Util::Bundler.ensure_bundle!
|
83
82
|
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
exit_code = 0
|
84
|
+
if opts[:parallel]
|
85
|
+
exec_group = PDK::CLI::ExecGroup.new(_('Validating module using %{num_of_threads} threads' % { num_of_threads: validators.count }), opts)
|
86
|
+
|
87
|
+
validators.each do |validator|
|
88
|
+
exec_group.register do
|
89
|
+
validator.invoke(report, options.merge(exec_group: exec_group))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
exit_code = exec_group.exit_code
|
94
|
+
else
|
95
|
+
validators.each do |validator|
|
96
|
+
validator_exit_code = validator.invoke(report, options.dup)
|
97
|
+
exit_code = validator_exit_code if validator_exit_code != 0
|
98
|
+
end
|
87
99
|
end
|
88
100
|
|
89
101
|
report_formats.each do |format|
|
@@ -15,7 +15,15 @@ require 'pdk/util/version'
|
|
15
15
|
module PDK
|
16
16
|
module Generate
|
17
17
|
class Module
|
18
|
-
|
18
|
+
def self.default_template_url
|
19
|
+
if !PDK.answers['template-url'].nil?
|
20
|
+
PDK.answers['template-url']
|
21
|
+
elsif PDK::Util.package_install?
|
22
|
+
'file://' + File.join(PDK::Util.package_cachedir, 'pdk-module-template.git')
|
23
|
+
else
|
24
|
+
'https://github.com/puppetlabs/pdk-module-template'
|
25
|
+
end
|
26
|
+
end
|
19
27
|
|
20
28
|
def self.invoke(opts = {})
|
21
29
|
target_dir = File.expand_path(opts[:target_dir])
|
@@ -42,9 +50,9 @@ module PDK
|
|
42
50
|
|
43
51
|
prepare_module_directory(temp_target_dir)
|
44
52
|
|
45
|
-
template_url = opts.fetch(:'template-url',
|
53
|
+
template_url = opts.fetch(:'template-url', default_template_url)
|
46
54
|
|
47
|
-
PDK::Module::TemplateDir.new(template_url) do |templates|
|
55
|
+
PDK::Module::TemplateDir.new(template_url, metadata.data) do |templates|
|
48
56
|
templates.render do |file_path, file_content|
|
49
57
|
file = Pathname.new(temp_target_dir) + file_path
|
50
58
|
file.dirname.mkpath
|
@@ -79,7 +87,7 @@ module PDK
|
|
79
87
|
login_clean = 'username' if login_clean.empty?
|
80
88
|
|
81
89
|
if login_clean != login
|
82
|
-
PDK.logger.warn _('
|
90
|
+
PDK.logger.warn _('Your username is not a valid Forge username, proceeding with the username %{username}. You can fix this afterwards in metadata.json.') % {
|
83
91
|
username: login_clean,
|
84
92
|
}
|
85
93
|
end
|
@@ -96,6 +104,9 @@ module PDK
|
|
96
104
|
'dependencies' => [
|
97
105
|
{ 'name' => 'puppetlabs-stdlib', 'version_requirement' => '>= 4.13.1 < 5.0.0' },
|
98
106
|
],
|
107
|
+
'requirements' => [
|
108
|
+
{ 'name' => 'puppet', 'version_requirement' => '>= 4.7.0 < 6.0.0' },
|
109
|
+
],
|
99
110
|
}
|
100
111
|
defaults['author'] = PDK.answers['author'] unless PDK.answers['author'].nil?
|
101
112
|
defaults['license'] = PDK.answers['license'] unless PDK.answers['license'].nil?
|
@@ -130,8 +141,8 @@ module PDK
|
|
130
141
|
questions = [
|
131
142
|
{
|
132
143
|
name: 'name',
|
133
|
-
question: _('
|
134
|
-
help: _('
|
144
|
+
question: _('If you have a Puppet Forge username, add it here.'),
|
145
|
+
help: _('We can use this to upload your module to the Forge when it\'s complete.'),
|
135
146
|
required: true,
|
136
147
|
validate_pattern: %r{\A[a-z0-9]+\Z}i,
|
137
148
|
validate_message: _('Forge usernames can only contain lowercase letters and numbers'),
|
@@ -149,7 +160,7 @@ module PDK
|
|
149
160
|
{
|
150
161
|
name: 'author',
|
151
162
|
question: _('Who wrote this module?'),
|
152
|
-
help: _('
|
163
|
+
help: _('This will be used to credit the module\'s author.'),
|
153
164
|
required: true,
|
154
165
|
default: metadata.data['author'],
|
155
166
|
},
|
@@ -162,28 +173,28 @@ module PDK
|
|
162
173
|
},
|
163
174
|
{
|
164
175
|
name: 'summary',
|
165
|
-
question: _('
|
166
|
-
help: _('
|
176
|
+
question: _('Please summarize the purpose of this module in a single sentence.'),
|
177
|
+
help: _('This will help other Puppet users understand what the module does.'),
|
167
178
|
required: true,
|
168
179
|
default: metadata.data['summary'],
|
169
180
|
},
|
170
181
|
{
|
171
182
|
name: 'source',
|
172
|
-
question: _(
|
173
|
-
help: _('
|
183
|
+
question: _('If there is a source code repository for this module, enter the URL here.'),
|
184
|
+
help: _('Skip this if none exists yet, you can update this later in the metadata.json.'),
|
174
185
|
required: true,
|
175
186
|
default: metadata.data['source'],
|
176
187
|
},
|
177
188
|
{
|
178
189
|
name: 'project_page',
|
179
|
-
question: _('
|
180
|
-
help: _('
|
190
|
+
question: _('If there is a URL where others can learn more about this module, enter it here.'),
|
191
|
+
help: _('Optional. As with all questions above, you can update this later in the metadata.json.'),
|
181
192
|
default: metadata.data['project_page'],
|
182
193
|
},
|
183
194
|
{
|
184
195
|
name: 'issues_url',
|
185
|
-
question: _('
|
186
|
-
help: _('
|
196
|
+
question: _('If there is a public issue tracker for this module, enter its URL here.'),
|
197
|
+
help: _('Optional. As with all questions above, you can update this later in the metadata.json.'),
|
187
198
|
default: metadata.data['issues_url'],
|
188
199
|
},
|
189
200
|
]
|
@@ -197,8 +208,11 @@ module PDK
|
|
197
208
|
interview.add_questions(questions)
|
198
209
|
|
199
210
|
puts _(
|
200
|
-
"\nWe need to create a metadata.json file for this module, so we're going to ask you %{count} quick
|
201
|
-
"
|
211
|
+
"\nWe need to create a metadata.json file for this module, so we\'re going to ask you %{count} quick " \
|
212
|
+
"questions.\n" \
|
213
|
+
'If the question is not applicable to this module, simply leave the answer blank and skip. A default option ' \
|
214
|
+
'is shown after each question. You can modify this or any other answers at any time by manually updating ' \
|
215
|
+
"the metadata.json file.\n\n",
|
202
216
|
) % { count: interview.num_questions }
|
203
217
|
|
204
218
|
answers = interview.run
|
@@ -220,7 +234,11 @@ module PDK
|
|
220
234
|
puts '-' * 40
|
221
235
|
puts
|
222
236
|
|
223
|
-
|
237
|
+
continue = prompt.yes?(_('About to generate this module; continue?')) do |q|
|
238
|
+
q.validate(proc { |value| [true, false].include?(value) || value =~ %r{\A(?:yes|y|no|n)\Z}i }, 'Please answer "yes" or "no"')
|
239
|
+
end
|
240
|
+
|
241
|
+
unless continue
|
224
242
|
PDK.logger.info _('Module not generated.')
|
225
243
|
exit 0
|
226
244
|
end
|
@@ -11,10 +11,7 @@ module PDK
|
|
11
11
|
# provided to the class and class spec templates during rendering.
|
12
12
|
def template_data
|
13
13
|
data = { name: object_name }
|
14
|
-
|
15
|
-
data[:params] = @options[:params]
|
16
|
-
data[:max_type_length] = @options[:params].map { |r| r[:type].length }.max
|
17
|
-
end
|
14
|
+
|
18
15
|
data
|
19
16
|
end
|
20
17
|
|
@@ -197,7 +197,7 @@ module PDK
|
|
197
197
|
@templates ||= [
|
198
198
|
{ type: 'CLI', url: @options[:'template-url'], allow_fallback: false },
|
199
199
|
{ type: 'metadata', url: module_metadata.data['template-url'], allow_fallback: true },
|
200
|
-
{ type: 'default', url: PDK::Generate::Module
|
200
|
+
{ type: 'default', url: PDK::Generate::Module.default_template_url, allow_fallback: false },
|
201
201
|
]
|
202
202
|
end
|
203
203
|
|
data/lib/pdk/logger.rb
CHANGED
data/lib/pdk/module/metadata.rb
CHANGED
@@ -15,6 +15,8 @@ module PDK
|
|
15
15
|
#
|
16
16
|
# @param path_or_url [String] The path to a directory to use as the
|
17
17
|
# template or a URL to a git repository.
|
18
|
+
# @param module_metadata [Hash] A Hash containing the module metadata.
|
19
|
+
# Defaults to an empty Hash.
|
18
20
|
# @yieldparam self [PDK::Module::TemplateDir] The initialised object with
|
19
21
|
# the template available on disk.
|
20
22
|
#
|
@@ -34,7 +36,7 @@ module PDK
|
|
34
36
|
# @raise [ArgumentError] (see #validate_module_template!)
|
35
37
|
#
|
36
38
|
# @api public
|
37
|
-
def initialize(path_or_url)
|
39
|
+
def initialize(path_or_url, module_metadata = {})
|
38
40
|
if File.directory?(path_or_url)
|
39
41
|
@path = path_or_url
|
40
42
|
else
|
@@ -61,6 +63,8 @@ module PDK
|
|
61
63
|
@object_dir = File.join(@path, 'object_templates')
|
62
64
|
validate_module_template!
|
63
65
|
|
66
|
+
@module_metadata = module_metadata
|
67
|
+
|
64
68
|
yield self
|
65
69
|
ensure
|
66
70
|
# If we cloned a git repo to get the template, remove the clone once
|
@@ -81,7 +85,7 @@ module PDK
|
|
81
85
|
def metadata
|
82
86
|
return {} unless @repo
|
83
87
|
|
84
|
-
ref_result = PDK::CLI::Exec.git('--git-dir', File.join(@path, '.git'), 'describe', '--all', '--long')
|
88
|
+
ref_result = PDK::CLI::Exec.git('--git-dir', File.join(@path, '.git'), 'describe', '--all', '--long', '--always')
|
85
89
|
if ref_result[:exit_code].zero?
|
86
90
|
{ 'template-url' => @repo, 'template-ref' => ref_result[:stdout].strip }
|
87
91
|
else
|
@@ -231,7 +235,9 @@ module PDK
|
|
231
235
|
end
|
232
236
|
|
233
237
|
file_config = @config.fetch(:global, {})
|
234
|
-
file_config
|
238
|
+
file_config['module_metadata'] = @module_metadata
|
239
|
+
file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
|
240
|
+
file_config
|
235
241
|
end
|
236
242
|
end
|
237
243
|
end
|
data/lib/pdk/report/event.rb
CHANGED
@@ -96,7 +96,7 @@ module PDK
|
|
96
96
|
location = nil if location.empty?
|
97
97
|
|
98
98
|
# TODO: maybe add trace
|
99
|
-
[
|
99
|
+
[severity, source, location, message].compact.join(': ')
|
100
100
|
end
|
101
101
|
|
102
102
|
# Renders the event as a JUnit XML testcase.
|
@@ -170,7 +170,9 @@ module PDK
|
|
170
170
|
|
171
171
|
if path.absolute?
|
172
172
|
module_root = Pathname.new(PDK::Util.module_root)
|
173
|
-
path.relative_path_from(module_root).to_path
|
173
|
+
path = path.relative_path_from(module_root).to_path
|
174
|
+
path << '/' if path == '.'
|
175
|
+
path
|
174
176
|
else
|
175
177
|
path.to_path
|
176
178
|
end
|
data/lib/pdk/util.rb
CHANGED
@@ -152,5 +152,19 @@ module PDK
|
|
152
152
|
json_result
|
153
153
|
end
|
154
154
|
module_function :find_valid_json_in
|
155
|
+
|
156
|
+
# Returns the targets' paths relative to the working directory
|
157
|
+
#
|
158
|
+
# @return [Array<String>] The absolute or path to the target
|
159
|
+
def targets_relative_to_pwd(targets)
|
160
|
+
targets.map do |t|
|
161
|
+
if Pathname.new(t).absolute?
|
162
|
+
Pathname.new(t).relative_path_from(Pathname.pwd)
|
163
|
+
else
|
164
|
+
t
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
module_function :targets_relative_to_pwd
|
155
169
|
end
|
156
170
|
end
|
data/lib/pdk/util/bundler.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'fileutils'
|
3
|
-
require 'tty-spinner'
|
4
3
|
require 'pdk/util'
|
5
4
|
require 'pdk/cli/exec'
|
6
5
|
|
@@ -83,8 +82,7 @@ module PDK
|
|
83
82
|
result = bundle_command(*argv).execute!
|
84
83
|
|
85
84
|
unless result[:exit_code].zero?
|
86
|
-
|
87
|
-
$stderr.puts result[:stderr]
|
85
|
+
PDK.logger.debug(result.values_at(:stdout, :stderr).join("\n"))
|
88
86
|
end
|
89
87
|
|
90
88
|
result[:exit_code].zero?
|
@@ -98,15 +96,14 @@ module PDK
|
|
98
96
|
result = command.execute!
|
99
97
|
|
100
98
|
unless result[:exit_code].zero?
|
101
|
-
|
102
|
-
$stderr.puts result[:stderr]
|
99
|
+
PDK.logger.fatal(result.values_at(:stdout, :stderr).join("\n"))
|
103
100
|
end
|
104
101
|
|
105
102
|
result[:exit_code].zero?
|
106
103
|
end
|
107
104
|
|
108
105
|
def install!
|
109
|
-
argv = ['install', "--gemfile=#{gemfile}"]
|
106
|
+
argv = ['install', "--gemfile=#{gemfile}", '-j4']
|
110
107
|
argv << "--path=#{bundle_cachedir}" if PDK::Util.gem_install?
|
111
108
|
|
112
109
|
command = bundle_command(*argv).tap do |c|
|
@@ -116,8 +113,7 @@ module PDK
|
|
116
113
|
result = command.execute!
|
117
114
|
|
118
115
|
unless result[:exit_code].zero?
|
119
|
-
|
120
|
-
$stderr.puts result[:stderr]
|
116
|
+
PDK.logger.fatal(result.values_at(:stdout, :stderr).join("\n"))
|
121
117
|
end
|
122
118
|
|
123
119
|
result[:exit_code].zero?
|
@@ -132,9 +128,7 @@ module PDK
|
|
132
128
|
result = command.execute!
|
133
129
|
|
134
130
|
unless result[:exit_code].zero?
|
135
|
-
PDK.logger.
|
136
|
-
$stderr.puts result[:stdout]
|
137
|
-
$stderr.puts result[:stderr]
|
131
|
+
PDK.logger.fatal(_("Failed to generate binstubs for '%{gems}':\n%{output}") % { gems: gems.join(' '), output: result.values_at(:stdout, :stderr).join("\n") })
|
138
132
|
end
|
139
133
|
|
140
134
|
result[:exit_code].zero?
|