pdk 2.7.0 → 3.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 +29 -0
- data/README.md +2 -48
- data/lib/pdk/analytics/client/google_analytics.rb +22 -26
- data/lib/pdk/analytics/util.rb +0 -1
- data/lib/pdk/analytics.rb +1 -1
- data/lib/pdk/bolt.rb +1 -0
- data/lib/pdk/cli/build.rb +53 -56
- data/lib/pdk/cli/bundle.rb +34 -33
- data/lib/pdk/cli/console.rb +136 -134
- data/lib/pdk/cli/convert.rb +39 -41
- data/lib/pdk/cli/env.rb +49 -47
- data/lib/pdk/cli/errors.rb +1 -2
- data/lib/pdk/cli/exec/command.rb +23 -29
- data/lib/pdk/cli/exec/interactive_command.rb +7 -12
- data/lib/pdk/cli/exec.rb +4 -11
- data/lib/pdk/cli/exec_group.rb +3 -2
- data/lib/pdk/cli/get/config.rb +21 -19
- data/lib/pdk/cli/get.rb +15 -13
- data/lib/pdk/cli/new/class.rb +22 -22
- data/lib/pdk/cli/new/defined_type.rb +22 -22
- data/lib/pdk/cli/new/fact.rb +19 -19
- data/lib/pdk/cli/new/function.rb +20 -20
- data/lib/pdk/cli/new/module.rb +40 -38
- data/lib/pdk/cli/new/provider.rb +19 -19
- data/lib/pdk/cli/new/task.rb +23 -23
- data/lib/pdk/cli/new/test.rb +50 -48
- data/lib/pdk/cli/new/transport.rb +18 -18
- data/lib/pdk/cli/new.rb +11 -9
- data/lib/pdk/cli/release/prep.rb +27 -25
- data/lib/pdk/cli/release/publish.rb +39 -37
- data/lib/pdk/cli/release.rb +152 -149
- data/lib/pdk/cli/remove/config.rb +63 -60
- data/lib/pdk/cli/remove.rb +15 -13
- data/lib/pdk/cli/set/config.rb +91 -89
- data/lib/pdk/cli/set.rb +15 -13
- data/lib/pdk/cli/test/unit.rb +71 -69
- data/lib/pdk/cli/test.rb +9 -7
- data/lib/pdk/cli/update.rb +33 -38
- data/lib/pdk/cli/util/command_redirector.rb +10 -1
- data/lib/pdk/cli/util/interview.rb +11 -4
- data/lib/pdk/cli/util/option_normalizer.rb +2 -4
- data/lib/pdk/cli/util/option_validator.rb +7 -9
- data/lib/pdk/cli/util/update_manager_printer.rb +4 -4
- data/lib/pdk/cli/util.rb +32 -48
- data/lib/pdk/cli/validate.rb +98 -96
- data/lib/pdk/cli.rb +124 -120
- data/lib/pdk/config/ini_file.rb +4 -3
- data/lib/pdk/config/ini_file_setting.rb +6 -10
- data/lib/pdk/config/json.rb +1 -0
- data/lib/pdk/config/json_schema_namespace.rb +5 -10
- data/lib/pdk/config/json_schema_setting.rb +3 -5
- data/lib/pdk/config/json_with_schema.rb +2 -4
- data/lib/pdk/config/namespace.rb +19 -13
- data/lib/pdk/config/setting.rb +5 -6
- data/lib/pdk/config/task_schema.json +116 -0
- data/lib/pdk/config/validator.rb +4 -4
- data/lib/pdk/config/yaml.rb +3 -8
- data/lib/pdk/config/yaml_with_schema.rb +4 -12
- data/lib/pdk/config.rb +47 -51
- data/lib/pdk/context/control_repo.rb +3 -2
- data/lib/pdk/context/module.rb +2 -2
- data/lib/pdk/context/none.rb +2 -2
- data/lib/pdk/context.rb +4 -5
- data/lib/pdk/control_repo.rb +3 -4
- data/lib/pdk/generate/defined_type.rb +3 -3
- data/lib/pdk/generate/fact.rb +3 -2
- data/lib/pdk/generate/function.rb +5 -4
- data/lib/pdk/generate/module.rb +91 -106
- data/lib/pdk/generate/provider.rb +5 -4
- data/lib/pdk/generate/puppet_class.rb +3 -3
- data/lib/pdk/generate/puppet_object.rb +9 -12
- data/lib/pdk/generate/task.rb +11 -10
- data/lib/pdk/generate/transport.rb +8 -7
- data/lib/pdk/generate.rb +1 -1
- data/lib/pdk/logger.rb +3 -2
- data/lib/pdk/module/build.rb +34 -49
- data/lib/pdk/module/convert.rb +13 -22
- data/lib/pdk/module/metadata.rb +53 -61
- data/lib/pdk/module/release.rb +19 -25
- data/lib/pdk/module/update.rb +4 -13
- data/lib/pdk/module/update_manager.rb +18 -25
- data/lib/pdk/module.rb +1 -1
- data/lib/pdk/monkey_patches.rb +268 -0
- data/lib/pdk/report/event.rb +12 -37
- data/lib/pdk/report.rb +4 -4
- data/lib/pdk/template/fetcher/git.rb +7 -8
- data/lib/pdk/template/fetcher/local.rb +1 -0
- data/lib/pdk/template/fetcher.rb +4 -2
- data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +4 -9
- data/lib/pdk/template/renderer/v1/renderer.rb +19 -20
- data/lib/pdk/template/renderer/v1/template_file.rb +4 -8
- data/lib/pdk/template/renderer/v1.rb +1 -1
- data/lib/pdk/template/renderer.rb +1 -0
- data/lib/pdk/template/template_dir.rb +3 -3
- data/lib/pdk/template.rb +2 -6
- data/lib/pdk/tests/unit.rb +36 -25
- data/lib/pdk/util/bundler.rb +10 -14
- data/lib/pdk/util/changelog_generator.rb +15 -12
- data/lib/pdk/util/env.rb +1 -0
- data/lib/pdk/util/filesystem.rb +18 -17
- data/lib/pdk/util/git.rb +16 -21
- data/lib/pdk/util/json_finder.rb +7 -6
- data/lib/pdk/util/puppet_strings.rb +1 -1
- data/lib/pdk/util/puppet_version.rb +16 -67
- data/lib/pdk/util/ruby_version.rb +9 -13
- data/lib/pdk/util/template_uri.rb +17 -29
- data/lib/pdk/util/vendored_file.rb +5 -18
- data/lib/pdk/util/windows/api_types.rb +70 -64
- data/lib/pdk/util/windows/file.rb +31 -27
- data/lib/pdk/util/windows/process.rb +59 -61
- data/lib/pdk/util/windows/string.rb +19 -12
- data/lib/pdk/util.rb +12 -20
- data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +1 -1
- data/lib/pdk/validate/control_repo/environment_conf_validator.rb +25 -25
- data/lib/pdk/validate/external_command_validator.rb +6 -1
- data/lib/pdk/validate/internal_ruby_validator.rb +5 -4
- data/lib/pdk/validate/invokable_validator.rb +30 -20
- data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +12 -14
- data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +13 -15
- data/lib/pdk/validate/metadata/metadata_validator_group.rb +1 -1
- data/lib/pdk/validate/puppet/puppet_epp_validator.rb +16 -18
- data/lib/pdk/validate/puppet/puppet_lint_validator.rb +14 -14
- data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +1 -1
- data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +16 -18
- data/lib/pdk/validate/puppet/puppet_validator_group.rb +1 -1
- data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +10 -11
- data/lib/pdk/validate/ruby/ruby_validator_group.rb +1 -1
- data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +19 -24
- data/lib/pdk/validate/tasks/tasks_name_validator.rb +11 -13
- data/lib/pdk/validate/tasks/tasks_validator_group.rb +1 -1
- data/lib/pdk/validate/validator.rb +4 -2
- data/lib/pdk/validate/validator_group.rb +6 -3
- data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +27 -36
- data/lib/pdk/validate/yaml/yaml_validator_group.rb +1 -1
- data/lib/pdk/validate.rb +6 -6
- data/lib/pdk/version.rb +2 -2
- data/lib/pdk.rb +12 -12
- metadata +27 -35
- data/lib/pdk/cli/config/get.rb +0 -26
- data/lib/pdk/cli/config.rb +0 -22
- data/lib/pdk/cli/module/build.rb +0 -12
- data/lib/pdk/cli/module/generate.rb +0 -47
- data/lib/pdk/cli/module.rb +0 -14
data/lib/pdk/cli.rb
CHANGED
|
@@ -11,148 +11,152 @@ module TTY
|
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
module Cri
|
|
15
|
+
class Command
|
|
16
|
+
class CriExitException
|
|
17
|
+
def initialize(is_error:)
|
|
18
|
+
@is_error = is_error
|
|
19
|
+
PDK.analytics.event('CLI', 'invalid command', label: PDK::CLI.anonymised_args.join(' ')) if error?
|
|
20
|
+
end
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
module PDK
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
25
|
+
module PDK
|
|
26
|
+
module CLI
|
|
27
|
+
autoload :Util, 'pdk/cli/util'
|
|
28
|
+
|
|
29
|
+
# Attempt to anonymise the raw ARGV array if the command parsing failed.
|
|
30
|
+
#
|
|
31
|
+
# If an item does not start with '-' but is preceeded by an item that does
|
|
32
|
+
# start with '-', assume that these items are an option/value pair and redact
|
|
33
|
+
# the value. Any additional values that do not start with '-' that follow an
|
|
34
|
+
# option/value pair are assumed to be arguments (rather than subcommand
|
|
35
|
+
# names) and are also redacted.
|
|
36
|
+
#
|
|
37
|
+
# @example
|
|
38
|
+
# # Where PDK::CLI.args => ['new', 'plan', '--some', 'value', 'plan_name']
|
|
39
|
+
#
|
|
40
|
+
# PDK::CLI.anonymised_args
|
|
41
|
+
# => ['new', 'plan', '--some', 'redacted', 'redacted']
|
|
42
|
+
#
|
|
43
|
+
# @return Array[String] the command arguments with any identifying values
|
|
44
|
+
# redacted.
|
|
45
|
+
def self.anonymised_args
|
|
46
|
+
in_args = false
|
|
47
|
+
@args.map do |arg|
|
|
48
|
+
if arg.start_with?('-')
|
|
49
|
+
in_args = true
|
|
50
|
+
arg
|
|
51
|
+
else
|
|
52
|
+
in_args ? 'redacted' : arg
|
|
53
|
+
end
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
|
-
end
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
57
|
+
def self.run(args)
|
|
58
|
+
@args = args
|
|
59
|
+
PDK::Config.analytics_config_interview! unless PDK::Util::Env['PDK_DISABLE_ANALYTICS'] || PDK::Config.analytics_config_exist?
|
|
60
|
+
@base_cmd.run(args)
|
|
61
|
+
rescue PDK::CLI::ExitWithError => e
|
|
62
|
+
PDK.logger.send(e.log_level, e.message)
|
|
63
|
+
|
|
64
|
+
exit e.exit_code
|
|
65
|
+
rescue PDK::CLI::FatalError => e
|
|
66
|
+
PDK.logger.fatal(e.message) if e.message
|
|
67
|
+
|
|
68
|
+
# If FatalError was raised as the result of another exception, send the
|
|
69
|
+
# details of that exception to the debug log. If there was no cause
|
|
70
|
+
# (FatalError raised on its own outside a rescue block), send the details
|
|
71
|
+
# of the FatalError exception to the debug log.
|
|
72
|
+
cause = e.cause
|
|
73
|
+
if cause.nil?
|
|
74
|
+
e.backtrace.each { |line| PDK.logger.debug(line) }
|
|
75
|
+
else
|
|
76
|
+
PDK.logger.debug("#{cause.class}: #{cause.message}")
|
|
77
|
+
cause.backtrace.each { |line| PDK.logger.debug(line) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
exit e.exit_code
|
|
73
81
|
end
|
|
74
82
|
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
def self.template_url_option(dsl)
|
|
84
|
+
require 'pdk/util/template_uri'
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
require 'pdk/util/template_uri'
|
|
86
|
+
desc = format('Specifies the URL to the template to use when creating new modules or classes. (default: %{default_url})', default_url: PDK::Util::TemplateURI.default_template_uri)
|
|
80
87
|
|
|
81
|
-
|
|
88
|
+
dsl.option nil, 'template-url', desc, argument: :required
|
|
89
|
+
end
|
|
82
90
|
|
|
83
|
-
dsl
|
|
84
|
-
|
|
91
|
+
def self.template_ref_option(dsl)
|
|
92
|
+
dsl.option nil, 'template-ref', 'Specifies the template git branch or tag to use when creating new modules or classes.', argument: :required
|
|
93
|
+
end
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
def self.skip_interview_option(dsl)
|
|
96
|
+
dsl.option nil, 'skip-interview', 'When specified, skips interactive querying of metadata.'
|
|
97
|
+
end
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
def self.full_interview_option(dsl)
|
|
100
|
+
dsl.option nil, 'full-interview', 'When specified, interactive querying of metadata will include all optional questions.'
|
|
101
|
+
end
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
103
|
+
def self.puppet_version_options(dsl)
|
|
104
|
+
dsl.option nil, 'puppet-version', 'Puppet version to run tests or validations against.', argument: :required
|
|
105
|
+
dsl.option nil, 'pe-version', '(Deprecated) Puppet Enterprise version to run tests or validations against.', argument: :required
|
|
106
|
+
end
|
|
97
107
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
def self.puppet_dev_option(dsl)
|
|
109
|
+
dsl.option nil,
|
|
110
|
+
'puppet-dev',
|
|
111
|
+
'When specified, PDK will validate or test against the current Puppet source from github.com. To use this option, you must have network access to https://github.com.'
|
|
112
|
+
end
|
|
102
113
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
114
|
+
@base_cmd = Cri::Command.define do
|
|
115
|
+
name 'pdk'
|
|
116
|
+
usage 'pdk command [options]'
|
|
117
|
+
summary 'Puppet Development Kit'
|
|
118
|
+
description 'The shortest path to better modules.'
|
|
119
|
+
default_subcommand 'help'
|
|
108
120
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
description 'The shortest path to better modules.'
|
|
114
|
-
default_subcommand 'help'
|
|
121
|
+
flag nil, :version, 'Show version of pdk.' do |_, _|
|
|
122
|
+
puts PDK::Util::Version.version_string
|
|
123
|
+
exit 0
|
|
124
|
+
end
|
|
115
125
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
flag :h, :help, 'Show help for this command.' do |_, c|
|
|
127
|
+
puts c.help
|
|
128
|
+
exit 0
|
|
129
|
+
end
|
|
120
130
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
format_desc =
|
|
132
|
+
"Specify desired output format. Valid formats are '#{PDK::Report.formats.join("', '")}'. " \
|
|
133
|
+
'You may also specify a file to which the formatted output is sent, ' \
|
|
134
|
+
"for example: '--format=junit:report.xml'. This option may be specified " \
|
|
135
|
+
'multiple times if each option specifies a distinct target file.'
|
|
125
136
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"for example: '--format=junit:report.xml'. This option may be specified " \
|
|
130
|
-
'multiple times if each option specifies a distinct target file.'
|
|
137
|
+
option :f, :format, format_desc, argument: :required, multiple: true do |values|
|
|
138
|
+
PDK::CLI::Util::OptionNormalizer.report_formats(values.compact)
|
|
139
|
+
end
|
|
131
140
|
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
flag :d, :debug, 'Enable debug output.' do |_, _|
|
|
142
|
+
PDK.logger.enable_debug_output
|
|
143
|
+
end
|
|
134
144
|
end
|
|
135
145
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
require 'pdk/cli/bundle'
|
|
147
|
+
require 'pdk/cli/build'
|
|
148
|
+
require 'pdk/cli/convert'
|
|
149
|
+
require 'pdk/cli/env'
|
|
150
|
+
require 'pdk/cli/get'
|
|
151
|
+
require 'pdk/cli/new'
|
|
152
|
+
require 'pdk/cli/set'
|
|
153
|
+
require 'pdk/cli/test'
|
|
154
|
+
require 'pdk/cli/update'
|
|
155
|
+
require 'pdk/cli/validate'
|
|
156
|
+
# require 'pdk/cli/console' Temporarily disabled while we work on the puppet-debugger gem. It will be back soon! (CONT-1154)
|
|
157
|
+
require 'pdk/cli/release'
|
|
158
|
+
require 'pdk/cli/remove'
|
|
159
|
+
|
|
160
|
+
@base_cmd.add_command Cri::Command.new_basic_help
|
|
139
161
|
end
|
|
140
|
-
|
|
141
|
-
require 'pdk/cli/bundle'
|
|
142
|
-
require 'pdk/cli/build'
|
|
143
|
-
require 'pdk/cli/config'
|
|
144
|
-
require 'pdk/cli/convert'
|
|
145
|
-
require 'pdk/cli/env'
|
|
146
|
-
require 'pdk/cli/get'
|
|
147
|
-
require 'pdk/cli/new'
|
|
148
|
-
require 'pdk/cli/set'
|
|
149
|
-
require 'pdk/cli/test'
|
|
150
|
-
require 'pdk/cli/update'
|
|
151
|
-
require 'pdk/cli/validate'
|
|
152
|
-
require 'pdk/cli/module'
|
|
153
|
-
require 'pdk/cli/console'
|
|
154
|
-
require 'pdk/cli/release'
|
|
155
|
-
require 'pdk/cli/remove'
|
|
156
|
-
|
|
157
|
-
@base_cmd.add_command Cri::Command.new_basic_help
|
|
158
162
|
end
|
data/lib/pdk/config/ini_file.rb
CHANGED
|
@@ -15,6 +15,7 @@ module PDK
|
|
|
15
15
|
# @see PDK::Config::Namespace.parse_file
|
|
16
16
|
def parse_file(filename)
|
|
17
17
|
raise unless block_given?
|
|
18
|
+
|
|
18
19
|
data = load_data(filename)
|
|
19
20
|
return if data.nil? || data.empty?
|
|
20
21
|
|
|
@@ -39,11 +40,13 @@ module PDK
|
|
|
39
40
|
lines = ''
|
|
40
41
|
data.each do |name, value|
|
|
41
42
|
next if value.nil?
|
|
43
|
+
|
|
42
44
|
if value.is_a?(Hash)
|
|
43
45
|
# Hashes are an INI section
|
|
44
46
|
lines += "\n[#{name}]\n"
|
|
45
47
|
value.each do |child_name, child_value|
|
|
46
48
|
next if child_value.nil?
|
|
49
|
+
|
|
47
50
|
lines += "#{child_name} = #{munge_serialized_value(child_value)}\n"
|
|
48
51
|
end
|
|
49
52
|
else
|
|
@@ -59,12 +62,11 @@ module PDK
|
|
|
59
62
|
def munge_serialized_value(value)
|
|
60
63
|
value = value.to_s unless value.is_a?(String)
|
|
61
64
|
# Add enclosing quotes if there's a space in the value
|
|
62
|
-
value =
|
|
65
|
+
value = "\"#{value}\"" if value.include?(' ')
|
|
63
66
|
value
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
# Adapted from https://raw.githubusercontent.com/puppetlabs/puppet/6c257fc7827989c2af2901f974666f0f23611153/lib/puppet/settings/ini_file.rb
|
|
67
|
-
# rubocop:disable Style/RegexpLiteral
|
|
68
70
|
# rubocop:disable Style/PerlBackrefs
|
|
69
71
|
# rubocop:disable Style/RedundantSelf
|
|
70
72
|
# rubocop:disable Style/StringLiterals
|
|
@@ -177,7 +179,6 @@ module PDK
|
|
|
177
179
|
# rubocop:enable Style/StringLiterals
|
|
178
180
|
# rubocop:enable Style/RedundantSelf
|
|
179
181
|
# rubocop:enable Style/PerlBackrefs
|
|
180
|
-
# rubocop:enable Style/RegexpLiteral
|
|
181
182
|
end
|
|
182
183
|
end
|
|
183
184
|
end
|
|
@@ -8,6 +8,7 @@ module PDK
|
|
|
8
8
|
# @see PDK::Config::Setting.initialize
|
|
9
9
|
def initialize(_name, namespace, initial_value = nil)
|
|
10
10
|
raise 'The IniFileSetting object can only be created within the IniFile Namespace' unless namespace.is_a?(PDK::Config::IniFile)
|
|
11
|
+
|
|
11
12
|
super
|
|
12
13
|
validate!(initial_value) unless initial_value.nil?
|
|
13
14
|
end
|
|
@@ -18,20 +19,15 @@ module PDK
|
|
|
18
19
|
def validate!(value)
|
|
19
20
|
# We're very restrictive here. Realistically Ini files only have string types
|
|
20
21
|
return if value.nil? || value.is_a?(String) || value.is_a?(Integer)
|
|
22
|
+
|
|
21
23
|
# The only other valid-ish type is a Hash
|
|
22
|
-
unless value.is_a?(Hash)
|
|
23
|
-
|
|
24
|
-
key: qualified_name,
|
|
25
|
-
class: value.class,
|
|
26
|
-
}
|
|
27
|
-
end
|
|
24
|
+
raise ArgumentError, format('The setting %{key} may only be a String or Integer, not %{class}', key: qualified_name, class: value.class) unless value.is_a?(Hash)
|
|
25
|
+
|
|
28
26
|
# Any hashes can only have a single String/Integer value
|
|
29
27
|
value.each do |child_name, child_value|
|
|
30
28
|
next if child_value.nil? || child_value.is_a?(String) || child_value.is_a?(Integer)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class: child_value.class,
|
|
34
|
-
}
|
|
29
|
+
|
|
30
|
+
raise ArgumentError, format('The setting %{key} may only be a String or Integer, not %{class}', key: "#{qualified_name}.#{child_name}", class: child_value.class)
|
|
35
31
|
end
|
|
36
32
|
end
|
|
37
33
|
end
|
data/lib/pdk/config/json.rb
CHANGED
|
@@ -58,6 +58,7 @@ module PDK
|
|
|
58
58
|
# @return [String[]]
|
|
59
59
|
def schema_property_names
|
|
60
60
|
return [] if schema['properties'].nil?
|
|
61
|
+
|
|
61
62
|
schema['properties'].keys
|
|
62
63
|
end
|
|
63
64
|
|
|
@@ -119,23 +120,17 @@ module PDK
|
|
|
119
120
|
@document_schema = create_empty_schema
|
|
120
121
|
|
|
121
122
|
return @document_schema if @schema_file.nil?
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
file: @schema_file,
|
|
125
|
-
}
|
|
126
|
-
end
|
|
123
|
+
|
|
124
|
+
raise PDK::Config::LoadError, format('Unable to open %{file} for reading. File does not exist', file: @schema_file) unless PDK::Util::Filesystem.file?(@schema_file)
|
|
127
125
|
|
|
128
126
|
# The schema should not query external URI references, except for the meta-schema. Local files are allowed
|
|
129
127
|
schema_reader = ::JSON::Schema::Reader.new(
|
|
130
128
|
accept_file: true,
|
|
131
|
-
accept_uri:
|
|
129
|
+
accept_uri: proc { |uri| uri.host.nil? || ['json-schema.org'].include?(uri.host) }
|
|
132
130
|
)
|
|
133
131
|
@document_schema = schema_reader.read(Addressable::URI.convert_path(@schema_file))
|
|
134
132
|
rescue ::JSON::Schema::JsonParseError => e
|
|
135
|
-
raise PDK::Config::LoadError, 'Unable to open %{file} for reading. JSON Error: %{msg}'
|
|
136
|
-
file: @schema_file,
|
|
137
|
-
msg: e.message,
|
|
138
|
-
}
|
|
133
|
+
raise PDK::Config::LoadError, format('Unable to open %{file} for reading. JSON Error: %{msg}', file: @schema_file, msg: e.message)
|
|
139
134
|
end
|
|
140
135
|
end
|
|
141
136
|
end
|
|
@@ -8,6 +8,7 @@ module PDK
|
|
|
8
8
|
# @see PDK::Config::Setting.initialize
|
|
9
9
|
def initialize(_name, namespace, _initial_value)
|
|
10
10
|
raise 'The JSONSchemaSetting object can only be created within the JSONSchemaNamespace' unless namespace.is_a?(PDK::Config::JSONSchemaNamespace)
|
|
11
|
+
|
|
11
12
|
super
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -24,10 +25,7 @@ module PDK
|
|
|
24
25
|
# ... add validate it
|
|
25
26
|
namespace.validate_document!(new_document)
|
|
26
27
|
rescue ::JSON::Schema::ValidationError => e
|
|
27
|
-
raise ArgumentError, '%{key} %{message}'
|
|
28
|
-
key: qualified_name,
|
|
29
|
-
message: e.message,
|
|
30
|
-
}
|
|
28
|
+
raise ArgumentError, format('%{key} %{message}', key: qualified_name, message: e.message)
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
|
|
@@ -46,7 +44,7 @@ module PDK
|
|
|
46
44
|
end
|
|
47
45
|
# ... otherwise call the settings chain default
|
|
48
46
|
# and if that doesn't exist, just return nil
|
|
49
|
-
@previous_setting
|
|
47
|
+
@previous_setting&.default
|
|
50
48
|
end
|
|
51
49
|
end
|
|
52
50
|
end
|
|
@@ -8,6 +8,7 @@ module PDK
|
|
|
8
8
|
# @see PDK::Config::Namespace.parse_file
|
|
9
9
|
def parse_file(filename)
|
|
10
10
|
raise unless block_given?
|
|
11
|
+
|
|
11
12
|
data = load_data(filename)
|
|
12
13
|
data = '{}' if data.nil? || data.empty?
|
|
13
14
|
require 'json'
|
|
@@ -19,10 +20,7 @@ module PDK
|
|
|
19
20
|
# Ensure the parsed document is actually valid
|
|
20
21
|
validate_document!(@raw_data)
|
|
21
22
|
rescue ::JSON::Schema::ValidationError => e
|
|
22
|
-
raise PDK::Config::LoadError, 'The configuration file %{filename} is not valid: %{message}'
|
|
23
|
-
filename: filename,
|
|
24
|
-
message: e.message,
|
|
25
|
-
}
|
|
23
|
+
raise PDK::Config::LoadError, format('The configuration file %{filename} is not valid: %{message}', filename: filename, message: e.message)
|
|
26
24
|
end
|
|
27
25
|
|
|
28
26
|
schema_property_names.each do |key|
|
data/lib/pdk/config/namespace.rb
CHANGED
|
@@ -36,7 +36,7 @@ module PDK
|
|
|
36
36
|
@loaded_from_file = false
|
|
37
37
|
@read_only = false
|
|
38
38
|
|
|
39
|
-
instance_eval(&block) if
|
|
39
|
+
instance_eval(&block) if block
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# Pre-configure a value in the namespace.
|
|
@@ -50,7 +50,7 @@ module PDK
|
|
|
50
50
|
# @return [nil]
|
|
51
51
|
def setting(key, &block)
|
|
52
52
|
@settings[key.to_s] ||= default_setting_class.new(key.to_s, self)
|
|
53
|
-
@settings[key.to_s].instance_eval(&block) if
|
|
53
|
+
@settings[key.to_s].instance_eval(&block) if block
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Mount a provided [self] (or subclass) into the namespace.
|
|
@@ -66,9 +66,10 @@ module PDK
|
|
|
66
66
|
# @return [self] the mounted namespace.
|
|
67
67
|
def mount(key, obj, &block)
|
|
68
68
|
raise ArgumentError, 'Only PDK::Config::Namespace objects can be mounted into a namespace' unless obj.is_a?(PDK::Config::Namespace)
|
|
69
|
+
|
|
69
70
|
obj.parent = self
|
|
70
71
|
obj.name = key.to_s
|
|
71
|
-
obj.instance_eval(&block) if
|
|
72
|
+
obj.instance_eval(&block) if block
|
|
72
73
|
@mounts[key.to_s] = obj
|
|
73
74
|
end
|
|
74
75
|
|
|
@@ -98,9 +99,11 @@ module PDK
|
|
|
98
99
|
# Check if it's a setting, otherwise nil
|
|
99
100
|
return nil if settings[key.to_s].nil?
|
|
100
101
|
return settings[key.to_s].value unless settings[key.to_s].value.nil?
|
|
102
|
+
|
|
101
103
|
# Duplicate arrays and hashes so that they are isolated from changes being made
|
|
102
104
|
default_value = PDK::Util.deep_duplicate(settings[key.to_s].default)
|
|
103
105
|
return default_value if default_value.nil? || !@persistent_defaults
|
|
106
|
+
|
|
104
107
|
# Persist the default value
|
|
105
108
|
settings[key.to_s].value = default_value
|
|
106
109
|
save_data
|
|
@@ -125,6 +128,7 @@ module PDK
|
|
|
125
128
|
return @mounts[key.to_s] unless @mounts[key.to_s].nil?
|
|
126
129
|
# Check if it's a setting, otherwise default_value
|
|
127
130
|
return default_value if settings[key.to_s].nil?
|
|
131
|
+
|
|
128
132
|
# Check if has a value, otherwise default_value
|
|
129
133
|
settings[key.to_s].value.nil? ? default_value : settings[key.to_s].value
|
|
130
134
|
end
|
|
@@ -139,6 +143,7 @@ module PDK
|
|
|
139
143
|
def []=(key, value)
|
|
140
144
|
# You can't set the value of a mount
|
|
141
145
|
raise ArgumentError, 'Namespace mounts can not be set a value' unless @mounts[key.to_s].nil?
|
|
146
|
+
|
|
142
147
|
set_volatile_value(key, value)
|
|
143
148
|
# Persist the change
|
|
144
149
|
save_data
|
|
@@ -157,7 +162,7 @@ module PDK
|
|
|
157
162
|
new_hash = {}
|
|
158
163
|
settings.each_pair { |k, v| new_hash[k] = v.value }
|
|
159
164
|
@mounts.each_pair { |k, mount_point| new_hash[k] = mount_point.to_h if mount_point.include_in_parent? }
|
|
160
|
-
new_hash.delete_if { |
|
|
165
|
+
new_hash.delete_if { |_k, v| v.nil? } # rubocop :disable Style/CollectionCompact
|
|
161
166
|
new_hash
|
|
162
167
|
end
|
|
163
168
|
|
|
@@ -168,14 +173,14 @@ module PDK
|
|
|
168
173
|
def resolve(filter = nil)
|
|
169
174
|
resolved = {}
|
|
170
175
|
# Resolve the settings
|
|
171
|
-
settings.
|
|
176
|
+
settings.each_value do |setting|
|
|
172
177
|
setting_name = setting.qualified_name
|
|
173
178
|
if be_resolved?(setting_name, filter)
|
|
174
179
|
resolved[setting_name] = setting.value.nil? ? setting.default : setting.value
|
|
175
180
|
end
|
|
176
181
|
end
|
|
177
182
|
# Resolve the mounts
|
|
178
|
-
@mounts.
|
|
183
|
+
@mounts.each_value { |mount| resolved.merge!(mount.resolve(filter)) }
|
|
179
184
|
resolved
|
|
180
185
|
end
|
|
181
186
|
|
|
@@ -239,7 +244,8 @@ module PDK
|
|
|
239
244
|
def be_resolved?(name, filter = nil)
|
|
240
245
|
return true if filter.nil? # If we're not filtering, this value should always be resolved
|
|
241
246
|
return true if name == filter # If it's exactly the same name then it should be resolved
|
|
242
|
-
|
|
247
|
+
|
|
248
|
+
name.start_with?("#{filter}.") # If name is a subkey of the filter then it should be resolved
|
|
243
249
|
end
|
|
244
250
|
|
|
245
251
|
# @abstract Subclass and override {#parse_file} to implement parsing logic
|
|
@@ -273,6 +279,7 @@ module PDK
|
|
|
273
279
|
# Need to use `@settings` and `@mounts` here to stop recursive calls
|
|
274
280
|
return unless @mounts[key.to_s].nil?
|
|
275
281
|
return unless @settings[key.to_s].nil?
|
|
282
|
+
|
|
276
283
|
@settings[key.to_s] = default_setting_class.new(key.to_s, self, initial_value)
|
|
277
284
|
end
|
|
278
285
|
|
|
@@ -286,6 +293,7 @@ module PDK
|
|
|
286
293
|
def set_volatile_value(key, value)
|
|
287
294
|
# Need to use `settings` here to force the backing file to be loaded
|
|
288
295
|
return create_missing_setting(key, value) if settings[key.to_s].nil?
|
|
296
|
+
|
|
289
297
|
# Need to use `@settings` here to stop recursive calls from []=
|
|
290
298
|
@settings[key.to_s].value = value
|
|
291
299
|
end
|
|
@@ -305,9 +313,7 @@ module PDK
|
|
|
305
313
|
rescue Errno::ENOENT => e
|
|
306
314
|
raise PDK::Config::LoadError, e.message
|
|
307
315
|
rescue Errno::EACCES
|
|
308
|
-
raise PDK::Config::LoadError, 'Unable to open %{file} for reading'
|
|
309
|
-
file: filename,
|
|
310
|
-
}
|
|
316
|
+
raise PDK::Config::LoadError, format('Unable to open %{file} for reading', file: filename)
|
|
311
317
|
end
|
|
312
318
|
|
|
313
319
|
# Persist the contents of the namespace to disk.
|
|
@@ -328,9 +334,7 @@ module PDK
|
|
|
328
334
|
|
|
329
335
|
PDK::Util::Filesystem.write_file(file, serialize_data(to_h))
|
|
330
336
|
rescue Errno::EACCES
|
|
331
|
-
raise PDK::Config::LoadError, 'Unable to open %{file} for writing'
|
|
332
|
-
file: file,
|
|
333
|
-
}
|
|
337
|
+
raise PDK::Config::LoadError, format('Unable to open %{file} for writing', file: file)
|
|
334
338
|
rescue SystemCallError => e
|
|
335
339
|
raise PDK::Config::LoadError, e.message
|
|
336
340
|
end
|
|
@@ -340,8 +344,10 @@ module PDK
|
|
|
340
344
|
# @return [Hash<String => PDK::Config::Setting>] the contents of the namespace.
|
|
341
345
|
def settings
|
|
342
346
|
return @settings if @loaded_from_file
|
|
347
|
+
|
|
343
348
|
@loaded_from_file = true
|
|
344
349
|
return @settings if file.nil?
|
|
350
|
+
|
|
345
351
|
parse_file(file) do |key, parsed_setting|
|
|
346
352
|
# Create a settings chain if a setting already exists
|
|
347
353
|
parsed_setting.previous_setting = @settings[key] unless @settings[key].nil?
|
data/lib/pdk/config/setting.rb
CHANGED
|
@@ -96,10 +96,7 @@ module PDK
|
|
|
96
96
|
@validators.each do |validator|
|
|
97
97
|
next if validator[:proc].call(value)
|
|
98
98
|
|
|
99
|
-
raise ArgumentError, '%{key} %{message}'
|
|
100
|
-
key: qualified_name,
|
|
101
|
-
message: validator[:message],
|
|
102
|
-
}
|
|
99
|
+
raise ArgumentError, format('%{key} %{message}', key: qualified_name, message: validator[:message])
|
|
103
100
|
end
|
|
104
101
|
end
|
|
105
102
|
|
|
@@ -110,7 +107,8 @@ module PDK
|
|
|
110
107
|
#
|
|
111
108
|
# @return [nil]
|
|
112
109
|
def default_to(&block)
|
|
113
|
-
raise ArgumentError, 'must be passed a block' unless
|
|
110
|
+
raise ArgumentError, 'must be passed a block' unless block
|
|
111
|
+
|
|
114
112
|
@default_to = block
|
|
115
113
|
end
|
|
116
114
|
|
|
@@ -120,8 +118,9 @@ module PDK
|
|
|
120
118
|
# {#default_to}, or `nil` if the setting has no default.
|
|
121
119
|
def default
|
|
122
120
|
return @default_to.call if default_block?
|
|
121
|
+
|
|
123
122
|
# If there is a previous setting in the chain, use its default
|
|
124
|
-
@previous_setting
|
|
123
|
+
@previous_setting&.default
|
|
125
124
|
end
|
|
126
125
|
|
|
127
126
|
private
|