pdk 0.0.1 → 0.1.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/LICENSE +201 -0
- data/README.md +270 -0
- data/exe/pdk +5 -0
- data/lib/pdk.rb +8 -0
- data/lib/pdk/cli.rb +80 -0
- data/lib/pdk/cli/errors.rb +12 -0
- data/lib/pdk/cli/exec.rb +51 -0
- data/lib/pdk/cli/input.rb +28 -0
- data/lib/pdk/cli/new.rb +30 -0
- data/lib/pdk/cli/new/class.rb +45 -0
- data/lib/pdk/cli/new/module.rb +55 -0
- data/lib/pdk/cli/test.rb +23 -0
- data/lib/pdk/cli/tests/unit.rb +52 -0
- data/lib/pdk/cli/util/option_normalizer.rb +44 -0
- data/lib/pdk/cli/util/option_validator.rb +74 -0
- data/lib/pdk/cli/validate.rb +81 -0
- data/lib/pdk/generate.rb +3 -0
- data/lib/pdk/generators/module.rb +139 -0
- data/lib/pdk/generators/puppet_class.rb +51 -0
- data/lib/pdk/generators/puppet_object.rb +213 -0
- data/lib/pdk/i18n.rb +4 -0
- data/lib/pdk/logger.rb +25 -0
- data/lib/pdk/module/metadata.rb +88 -0
- data/lib/pdk/module/templatedir.rb +231 -0
- data/lib/pdk/report.rb +38 -0
- data/lib/pdk/template_file.rb +87 -0
- data/lib/pdk/tests/unit.rb +21 -0
- data/lib/pdk/util.rb +16 -0
- data/lib/pdk/validate.rb +12 -0
- data/lib/pdk/validators/base_validator.rb +14 -0
- data/lib/pdk/validators/metadata.rb +17 -0
- data/lib/pdk/validators/puppet_lint.rb +17 -0
- data/lib/pdk/validators/puppet_parser.rb +17 -0
- data/lib/pdk/validators/ruby_lint.rb +17 -0
- data/lib/pdk/version.rb +3 -0
- data/locales/config.yaml +21 -0
- data/locales/de/pdk.po +250 -0
- data/locales/pdk.pot +215 -0
- metadata +92 -12
data/exe/pdk
ADDED
data/lib/pdk.rb
ADDED
data/lib/pdk/cli.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'cri'
|
2
|
+
|
3
|
+
require 'pdk/cli/errors'
|
4
|
+
require 'pdk/cli/util/option_validator'
|
5
|
+
require 'pdk/cli/util/option_normalizer'
|
6
|
+
require 'pdk/logger'
|
7
|
+
require 'pdk/report'
|
8
|
+
|
9
|
+
require 'pdk/cli/new'
|
10
|
+
require 'pdk/cli/validate'
|
11
|
+
require 'pdk/cli/test'
|
12
|
+
|
13
|
+
module PDK
|
14
|
+
module CLI
|
15
|
+
def self.base_command
|
16
|
+
@base ||= Cri::Command.new.tap do |cmd|
|
17
|
+
cmd.modify do
|
18
|
+
name 'pdk'
|
19
|
+
usage _("pdk command [options]")
|
20
|
+
summary _("Puppet Development Kit")
|
21
|
+
description _("The shortest path to better modules.")
|
22
|
+
|
23
|
+
flag :h, :help, _("show help for this command") do |_, c|
|
24
|
+
puts c.help
|
25
|
+
exit 0
|
26
|
+
end
|
27
|
+
|
28
|
+
format_desc = _(
|
29
|
+
"Specify desired output format. Valid formats are '%{available_formats}'. " +
|
30
|
+
"You may also specify a file to which the formatted output will be directed, " +
|
31
|
+
"for example: '--format=junit:report.xml'. This option may be specified " +
|
32
|
+
"multiple times as long as each option specifies a distinct target file."
|
33
|
+
) % {available_formats: PDK::Report.formats.join("', '")}
|
34
|
+
|
35
|
+
option :f, :format, format_desc, { argument: :required, multiple: true } do |values|
|
36
|
+
values.compact.each do |v|
|
37
|
+
if v.include?(':')
|
38
|
+
format = v.split(':', 2).first
|
39
|
+
|
40
|
+
PDK::CLI::Util::OptionValidator.enum(format, PDK::Report.formats)
|
41
|
+
else
|
42
|
+
PDK::CLI::Util::OptionValidator.enum(v, PDK::Report.formats)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
flag :d, :debug, _("Enable debug output.") do |_, _|
|
48
|
+
PDK.logger.enable_debug_output
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
cmd.add_command(Cri::Command.new_basic_help)
|
53
|
+
|
54
|
+
cmd.add_command(PDK::CLI::New.command)
|
55
|
+
cmd.add_command(PDK::CLI::Validate.command)
|
56
|
+
cmd.add_command(PDK::CLI::Test.command)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.run(args)
|
61
|
+
base_command.run(args)
|
62
|
+
rescue PDK::CLI::FatalError => e
|
63
|
+
PDK.logger.fatal(e.message) if e.message
|
64
|
+
|
65
|
+
# If FatalError was raised as the result of another exception, send the
|
66
|
+
# details of that exception to the debug log. If there was no cause
|
67
|
+
# (FatalError raised on its own outside a rescue block), send the details
|
68
|
+
# of the FatalError exception to the debug log.
|
69
|
+
cause = e.cause
|
70
|
+
if cause.nil?
|
71
|
+
e.backtrace.each { |line| PDK.logger.debug(line) }
|
72
|
+
else
|
73
|
+
PDK.logger.debug("#{cause.class}: #{cause.message}")
|
74
|
+
cause.backtrace.each { |line| PDK.logger.debug(line) }
|
75
|
+
end
|
76
|
+
|
77
|
+
exit e.exit_code
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module PDK
|
2
|
+
module CLI
|
3
|
+
class FatalError < StandardError
|
4
|
+
attr_reader :exit_code
|
5
|
+
|
6
|
+
def initialize(msg = _("An unexpected error has occurred, try running the command again with --debug"), exit_code=1)
|
7
|
+
@exit_code = exit_code
|
8
|
+
super(msg)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/pdk/cli/exec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'childprocess'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module PDK
|
5
|
+
module CLI
|
6
|
+
module Exec
|
7
|
+
# TODO: decide how to handle multiple output targets when underlying tool doesn't support that
|
8
|
+
# TODO: decide what this method should return
|
9
|
+
# TODO: decide how/when to connect stdin to child process for things like pry
|
10
|
+
def self.execute(*cmd)
|
11
|
+
process = ChildProcess.build(*cmd)
|
12
|
+
|
13
|
+
process.io.stdout = Tempfile.new('stdout')
|
14
|
+
process.io.stderr = Tempfile.new('stderr')
|
15
|
+
|
16
|
+
begin
|
17
|
+
# start the process
|
18
|
+
process.start
|
19
|
+
|
20
|
+
# wait indefinitely for process to exit...
|
21
|
+
process.wait
|
22
|
+
|
23
|
+
stdout = process.io.stdout.open.read
|
24
|
+
stderr = process.io.stderr.open.read
|
25
|
+
ensure
|
26
|
+
process.io.stdout.close
|
27
|
+
process.io.stderr.close
|
28
|
+
end
|
29
|
+
|
30
|
+
{
|
31
|
+
:exit_code => process.exit_code,
|
32
|
+
:stdout => stdout,
|
33
|
+
:stderr => stderr
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.pdk_basedir
|
38
|
+
@pdk_basedir ||= Gem.win_platform? ? 'C:/Program Files/Puppet Labs/DevelopmentKit' : '/opt/puppetlabs/sdk'
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.git_bindir
|
42
|
+
@git_dir ||= File.join(pdk_basedir, 'private', 'git', 'bin')
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.git(*args)
|
46
|
+
git_path = ENV['PDK_USE_SYSTEM_BINARIES'].nil? ? File.join(git_bindir, 'git') : 'git'
|
47
|
+
execute(git_path, *args)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PDK
|
2
|
+
module CLI
|
3
|
+
module Input
|
4
|
+
# Query the user for a value via STDIN.
|
5
|
+
#
|
6
|
+
# @param message [String] The message to be displayed to the user before
|
7
|
+
# accepting input.
|
8
|
+
# @param default [String] The default value to be used if the user
|
9
|
+
# provides a blank value.
|
10
|
+
#
|
11
|
+
# @return [String] The value provided by the user (or the supplied
|
12
|
+
# default value).
|
13
|
+
def self.get(message, default=nil)
|
14
|
+
print message
|
15
|
+
if default.nil?
|
16
|
+
print " [(none)]"
|
17
|
+
else
|
18
|
+
print " [#{default}]"
|
19
|
+
end
|
20
|
+
|
21
|
+
print "\n--> "
|
22
|
+
input = (STDIN.gets || '').chomp.strip
|
23
|
+
input = default if input == ''
|
24
|
+
input
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/pdk/cli/new.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'cri'
|
2
|
+
require 'pdk/cli/new/module'
|
3
|
+
require 'pdk/cli/new/class'
|
4
|
+
|
5
|
+
module PDK
|
6
|
+
module CLI
|
7
|
+
module New
|
8
|
+
def self.command
|
9
|
+
@new ||= Cri::Command.new.tap do |cmd|
|
10
|
+
cmd.modify do
|
11
|
+
name 'new'
|
12
|
+
usage _("new <type> [options]")
|
13
|
+
summary _("create a new module, etc.")
|
14
|
+
description _("Creates a new instance of <type> using the options relevant to that type of thing")
|
15
|
+
|
16
|
+
# print the help text for the 'new' sub command if no type has been
|
17
|
+
# provided.
|
18
|
+
run do |opts, args, cmd|
|
19
|
+
puts command.help
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
cmd.add_command(PDK::CLI::New::Module.command)
|
25
|
+
cmd.add_command(PDK::CLI::New::PuppetClass.command)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'cri'
|
2
|
+
require 'pdk/cli/util/option_validator'
|
3
|
+
|
4
|
+
require 'pdk/generators/module'
|
5
|
+
require 'pdk/generators/puppet_class'
|
6
|
+
|
7
|
+
module PDK
|
8
|
+
module CLI
|
9
|
+
module New
|
10
|
+
class PuppetClass
|
11
|
+
include PDK::CLI::Util
|
12
|
+
|
13
|
+
def self.command
|
14
|
+
@puppet_class ||= Cri::Command.define do
|
15
|
+
name 'class'
|
16
|
+
usage _("class [options] <class_name> [parameter[:type]] [parameter[:type]] ...")
|
17
|
+
summary _("Create a new class named <class_name> using given options")
|
18
|
+
|
19
|
+
option nil, 'template-url', _("Specifies the URL to the template to use when creating the module. Defaults to the template used to create the module, otherwise %{default}") % {:default => PDK::Generate::Module::DEFAULT_TEMPLATE}, argument: :required
|
20
|
+
|
21
|
+
run do |opts, args, cmd|
|
22
|
+
class_name = args[0]
|
23
|
+
module_dir = Dir.pwd
|
24
|
+
|
25
|
+
if class_name.nil? || class_name.empty?
|
26
|
+
puts command.help
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
|
30
|
+
unless PDK::CLI::Util::OptionValidator.is_valid_class_name?(class_name)
|
31
|
+
raise PDK::CLI::FatalError, _("'%{name}' is not a valid class name") % {name: class_name}
|
32
|
+
end
|
33
|
+
|
34
|
+
if args.length > 1
|
35
|
+
opts[:params] = args[1..-1].map { |r| PDK::CLI::Util::OptionNormalizer.parameter_specification(r) }
|
36
|
+
end
|
37
|
+
|
38
|
+
PDK::Generate::PuppetClass.new(module_dir, class_name, opts).run
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'cri'
|
2
|
+
require 'pdk/cli/util/option_validator'
|
3
|
+
|
4
|
+
require 'pdk/generators/module'
|
5
|
+
|
6
|
+
module PDK
|
7
|
+
module CLI
|
8
|
+
module New
|
9
|
+
class Module
|
10
|
+
include PDK::CLI::Util
|
11
|
+
|
12
|
+
def self.command
|
13
|
+
@module ||= Cri::Command.define do
|
14
|
+
name 'module'
|
15
|
+
usage _("module [options] <module_name> [target_dir]")
|
16
|
+
summary _("Create a new module named <module_name> using given options")
|
17
|
+
|
18
|
+
option nil, 'template-url', _("Specifies the URL to the template to use when creating the module. Defaults to %{default}") % {:default => PDK::Generate::Module::DEFAULT_TEMPLATE}, argument: :required
|
19
|
+
|
20
|
+
option nil, 'license', _("Specifies the license this module is written under. This should be a identifier from https://spdx.org/licenses/. Common values are 'Apache-2.0', 'MIT', or 'proprietary'."), argument: :required
|
21
|
+
|
22
|
+
option nil, 'vcs', _("Specifies the version control driver. Valid values: 'git', 'none'. Default: 'git'."), argument: :required
|
23
|
+
|
24
|
+
flag nil, 'skip-interview', _("When specified, skips interactive querying of metadata.")
|
25
|
+
|
26
|
+
run do |opts, args, cmd|
|
27
|
+
module_name = args[0]
|
28
|
+
target_dir = args[1]
|
29
|
+
|
30
|
+
if module_name.nil? || module_name.empty?
|
31
|
+
puts command.help
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
unless OptionValidator.is_valid_module_name?(module_name)
|
36
|
+
error_msg = _(
|
37
|
+
"'%{module_name}' is not a valid module name.\n" +
|
38
|
+
"Module names must begin with a lowercase letter and can only include lowercase letters, digits, and underscores."
|
39
|
+
) % {:module_name => module_name}
|
40
|
+
raise PDK::CLI::FatalError.new(error_msg)
|
41
|
+
end
|
42
|
+
|
43
|
+
opts[:name] = module_name
|
44
|
+
opts[:target_dir] = target_dir.nil? ? module_name : target_dir
|
45
|
+
opts[:vcs] ||= 'git'
|
46
|
+
|
47
|
+
PDK.logger.info(_("Creating new module: %{modname}") % {:modname => module_name})
|
48
|
+
PDK::Generate::Module.invoke(opts)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/pdk/cli/test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'cri'
|
2
|
+
require 'pdk/cli/tests/unit'
|
3
|
+
require 'pdk/report'
|
4
|
+
|
5
|
+
|
6
|
+
module PDK
|
7
|
+
module CLI
|
8
|
+
module Test
|
9
|
+
|
10
|
+
def self.command
|
11
|
+
@test ||= Cri::Command.new.tap do |cmd|
|
12
|
+
cmd.modify do
|
13
|
+
name 'test'
|
14
|
+
usage _("test [type] [options]")
|
15
|
+
summary _("Run tests.")
|
16
|
+
end
|
17
|
+
|
18
|
+
cmd.add_command(PDK::CLI::Test::Unit.command)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'cri'
|
2
|
+
require 'pdk/cli/util/option_validator'
|
3
|
+
require 'pdk/report'
|
4
|
+
|
5
|
+
require 'pdk/tests/unit'
|
6
|
+
|
7
|
+
module PDK
|
8
|
+
module CLI
|
9
|
+
module Test
|
10
|
+
class Unit
|
11
|
+
include PDK::CLI::Util
|
12
|
+
|
13
|
+
def self.command
|
14
|
+
@unit ||= Cri::Command.define do
|
15
|
+
name 'unit'
|
16
|
+
usage _("unit [options]")
|
17
|
+
summary _("Run unit tests.")
|
18
|
+
|
19
|
+
flag nil, :list, _("list all available unit tests and their descriptions")
|
20
|
+
|
21
|
+
option nil, :tests, _("a comma-separated list of tests to run"), argument: :required do |values|
|
22
|
+
OptionValidator.list(values)
|
23
|
+
end
|
24
|
+
|
25
|
+
option nil, :runner_options, _("options to pass through to the actual test-runner"), argument: :required
|
26
|
+
|
27
|
+
run do |opts, args, cmd|
|
28
|
+
report = nil
|
29
|
+
|
30
|
+
if opts[:list]
|
31
|
+
puts _("List of all available unit tests: (TODO)")
|
32
|
+
end
|
33
|
+
|
34
|
+
if opts[:tests]
|
35
|
+
tests = opts.fetch(:tests)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Note: Reporting may be delegated to the validation tool itself.
|
39
|
+
if opts[:'report-file']
|
40
|
+
format = opts.fetch(:'report-format', PDK::Report.default_format)
|
41
|
+
report = Report.new(opts.fetch(:'report-file'), format)
|
42
|
+
end
|
43
|
+
|
44
|
+
puts _("Running unit tests: %{tests}") % {tests: tests}
|
45
|
+
PDK::Test::Unit.invoke(tests, report)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module PDK
|
2
|
+
module CLI
|
3
|
+
module Util
|
4
|
+
class OptionNormalizer
|
5
|
+
def self.comma_separated_list_to_array(list, options = {})
|
6
|
+
raise _("Error: expected comma separated list") unless OptionValidator.is_comma_separated_list?(list)
|
7
|
+
list.split(',').compact
|
8
|
+
end
|
9
|
+
|
10
|
+
# Parse one or more format:target pairs.
|
11
|
+
# @return [Array<Report>] An array of one or more Reports.
|
12
|
+
def self.report_formats(formats, options = {})
|
13
|
+
reports = []
|
14
|
+
formats.each do |f|
|
15
|
+
if f.include?(':')
|
16
|
+
format, target = f.split(':')
|
17
|
+
else
|
18
|
+
format, target = f, PDK::Report.default_target
|
19
|
+
end
|
20
|
+
|
21
|
+
reports << Report.new(target, format)
|
22
|
+
end
|
23
|
+
|
24
|
+
reports
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.parameter_specification(value)
|
28
|
+
param_name, param_type = value.split(':', 2)
|
29
|
+
param_type = 'String' if param_type.nil?
|
30
|
+
|
31
|
+
unless PDK::CLI::Util::OptionValidator.is_valid_param_name?(param_name)
|
32
|
+
raise PDK::CLI::FatalError, _("'%{name}' is not a valid parameter name") % {name: param_name}
|
33
|
+
end
|
34
|
+
|
35
|
+
unless PDK::CLI::Util::OptionValidator.is_valid_data_type?(param_type)
|
36
|
+
raise PDK::CLI::FatalError, _("'%{type}' is not a valid data type") % {type: param_type}
|
37
|
+
end
|
38
|
+
|
39
|
+
{name: param_name, type: param_type}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|