pdk 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|