pdk 1.9.0 → 3.2.0

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