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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/README.md +2 -48
  4. data/lib/pdk/analytics/client/google_analytics.rb +22 -26
  5. data/lib/pdk/analytics/util.rb +0 -1
  6. data/lib/pdk/analytics.rb +1 -1
  7. data/lib/pdk/bolt.rb +1 -0
  8. data/lib/pdk/cli/build.rb +53 -56
  9. data/lib/pdk/cli/bundle.rb +34 -33
  10. data/lib/pdk/cli/console.rb +136 -134
  11. data/lib/pdk/cli/convert.rb +39 -41
  12. data/lib/pdk/cli/env.rb +49 -47
  13. data/lib/pdk/cli/errors.rb +1 -2
  14. data/lib/pdk/cli/exec/command.rb +23 -29
  15. data/lib/pdk/cli/exec/interactive_command.rb +7 -12
  16. data/lib/pdk/cli/exec.rb +4 -11
  17. data/lib/pdk/cli/exec_group.rb +3 -2
  18. data/lib/pdk/cli/get/config.rb +21 -19
  19. data/lib/pdk/cli/get.rb +15 -13
  20. data/lib/pdk/cli/new/class.rb +22 -22
  21. data/lib/pdk/cli/new/defined_type.rb +22 -22
  22. data/lib/pdk/cli/new/fact.rb +19 -19
  23. data/lib/pdk/cli/new/function.rb +20 -20
  24. data/lib/pdk/cli/new/module.rb +40 -38
  25. data/lib/pdk/cli/new/provider.rb +19 -19
  26. data/lib/pdk/cli/new/task.rb +23 -23
  27. data/lib/pdk/cli/new/test.rb +50 -48
  28. data/lib/pdk/cli/new/transport.rb +18 -18
  29. data/lib/pdk/cli/new.rb +11 -9
  30. data/lib/pdk/cli/release/prep.rb +27 -25
  31. data/lib/pdk/cli/release/publish.rb +39 -37
  32. data/lib/pdk/cli/release.rb +152 -149
  33. data/lib/pdk/cli/remove/config.rb +63 -60
  34. data/lib/pdk/cli/remove.rb +15 -13
  35. data/lib/pdk/cli/set/config.rb +91 -89
  36. data/lib/pdk/cli/set.rb +15 -13
  37. data/lib/pdk/cli/test/unit.rb +71 -69
  38. data/lib/pdk/cli/test.rb +9 -7
  39. data/lib/pdk/cli/update.rb +33 -38
  40. data/lib/pdk/cli/util/command_redirector.rb +10 -1
  41. data/lib/pdk/cli/util/interview.rb +11 -4
  42. data/lib/pdk/cli/util/option_normalizer.rb +2 -4
  43. data/lib/pdk/cli/util/option_validator.rb +7 -9
  44. data/lib/pdk/cli/util/update_manager_printer.rb +4 -4
  45. data/lib/pdk/cli/util.rb +32 -48
  46. data/lib/pdk/cli/validate.rb +98 -96
  47. data/lib/pdk/cli.rb +124 -120
  48. data/lib/pdk/config/ini_file.rb +4 -3
  49. data/lib/pdk/config/ini_file_setting.rb +6 -10
  50. data/lib/pdk/config/json.rb +1 -0
  51. data/lib/pdk/config/json_schema_namespace.rb +5 -10
  52. data/lib/pdk/config/json_schema_setting.rb +3 -5
  53. data/lib/pdk/config/json_with_schema.rb +2 -4
  54. data/lib/pdk/config/namespace.rb +19 -13
  55. data/lib/pdk/config/setting.rb +5 -6
  56. data/lib/pdk/config/task_schema.json +116 -0
  57. data/lib/pdk/config/validator.rb +4 -4
  58. data/lib/pdk/config/yaml.rb +3 -8
  59. data/lib/pdk/config/yaml_with_schema.rb +4 -12
  60. data/lib/pdk/config.rb +47 -51
  61. data/lib/pdk/context/control_repo.rb +3 -2
  62. data/lib/pdk/context/module.rb +2 -2
  63. data/lib/pdk/context/none.rb +2 -2
  64. data/lib/pdk/context.rb +4 -5
  65. data/lib/pdk/control_repo.rb +3 -4
  66. data/lib/pdk/generate/defined_type.rb +3 -3
  67. data/lib/pdk/generate/fact.rb +3 -2
  68. data/lib/pdk/generate/function.rb +5 -4
  69. data/lib/pdk/generate/module.rb +91 -106
  70. data/lib/pdk/generate/provider.rb +5 -4
  71. data/lib/pdk/generate/puppet_class.rb +3 -3
  72. data/lib/pdk/generate/puppet_object.rb +9 -12
  73. data/lib/pdk/generate/task.rb +11 -10
  74. data/lib/pdk/generate/transport.rb +8 -7
  75. data/lib/pdk/generate.rb +1 -1
  76. data/lib/pdk/logger.rb +3 -2
  77. data/lib/pdk/module/build.rb +34 -49
  78. data/lib/pdk/module/convert.rb +13 -22
  79. data/lib/pdk/module/metadata.rb +53 -61
  80. data/lib/pdk/module/release.rb +19 -25
  81. data/lib/pdk/module/update.rb +4 -13
  82. data/lib/pdk/module/update_manager.rb +18 -25
  83. data/lib/pdk/module.rb +1 -1
  84. data/lib/pdk/monkey_patches.rb +268 -0
  85. data/lib/pdk/report/event.rb +12 -37
  86. data/lib/pdk/report.rb +4 -4
  87. data/lib/pdk/template/fetcher/git.rb +7 -8
  88. data/lib/pdk/template/fetcher/local.rb +1 -0
  89. data/lib/pdk/template/fetcher.rb +4 -2
  90. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +4 -9
  91. data/lib/pdk/template/renderer/v1/renderer.rb +19 -20
  92. data/lib/pdk/template/renderer/v1/template_file.rb +4 -8
  93. data/lib/pdk/template/renderer/v1.rb +1 -1
  94. data/lib/pdk/template/renderer.rb +1 -0
  95. data/lib/pdk/template/template_dir.rb +3 -3
  96. data/lib/pdk/template.rb +2 -6
  97. data/lib/pdk/tests/unit.rb +36 -25
  98. data/lib/pdk/util/bundler.rb +10 -14
  99. data/lib/pdk/util/changelog_generator.rb +15 -12
  100. data/lib/pdk/util/env.rb +1 -0
  101. data/lib/pdk/util/filesystem.rb +18 -17
  102. data/lib/pdk/util/git.rb +16 -21
  103. data/lib/pdk/util/json_finder.rb +7 -6
  104. data/lib/pdk/util/puppet_strings.rb +1 -1
  105. data/lib/pdk/util/puppet_version.rb +16 -67
  106. data/lib/pdk/util/ruby_version.rb +9 -13
  107. data/lib/pdk/util/template_uri.rb +17 -29
  108. data/lib/pdk/util/vendored_file.rb +5 -18
  109. data/lib/pdk/util/windows/api_types.rb +70 -64
  110. data/lib/pdk/util/windows/file.rb +31 -27
  111. data/lib/pdk/util/windows/process.rb +59 -61
  112. data/lib/pdk/util/windows/string.rb +19 -12
  113. data/lib/pdk/util.rb +12 -20
  114. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +1 -1
  115. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +25 -25
  116. data/lib/pdk/validate/external_command_validator.rb +6 -1
  117. data/lib/pdk/validate/internal_ruby_validator.rb +5 -4
  118. data/lib/pdk/validate/invokable_validator.rb +30 -20
  119. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +12 -14
  120. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +13 -15
  121. data/lib/pdk/validate/metadata/metadata_validator_group.rb +1 -1
  122. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +16 -18
  123. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +14 -14
  124. data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +1 -1
  125. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +16 -18
  126. data/lib/pdk/validate/puppet/puppet_validator_group.rb +1 -1
  127. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +10 -11
  128. data/lib/pdk/validate/ruby/ruby_validator_group.rb +1 -1
  129. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +19 -24
  130. data/lib/pdk/validate/tasks/tasks_name_validator.rb +11 -13
  131. data/lib/pdk/validate/tasks/tasks_validator_group.rb +1 -1
  132. data/lib/pdk/validate/validator.rb +4 -2
  133. data/lib/pdk/validate/validator_group.rb +6 -3
  134. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +27 -36
  135. data/lib/pdk/validate/yaml/yaml_validator_group.rb +1 -1
  136. data/lib/pdk/validate.rb +6 -6
  137. data/lib/pdk/version.rb +2 -2
  138. data/lib/pdk.rb +12 -12
  139. metadata +27 -35
  140. data/lib/pdk/cli/config/get.rb +0 -26
  141. data/lib/pdk/cli/config.rb +0 -22
  142. data/lib/pdk/cli/module/build.rb +0 -12
  143. data/lib/pdk/cli/module/generate.rb +0 -47
  144. 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
- class Cri::Command::CriExitException
15
- def initialize(is_error:)
16
- @is_error = is_error
17
- PDK.analytics.event('CLI', 'invalid command', label: PDK::CLI.anonymised_args.join(' ')) if error?
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::CLI
22
- autoload :Util, 'pdk/cli/util'
23
-
24
- # Attempt to anonymise the raw ARGV array if the command parsing failed.
25
- #
26
- # If an item does not start with '-' but is preceeded by an item that does
27
- # start with '-', assume that these items are an option/value pair and redact
28
- # the value. Any additional values that do not start with '-' that follow an
29
- # option/value pair are assumed to be arguments (rather than subcommand
30
- # names) and are also redacted.
31
- #
32
- # @example
33
- # # Where PDK::CLI.args => ['new', 'plan', '--some', 'value', 'plan_name']
34
- #
35
- # PDK::CLI.anonymised_args
36
- # => ['new', 'plan', '--some', 'redacted', 'redacted']
37
- #
38
- # @return Array[String] the command arguments with any identifying values
39
- # redacted.
40
- def self.anonymised_args
41
- in_args = false
42
- @args.map do |arg|
43
- if arg.start_with?('-')
44
- in_args = true
45
- arg
46
- else
47
- in_args ? 'redacted' : arg
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
- def self.run(args)
53
- @args = args
54
- PDK::Config.analytics_config_interview! unless PDK::Util::Env['PDK_DISABLE_ANALYTICS'] || PDK::Config.analytics_config_exist?
55
- @base_cmd.run(args)
56
- rescue PDK::CLI::ExitWithError => e
57
- PDK.logger.send(e.log_level, e.message)
58
-
59
- exit e.exit_code
60
- rescue PDK::CLI::FatalError => e
61
- PDK.logger.fatal(e.message) if e.message
62
-
63
- # If FatalError was raised as the result of another exception, send the
64
- # details of that exception to the debug log. If there was no cause
65
- # (FatalError raised on its own outside a rescue block), send the details
66
- # of the FatalError exception to the debug log.
67
- cause = e.cause
68
- if cause.nil?
69
- e.backtrace.each { |line| PDK.logger.debug(line) }
70
- else
71
- PDK.logger.debug("#{cause.class}: #{cause.message}")
72
- cause.backtrace.each { |line| PDK.logger.debug(line) }
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
- exit e.exit_code
76
- end
83
+ def self.template_url_option(dsl)
84
+ require 'pdk/util/template_uri'
77
85
 
78
- def self.template_url_option(dsl)
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
- desc = '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 }
88
+ dsl.option nil, 'template-url', desc, argument: :required
89
+ end
82
90
 
83
- dsl.option nil, 'template-url', desc, argument: :required
84
- end
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
- def self.template_ref_option(dsl)
87
- dsl.option nil, 'template-ref', 'Specifies the template git branch or tag to use when creating new modules or classes.', argument: :required
88
- end
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
- def self.skip_interview_option(dsl)
91
- dsl.option nil, 'skip-interview', 'When specified, skips interactive querying of metadata.'
92
- end
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
- def self.full_interview_option(dsl)
95
- dsl.option nil, 'full-interview', 'When specified, interactive querying of metadata will include all optional questions.'
96
- end
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
- def self.puppet_version_options(dsl)
99
- dsl.option nil, 'puppet-version', 'Puppet version to run tests or validations against.', argument: :required
100
- dsl.option nil, 'pe-version', 'Puppet Enterprise version to run tests or validations against.', argument: :required
101
- end
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
- def self.puppet_dev_option(dsl)
104
- dsl.option nil,
105
- 'puppet-dev',
106
- '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.'
107
- end
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
- @base_cmd = Cri::Command.define do
110
- name 'pdk'
111
- usage 'pdk command [options]'
112
- summary 'Puppet Development Kit'
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
- flag nil, :version, 'Show version of pdk.' do |_, _|
117
- puts PDK::Util::Version.version_string
118
- exit 0
119
- end
126
+ flag :h, :help, 'Show help for this command.' do |_, c|
127
+ puts c.help
128
+ exit 0
129
+ end
120
130
 
121
- flag :h, :help, 'Show help for this command.' do |_, c|
122
- puts c.help
123
- exit 0
124
- end
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
- format_desc =
127
- "Specify desired output format. Valid formats are '#{PDK::Report.formats.join("', '")}'. " \
128
- 'You may also specify a file to which the formatted output is sent, ' \
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
- option :f, :format, format_desc, argument: :required, multiple: true do |values|
133
- PDK::CLI::Util::OptionNormalizer.report_formats(values.compact)
141
+ flag :d, :debug, 'Enable debug output.' do |_, _|
142
+ PDK.logger.enable_debug_output
143
+ end
134
144
  end
135
145
 
136
- flag :d, :debug, 'Enable debug output.' do |_, _|
137
- PDK.logger.enable_debug_output
138
- end
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
@@ -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 = '"' + value + '"' if value.include?(' ')
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
- raise ArgumentError, 'The setting %{key} may only be a String or Integer, not %{class}' % {
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
- raise ArgumentError, 'The setting %{key} may only be a String or Integer, not %{class}' % {
32
- key: qualified_name + '.' + child_name,
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
@@ -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
  return if data.nil? || data.empty?
13
14
 
@@ -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
- unless PDK::Util::Filesystem.file?(@schema_file)
123
- raise PDK::Config::LoadError, 'Unable to open %{file} for reading. File does not exist' % {
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: proc { |uri| uri.host.nil? || ['json-schema.org'].include?(uri.host) },
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.nil? ? nil : @previous_setting.default
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|
@@ -36,7 +36,7 @@ module PDK
36
36
  @loaded_from_file = false
37
37
  @read_only = false
38
38
 
39
- instance_eval(&block) if block_given?
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 block_given?
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 block_given?
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 { |_, v| v.nil? }
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.values.each do |setting|
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.values.each { |mount| resolved.merge!(mount.resolve(filter)) }
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
- name.start_with?(filter + '.') # If name is a subkey of the filter then it should be resolved
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?
@@ -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 block_given?
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.nil? ? nil : @previous_setting.default
123
+ @previous_setting&.default
125
124
  end
126
125
 
127
126
  private