pdk 1.9.0 → 3.2.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 (163) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +744 -711
  3. data/README.md +23 -21
  4. data/lib/pdk/answer_file.rb +3 -112
  5. data/lib/pdk/bolt.rb +20 -0
  6. data/lib/pdk/cli/build.rb +51 -54
  7. data/lib/pdk/cli/bundle.rb +33 -29
  8. data/lib/pdk/cli/console.rb +148 -0
  9. data/lib/pdk/cli/convert.rb +46 -37
  10. data/lib/pdk/cli/env.rb +51 -0
  11. data/lib/pdk/cli/errors.rb +4 -3
  12. data/lib/pdk/cli/exec/command.rb +285 -0
  13. data/lib/pdk/cli/exec/interactive_command.rb +109 -0
  14. data/lib/pdk/cli/exec.rb +32 -201
  15. data/lib/pdk/cli/exec_group.rb +79 -43
  16. data/lib/pdk/cli/get/config.rb +26 -0
  17. data/lib/pdk/cli/get.rb +22 -0
  18. data/lib/pdk/cli/new/class.rb +20 -22
  19. data/lib/pdk/cli/new/defined_type.rb +21 -21
  20. data/lib/pdk/cli/new/fact.rb +27 -0
  21. data/lib/pdk/cli/new/function.rb +27 -0
  22. data/lib/pdk/cli/new/module.rb +40 -29
  23. data/lib/pdk/cli/new/provider.rb +18 -18
  24. data/lib/pdk/cli/new/task.rb +23 -22
  25. data/lib/pdk/cli/new/test.rb +52 -0
  26. data/lib/pdk/cli/new/transport.rb +27 -0
  27. data/lib/pdk/cli/new.rb +15 -9
  28. data/lib/pdk/cli/release/prep.rb +39 -0
  29. data/lib/pdk/cli/release/publish.rb +46 -0
  30. data/lib/pdk/cli/release.rb +185 -0
  31. data/lib/pdk/cli/remove/config.rb +83 -0
  32. data/lib/pdk/cli/remove.rb +22 -0
  33. data/lib/pdk/cli/set/config.rb +121 -0
  34. data/lib/pdk/cli/set.rb +22 -0
  35. data/lib/pdk/cli/test/unit.rb +71 -69
  36. data/lib/pdk/cli/test.rb +9 -8
  37. data/lib/pdk/cli/update.rb +38 -21
  38. data/lib/pdk/cli/util/command_redirector.rb +13 -3
  39. data/lib/pdk/cli/util/interview.rb +25 -9
  40. data/lib/pdk/cli/util/option_normalizer.rb +6 -6
  41. data/lib/pdk/cli/util/option_validator.rb +19 -9
  42. data/lib/pdk/cli/util/spinner.rb +13 -0
  43. data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
  44. data/lib/pdk/cli/util.rb +105 -48
  45. data/lib/pdk/cli/validate.rb +96 -111
  46. data/lib/pdk/cli.rb +134 -87
  47. data/lib/pdk/config/errors.rb +5 -0
  48. data/lib/pdk/config/ini_file.rb +184 -0
  49. data/lib/pdk/config/ini_file_setting.rb +35 -0
  50. data/lib/pdk/config/json.rb +35 -0
  51. data/lib/pdk/config/json_schema_namespace.rb +137 -0
  52. data/lib/pdk/config/json_schema_setting.rb +51 -0
  53. data/lib/pdk/config/json_with_schema.rb +47 -0
  54. data/lib/pdk/config/namespace.rb +362 -0
  55. data/lib/pdk/config/setting.rb +134 -0
  56. data/lib/pdk/config/task_schema.json +116 -0
  57. data/lib/pdk/config/validator.rb +31 -0
  58. data/lib/pdk/config/yaml.rb +41 -0
  59. data/lib/pdk/config/yaml_with_schema.rb +51 -0
  60. data/lib/pdk/config.rb +304 -0
  61. data/lib/pdk/context/control_repo.rb +61 -0
  62. data/lib/pdk/context/module.rb +28 -0
  63. data/lib/pdk/context/none.rb +22 -0
  64. data/lib/pdk/context.rb +98 -0
  65. data/lib/pdk/control_repo.rb +89 -0
  66. data/lib/pdk/generate/defined_type.rb +27 -33
  67. data/lib/pdk/generate/fact.rb +26 -0
  68. data/lib/pdk/generate/function.rb +49 -0
  69. data/lib/pdk/generate/module.rb +160 -153
  70. data/lib/pdk/generate/provider.rb +16 -69
  71. data/lib/pdk/generate/puppet_class.rb +27 -32
  72. data/lib/pdk/generate/puppet_object.rb +100 -159
  73. data/lib/pdk/generate/task.rb +34 -51
  74. data/lib/pdk/generate/transport.rb +34 -0
  75. data/lib/pdk/generate.rb +21 -8
  76. data/lib/pdk/logger.rb +24 -6
  77. data/lib/pdk/module/build.rb +125 -37
  78. data/lib/pdk/module/convert.rb +146 -65
  79. data/lib/pdk/module/metadata.rb +72 -71
  80. data/lib/pdk/module/release.rb +255 -0
  81. data/lib/pdk/module/update.rb +48 -37
  82. data/lib/pdk/module/update_manager.rb +75 -39
  83. data/lib/pdk/module.rb +10 -2
  84. data/lib/pdk/monkey_patches.rb +268 -0
  85. data/lib/pdk/report/event.rb +36 -48
  86. data/lib/pdk/report.rb +35 -22
  87. data/lib/pdk/template/fetcher/git.rb +84 -0
  88. data/lib/pdk/template/fetcher/local.rb +29 -0
  89. data/lib/pdk/template/fetcher.rb +100 -0
  90. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +108 -0
  91. data/lib/pdk/template/renderer/v1/renderer.rb +131 -0
  92. data/lib/pdk/template/renderer/v1/template_file.rb +100 -0
  93. data/lib/pdk/template/renderer/v1.rb +25 -0
  94. data/lib/pdk/template/renderer.rb +97 -0
  95. data/lib/pdk/template/template_dir.rb +67 -0
  96. data/lib/pdk/template.rb +52 -0
  97. data/lib/pdk/tests/unit.rb +101 -51
  98. data/lib/pdk/util/bundler.rb +44 -42
  99. data/lib/pdk/util/changelog_generator.rb +138 -0
  100. data/lib/pdk/util/env.rb +48 -0
  101. data/lib/pdk/util/filesystem.rb +139 -2
  102. data/lib/pdk/util/git.rb +108 -8
  103. data/lib/pdk/util/json_finder.rb +86 -0
  104. data/lib/pdk/util/puppet_strings.rb +125 -0
  105. data/lib/pdk/util/puppet_version.rb +71 -87
  106. data/lib/pdk/util/ruby_version.rb +49 -25
  107. data/lib/pdk/util/template_uri.rb +283 -0
  108. data/lib/pdk/util/vendored_file.rb +34 -42
  109. data/lib/pdk/util/version.rb +11 -10
  110. data/lib/pdk/util/windows/api_types.rb +74 -44
  111. data/lib/pdk/util/windows/file.rb +31 -27
  112. data/lib/pdk/util/windows/process.rb +74 -0
  113. data/lib/pdk/util/windows/string.rb +19 -12
  114. data/lib/pdk/util/windows.rb +2 -0
  115. data/lib/pdk/util.rb +111 -124
  116. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
  117. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
  118. data/lib/pdk/validate/external_command_validator.rb +213 -0
  119. data/lib/pdk/validate/internal_ruby_validator.rb +101 -0
  120. data/lib/pdk/validate/invokable_validator.rb +238 -0
  121. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +84 -0
  122. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +76 -0
  123. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
  124. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +131 -0
  125. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
  126. data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +38 -0
  127. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +135 -0
  128. data/lib/pdk/validate/puppet/puppet_validator_group.rb +22 -0
  129. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +79 -0
  130. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
  131. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +83 -0
  132. data/lib/pdk/validate/tasks/tasks_name_validator.rb +45 -0
  133. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
  134. data/lib/pdk/validate/validator.rb +120 -0
  135. data/lib/pdk/validate/validator_group.rb +107 -0
  136. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +86 -0
  137. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
  138. data/lib/pdk/validate.rb +86 -12
  139. data/lib/pdk/version.rb +2 -2
  140. data/lib/pdk.rb +60 -10
  141. metadata +138 -100
  142. data/lib/pdk/cli/module/build.rb +0 -14
  143. data/lib/pdk/cli/module/generate.rb +0 -45
  144. data/lib/pdk/cli/module.rb +0 -14
  145. data/lib/pdk/i18n.rb +0 -4
  146. data/lib/pdk/module/templatedir.rb +0 -321
  147. data/lib/pdk/template_file.rb +0 -95
  148. data/lib/pdk/validate/base_validator.rb +0 -215
  149. data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -86
  150. data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -109
  151. data/lib/pdk/validate/metadata_validator.rb +0 -30
  152. data/lib/pdk/validate/puppet/puppet_lint.rb +0 -67
  153. data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -112
  154. data/lib/pdk/validate/puppet_validator.rb +0 -30
  155. data/lib/pdk/validate/ruby/rubocop.rb +0 -77
  156. data/lib/pdk/validate/ruby_validator.rb +0 -29
  157. data/lib/pdk/validate/tasks/metadata_lint.rb +0 -126
  158. data/lib/pdk/validate/tasks/name.rb +0 -88
  159. data/lib/pdk/validate/tasks_validator.rb +0 -33
  160. data/lib/pdk/validate/yaml/syntax.rb +0 -109
  161. data/lib/pdk/validate/yaml_validator.rb +0 -31
  162. data/locales/config.yaml +0 -21
  163. data/locales/pdk.pot +0 -1291
@@ -1,321 +0,0 @@
1
- require 'yaml'
2
- require 'deep_merge'
3
- require 'pdk/util'
4
- require 'pdk/util/git'
5
- require 'pdk/cli/errors'
6
- require 'pdk/template_file'
7
-
8
- module PDK
9
- module Module
10
- class TemplateDir
11
- attr_accessor :module_metadata
12
-
13
- # Initialises the TemplateDir object with the path or URL to the template
14
- # and the block of code to run to be run while the template is available.
15
- #
16
- # The template directory is only guaranteed to be available on disk
17
- # within the scope of the block passed to this method.
18
- #
19
- # @param path_or_url [String] The path to a directory to use as the
20
- # template or a URL to a git repository.
21
- # @param module_metadata [Hash] A Hash containing the module metadata.
22
- # Defaults to an empty Hash.
23
- # @yieldparam self [PDK::Module::TemplateDir] The initialised object with
24
- # the template available on disk.
25
- #
26
- # @example Using a git repository as a template
27
- # PDK::Module::TemplateDir.new('https://github.com/puppetlabs/pdk-templates') do |t|
28
- # t.render do |filename, content|
29
- # File.open(filename, 'w') do |file|
30
- # file.write(content)
31
- # end
32
- # end
33
- # end
34
- #
35
- # @raise [ArgumentError] If no block is given to this method.
36
- # @raise [PDK::CLI::FatalError] (see #clone_repo)
37
- # @raise [ArgumentError] (see #validate_module_template!)
38
- #
39
- # @api public
40
- def initialize(path_or_url, module_metadata = {}, init = false)
41
- unless block_given?
42
- raise ArgumentError, _('%{class_name} must be initialized with a block.') % { class_name: self.class.name }
43
- end
44
-
45
- if PDK::Util::Git.repo?(path_or_url)
46
- @path = self.class.clone_template_repo(path_or_url)
47
- @repo = path_or_url
48
- else
49
- @path = path_or_url
50
- end
51
-
52
- @init = init
53
- @moduleroot_dir = File.join(@path, 'moduleroot')
54
- @moduleroot_init = File.join(@path, 'moduleroot_init')
55
- @dirs = [@moduleroot_dir]
56
- @dirs << @moduleroot_init if @init
57
- @object_dir = File.join(@path, 'object_templates')
58
-
59
- validate_module_template!
60
-
61
- @module_metadata = module_metadata
62
-
63
- yield self
64
- ensure
65
- # If we cloned a git repo to get the template, remove the clone once
66
- # we're done with it.
67
- if @repo
68
- FileUtils.remove_dir(@path)
69
- end
70
- end
71
-
72
- # Retrieve identifying metadata for the template.
73
- #
74
- # For git repositories, this will return the URL to the repository and
75
- # a reference to the HEAD.
76
- #
77
- # @return [Hash{String => String}] A hash of identifying metadata.
78
- #
79
- # @api public
80
- def metadata
81
- result = {
82
- 'pdk-version' => PDK::Util::Version.version_string,
83
- }
84
-
85
- result['template-url'] = @repo ? @repo : @path
86
-
87
- ref_result = PDK::Util::Git.git('--git-dir', File.join(@path, '.git'), 'describe', '--all', '--long', '--always')
88
- result['template-ref'] = ref_result[:stdout].strip if ref_result[:exit_code].zero?
89
-
90
- result
91
- end
92
-
93
- # Loop through the files in the template, yielding each rendered file to
94
- # the supplied block.
95
- #
96
- # @yieldparam dest_path [String] The path of the destination file,
97
- # relative to the root of the module.
98
- # @yieldparam dest_content [String] The rendered content of the
99
- # destination file.
100
- #
101
- # @raise [PDK::CLI::FatalError] If the template fails to render.
102
- #
103
- # @return [void]
104
- #
105
- # @api public
106
- def render
107
- PDK::Module::TemplateDir.files_in_template(@dirs).each do |template_file, template_loc|
108
- template_file = template_file.to_s
109
- PDK.logger.debug(_("Rendering '%{template}'...") % { template: template_file })
110
- dest_path = template_file.sub(%r{\.erb\Z}, '')
111
- config = config_for(dest_path)
112
- dest_status = :manage
113
-
114
- if config['unmanaged']
115
- dest_status = :unmanage
116
- elsif config['delete']
117
- dest_status = :delete
118
- else
119
- begin
120
- dest_content = PDK::TemplateFile.new(File.join(template_loc, template_file), configs: config, template_dir: self).render
121
- rescue => e
122
- error_msg = _(
123
- "Failed to render template '%{template}'\n" \
124
- '%{exception}: %{message}',
125
- ) % { template: template_file, exception: e.class, message: e.message }
126
- raise PDK::CLI::FatalError, error_msg
127
- end
128
- end
129
-
130
- yield dest_path, dest_content, dest_status
131
- end
132
- end
133
-
134
- # Searches the template directory for template files that can be used to
135
- # render files for the specified object type.
136
- #
137
- # @param object_type [Symbol] The object type, e.g. (`:class`,
138
- # `:defined_type`, `:fact`, etc).
139
- #
140
- # @return [Hash{Symbol => String}] if the templates are available in the
141
- # template dir, otherwise `nil`. The returned hash can contain two keys,
142
- # :object contains the path on disk to the template for the object, :spec
143
- # contains the path on disk to the template for the object's spec file
144
- # (if available).
145
- #
146
- # @api public
147
- def object_template_for(object_type)
148
- object_path = File.join(@object_dir, "#{object_type}.erb")
149
- type_path = File.join(@object_dir, "#{object_type}_type.erb")
150
- spec_path = File.join(@object_dir, "#{object_type}_spec.erb")
151
- type_spec_path = File.join(@object_dir, "#{object_type}_type_spec.erb")
152
-
153
- if File.file?(object_path) && File.readable?(object_path)
154
- result = { object: object_path }
155
- result[:type] = type_path if File.file?(type_path) && File.readable?(type_path)
156
- result[:spec] = spec_path if File.file?(spec_path) && File.readable?(spec_path)
157
- result[:type_spec] = type_spec_path if File.file?(type_spec_path) && File.readable?(type_spec_path)
158
- result
159
- else
160
- nil
161
- end
162
- end
163
-
164
- # Generate a hash of data to be used when rendering object templates.
165
- #
166
- # Read `config_defaults.yml` from the root of the template directory (if
167
- # it exists) build a hash of values from the value of the `:global`
168
- # key.
169
- #
170
- # @return [Hash] The data that will be available to the template via the
171
- # `@configs` instance variable.
172
- #
173
- # @api private
174
- def object_config
175
- config_for(nil)
176
- end
177
-
178
- # Validate the content of the template directory.
179
- #
180
- # @raise [ArgumentError] If the specified path is not a directory.
181
- # @raise [ArgumentError] If the template directory does not contain
182
- # a directory called 'moduleroot'.
183
- #
184
- # @return [void]
185
- #
186
- # @api private
187
- def validate_module_template!
188
- # rubocop:disable Style/GuardClause
189
- unless File.directory?(@path)
190
- if PDK::Util.package_install? && File.fnmatch?(File.join(PDK::Util.package_cachedir, '*'), @path)
191
- raise ArgumentError, _('The built-in template has substantially changed. Please run "pdk convert" on your module to continue.')
192
- else
193
- raise ArgumentError, _("The specified template '%{path}' is not a directory.") % { path: @path }
194
- end
195
- end
196
-
197
- unless File.directory?(@moduleroot_dir)
198
- raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot/' directory.") % { path: @path }
199
- end
200
-
201
- unless File.directory?(@moduleroot_init)
202
- # rubocop:disable Metrics/LineLength
203
- raise ArgumentError, _("The template at '%{path}' does not contain a 'moduleroot_init/' directory, which indicates you are using an older style of template. Before continuing please use the --template-url flag when running the pdk new commands to pass a new style template.") % { path: @path }
204
- # rubocop:enable Metrics/LineLength Style/GuardClause
205
- end
206
- end
207
-
208
- # Get a list of template files in the template directory.
209
- #
210
- # @return [Hash{String=>String}] A hash of key file names and
211
- # value locations.
212
- #
213
- # @api public
214
- def self.files_in_template(dirs)
215
- temp_paths = []
216
- dirlocs = []
217
- dirs.each do |dir|
218
- raise ArgumentError, _("The directory '%{dir}' doesn't exist") % { dir: dir } unless Dir.exist?(dir)
219
- temp_paths += Dir.glob(File.join(dir, '**', '*'), File::FNM_DOTMATCH).select do |template_path|
220
- if File.file?(template_path) && !File.symlink?(template_path)
221
- dirlocs << dir
222
- end
223
- end
224
- temp_paths.map do |template_path|
225
- template_path.sub!(%r{\A#{Regexp.escape(dir)}#{Regexp.escape(File::SEPARATOR)}}, '')
226
- end
227
- end
228
- Hash[temp_paths.zip dirlocs]
229
- end
230
-
231
- # Generate a hash of data to be used when rendering the specified
232
- # template.
233
- #
234
- # @param dest_path [String] The destination path of the file that the
235
- # data is for, relative to the root of the module.
236
- #
237
- # @return [Hash] The data that will be available to the template via the
238
- # `@configs` instance variable.
239
- #
240
- # @api private
241
- def config_for(dest_path, sync_config_path = nil)
242
- module_root = PDK::Util.module_root
243
- sync_config_path ||= File.join(module_root, '.sync.yml') unless module_root.nil?
244
- config_path = File.join(@path, 'config_defaults.yml')
245
-
246
- if @config.nil?
247
- conf_defaults = read_config(config_path)
248
- sync_config = read_config(sync_config_path) unless sync_config_path.nil?
249
- @config = conf_defaults
250
- @config.deep_merge!(sync_config, knockout_prefix: '---') unless sync_config.nil?
251
- end
252
- file_config = @config.fetch(:global, {})
253
- file_config['module_metadata'] = @module_metadata
254
- file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
255
- file_config.merge!(@config)
256
- end
257
-
258
- # Generates a hash of data from a given yaml file location.
259
- #
260
- # @param loc [String] The path of the yaml config file.
261
- #
262
- # @warn If the specified path is not a valid yaml file. Returns an empty Hash
263
- # if so.
264
- #
265
- # @return [Hash] The data that has been read in from the given yaml file.
266
- #
267
- # @api private
268
- def read_config(loc)
269
- if File.file?(loc) && File.readable?(loc)
270
- begin
271
- YAML.safe_load(File.read(loc), [], [], true)
272
- rescue Psych::SyntaxError => e
273
- PDK.logger.warn _("'%{file}' is not a valid YAML file: %{problem} %{context} at line %{line} column %{column}") % {
274
- file: loc,
275
- problem: e.problem,
276
- context: e.context,
277
- line: e.line,
278
- column: e.column,
279
- }
280
- {}
281
- end
282
- else
283
- {}
284
- end
285
- end
286
-
287
- # @return [String] Path to working directory into which template repo has been cloned and reset
288
- #
289
- # @raise [PDK::CLI::FatalError] If unable to clone the given origin_repo into a tempdir.
290
- # @raise [PDK::CLI::FatalError] If reset HEAD of the cloned repo to desired ref.
291
- #
292
- # @api private
293
- def self.clone_template_repo(origin_repo)
294
- # @todo When switching this over to using rugged, cache the cloned
295
- # template repo in `%AppData%` or `$XDG_CACHE_DIR` and update before
296
- # use.
297
- temp_dir = PDK::Util.make_tmpdir_name('pdk-templates')
298
- git_ref = (origin_repo == PDK::Util.default_template_url) ? PDK::Util.default_template_ref : 'origin/master'
299
-
300
- clone_result = PDK::Util::Git.git('clone', origin_repo, temp_dir)
301
-
302
- if clone_result[:exit_code].zero?
303
- Dir.chdir(temp_dir) do
304
- reset_result = PDK::Util::Git.git('reset', '--hard', git_ref)
305
- unless reset_result[:exit_code].zero?
306
- PDK.logger.error reset_result[:stdout]
307
- PDK.logger.error reset_result[:stderr]
308
- raise PDK::CLI::FatalError, _("Unable to set HEAD of git repository at '%{repo}' to ref:'%{ref}'.") % { repo: temp_dir, ref: git_ref }
309
- end
310
- end
311
- else
312
- PDK.logger.error clone_result[:stdout]
313
- PDK.logger.error clone_result[:stderr]
314
- raise PDK::CLI::FatalError, _("Unable to clone git repository at '%{repo}' into '%{dest}'.") % { repo: origin_repo, dest: temp_dir }
315
- end
316
-
317
- PDK::Util.canonical_path(temp_dir)
318
- end
319
- end
320
- end
321
- end
@@ -1,95 +0,0 @@
1
- require 'ostruct'
2
-
3
- module PDK
4
- class TemplateFile < OpenStruct
5
- # Initialises the TemplateFile object with the path to the template file
6
- # and the data to be used when rendering the template.
7
- #
8
- # @param template_file [String] The path on disk to the template file.
9
- # @param data [Hash{Symbol => Object}] The data that should be provided to
10
- # the template when rendering.
11
- # @option data [Object] :configs The value of this key will be provided to
12
- # the template as an instance variable `@configs` in order to maintain
13
- # compatibility with modulesync.
14
- #
15
- # @api public
16
- def initialize(template_file, data = {})
17
- @template_file = template_file
18
-
19
- if data.key?(:configs)
20
- @configs = data[:configs]
21
- end
22
-
23
- super(data)
24
- end
25
-
26
- # Renders the template by calling the appropriate engine based on the file
27
- # extension.
28
- #
29
- # If the template has an `.erb` extension, the content of the template
30
- # file will be treated as an ERB template. All other extensions are treated
31
- # as plain text.
32
- #
33
- # @return [String] The rendered template
34
- #
35
- # @raise (see #template_content)
36
- #
37
- # @api public
38
- def render
39
- case File.extname(@template_file)
40
- when '.erb'
41
- render_erb
42
- else
43
- render_plain
44
- end
45
- end
46
-
47
- def config_for(path)
48
- return nil unless respond_to?(:template_dir)
49
-
50
- template_dir.config_for(path)
51
- end
52
-
53
- private
54
-
55
- # Reads the content of the template file into memory.
56
- #
57
- # @return [String] The content of the template file.
58
- #
59
- # @raise [ArgumentError] If the template file does not exist or can not be
60
- # read.
61
- #
62
- # @api private
63
- def template_content
64
- if File.file?(@template_file) && File.readable?(@template_file)
65
- return File.read(@template_file)
66
- end
67
-
68
- raise ArgumentError, _("'%{template}' is not a readable file") % { template: @template_file }
69
- end
70
-
71
- # Renders the content of the template file as an ERB template.
72
- #
73
- # @return [String] The rendered template.
74
- #
75
- # @raise (see #template_content)
76
- #
77
- # @api private
78
- def render_erb
79
- renderer = ERB.new(template_content, nil, '-')
80
- renderer.filename = @template_file
81
- renderer.result(binding)
82
- end
83
-
84
- # Renders the content of the template file as plain text.
85
- #
86
- # @return [String] The rendered template.
87
- #
88
- # @raise (see #template_content)
89
- #
90
- # @api private
91
- def render_plain
92
- template_content
93
- end
94
- end
95
- end
@@ -1,215 +0,0 @@
1
- require 'pdk'
2
- require 'pdk/cli/exec'
3
- require 'pdk/module'
4
-
5
- module PDK
6
- module Validate
7
- class BaseValidator
8
- # Controls how many times the validator is invoked.
9
- #
10
- # :once - The validator will be invoked once and passed all the
11
- # targets.
12
- # :per_target - The validator will be invoked for each target
13
- # separately.
14
- INVOKE_STYLE = :once
15
-
16
- # Controls how the validator behaves if not passed any targets.
17
- #
18
- # true - PDK will not pass the globbed targets to the validator command
19
- # and it will instead rely on the underlying tool to find its
20
- # own default targets.
21
- # false - PDK will pass the globbed targets to the validator command.
22
- ALLOW_EMPTY_TARGETS = false
23
-
24
- IGNORE_DOTFILES = true
25
-
26
- def self.cmd_path
27
- File.join(PDK::Util.module_root, 'bin', cmd)
28
- end
29
-
30
- # Parses the target strings provided from the CLI
31
- #
32
- # @param options [Hash] A Hash containing the input options from the CLI.
33
- #
34
- # @return targets [Array] An Array of Strings containing target file paths
35
- # for the validator to validate.
36
- # @return skipped [Array] An Array of Strings containing targets
37
- # that are skipped due to target not containing
38
- # any files that can be validated by the validator.
39
- # @return invalid [Array] An Array of Strings containing targets that do
40
- # not exist, and will not be run by validator.
41
- def self.parse_targets(options)
42
- # If no targets are specified, then we will run validations from the
43
- # base module directory.
44
-
45
- targets = options.fetch(:targets, []).empty? ? [PDK::Util.module_root] : options[:targets]
46
-
47
- targets.map! { |r| r.gsub(File::ALT_SEPARATOR, File::SEPARATOR) } if File::ALT_SEPARATOR
48
- skipped = []
49
- invalid = []
50
- matched = targets.map { |target|
51
- if respond_to?(:pattern)
52
- if File.directory?(target)
53
- target_root = PDK::Util.module_root
54
- pattern_glob = Array(pattern).map { |p| Dir.glob(File.join(target_root, p), File::FNM_DOTMATCH) }
55
-
56
- target_list = pattern_glob.flatten.map do |file|
57
- if File.fnmatch(File.join(File.expand_path(target), '*'), file, File::FNM_DOTMATCH)
58
- Pathname.new(file).relative_path_from(Pathname.new(PDK::Util.module_root)).to_s
59
- end
60
- end
61
-
62
- ignore_list = ignore_pathspec
63
- target_list = target_list.reject { |file| ignore_list.match(file) }
64
-
65
- skipped << target if target_list.flatten.empty?
66
- target_list
67
- elsif File.file?(target)
68
- if Array(pattern).include? target
69
- target
70
- elsif Array(pattern).any? { |p| File.fnmatch(File.expand_path(p), File.expand_path(target), File::FNM_DOTMATCH) }
71
- target
72
- else
73
- skipped << target
74
- next
75
- end
76
- else
77
- invalid << target
78
- next
79
- end
80
- else
81
- target
82
- end
83
- }.compact.flatten
84
- [matched, skipped, invalid]
85
- end
86
-
87
- def self.ignore_pathspec
88
- ignore_pathspec = PDK::Module.default_ignored_pathspec(ignore_dotfiles?)
89
-
90
- if respond_to?(:pattern_ignore)
91
- Array(pattern_ignore).each do |pattern|
92
- ignore_pathspec.add(pattern)
93
- end
94
- end
95
-
96
- ignore_pathspec
97
- end
98
-
99
- def self.ignore_dotfiles?
100
- self::IGNORE_DOTFILES
101
- end
102
-
103
- def self.parse_options(_options, targets)
104
- targets
105
- end
106
-
107
- def self.spinner_text(_targets = nil)
108
- _('Invoking %{cmd}') % { cmd: cmd }
109
- end
110
-
111
- def self.process_skipped(report, skipped = [])
112
- skipped.each do |skipped_target|
113
- PDK.logger.debug(_('%{validator}: Skipped \'%{target}\'. Target does not contain any files to validate (%{pattern}).') % { validator: name, target: skipped_target, pattern: pattern })
114
- report.add_event(
115
- file: skipped_target,
116
- source: name,
117
- message: _('Target does not contain any files to validate (%{pattern}).') % { pattern: pattern },
118
- severity: :info,
119
- state: :skipped,
120
- )
121
- end
122
- end
123
-
124
- def self.process_invalid(report, invalid = [])
125
- invalid.each do |invalid_target|
126
- PDK.logger.debug(_('%{validator}: Skipped \'%{target}\'. Target file not found.') % { validator: name, target: invalid_target })
127
- report.add_event(
128
- file: invalid_target,
129
- source: name,
130
- message: _('File does not exist.'),
131
- severity: :error,
132
- state: :error,
133
- )
134
- end
135
- end
136
-
137
- def self.allow_empty_targets?
138
- self::ALLOW_EMPTY_TARGETS == true
139
- end
140
-
141
- def self.invoke(report, options = {})
142
- targets, skipped, invalid = parse_targets(options)
143
-
144
- process_skipped(report, skipped)
145
- process_invalid(report, invalid)
146
-
147
- return 0 if targets.empty?
148
-
149
- PDK::Util::Bundler.ensure_binstubs!(cmd)
150
-
151
- # If invoking :per_target, split the targets array into an array of
152
- # single element arrays (one per target). If invoking :once, wrap the
153
- # targets array in another array. This is so we can loop through the
154
- # invokes with the same logic, regardless of which invoke style is
155
- # needed.
156
- #
157
- if self::INVOKE_STYLE == :per_target
158
- targets = targets.combination(1).to_a
159
- else
160
- targets = targets.each_slice(1000).to_a
161
- options[:split_exec] = PDK::CLI::ExecGroup.new(spinner_text(targets), parallel: false)
162
- end
163
-
164
- if options.fetch(:targets, []).empty? && allow_empty_targets?
165
- targets = [[]]
166
- end
167
-
168
- exit_codes = []
169
-
170
- targets.each do |invokation_targets|
171
- cmd_argv = parse_options(options, invokation_targets).unshift(cmd_path).compact
172
- cmd_argv.unshift(File.join(PDK::Util::RubyVersion.bin_path, 'ruby.exe'), '-W0') if Gem.win_platform?
173
-
174
- command = PDK::CLI::Exec::Command.new(*cmd_argv).tap do |c|
175
- c.context = :module
176
- c.environment = { 'PUPPET_GEM_VERSION' => options[:puppet] } if options[:puppet]
177
- unless options[:split_exec]
178
- exec_group = options[:exec_group]
179
- if exec_group
180
- sub_spinner = exec_group.add_spinner(spinner_text(invokation_targets))
181
- c.register_spinner(sub_spinner)
182
- else
183
- c.add_spinner(spinner_text(invokation_targets))
184
- end
185
- end
186
- end
187
-
188
- if options[:split_exec]
189
- options[:split_exec].register do
190
- result = command.execute!
191
-
192
- begin
193
- parse_output(report, result, invokation_targets.compact)
194
- rescue PDK::Validate::ParseOutputError => e
195
- $stderr.puts e.message
196
- end
197
- result[:exit_code]
198
- end
199
- else
200
- result = command.execute!
201
- exit_codes << result[:exit_code]
202
-
203
- begin
204
- parse_output(report, result, invokation_targets.compact)
205
- rescue PDK::Validate::ParseOutputError => e
206
- $stderr.puts e.message
207
- end
208
- end
209
- end
210
-
211
- options.key?(:split_exec) ? options[:split_exec].exit_code : exit_codes.max
212
- end
213
- end
214
- end
215
- end