pdk 1.9.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +744 -711
- data/README.md +23 -21
- data/lib/pdk/answer_file.rb +3 -112
- data/lib/pdk/bolt.rb +20 -0
- data/lib/pdk/cli/build.rb +51 -54
- data/lib/pdk/cli/bundle.rb +33 -29
- data/lib/pdk/cli/console.rb +148 -0
- data/lib/pdk/cli/convert.rb +46 -37
- data/lib/pdk/cli/env.rb +51 -0
- data/lib/pdk/cli/errors.rb +4 -3
- data/lib/pdk/cli/exec/command.rb +285 -0
- data/lib/pdk/cli/exec/interactive_command.rb +109 -0
- data/lib/pdk/cli/exec.rb +32 -201
- data/lib/pdk/cli/exec_group.rb +79 -43
- data/lib/pdk/cli/get/config.rb +26 -0
- data/lib/pdk/cli/get.rb +22 -0
- data/lib/pdk/cli/new/class.rb +20 -22
- data/lib/pdk/cli/new/defined_type.rb +21 -21
- data/lib/pdk/cli/new/fact.rb +27 -0
- data/lib/pdk/cli/new/function.rb +27 -0
- data/lib/pdk/cli/new/module.rb +40 -29
- data/lib/pdk/cli/new/provider.rb +18 -18
- data/lib/pdk/cli/new/task.rb +23 -22
- data/lib/pdk/cli/new/test.rb +52 -0
- data/lib/pdk/cli/new/transport.rb +27 -0
- data/lib/pdk/cli/new.rb +15 -9
- data/lib/pdk/cli/release/prep.rb +39 -0
- data/lib/pdk/cli/release/publish.rb +46 -0
- data/lib/pdk/cli/release.rb +185 -0
- data/lib/pdk/cli/remove/config.rb +83 -0
- data/lib/pdk/cli/remove.rb +22 -0
- data/lib/pdk/cli/set/config.rb +121 -0
- data/lib/pdk/cli/set.rb +22 -0
- data/lib/pdk/cli/test/unit.rb +71 -69
- data/lib/pdk/cli/test.rb +9 -8
- data/lib/pdk/cli/update.rb +38 -21
- data/lib/pdk/cli/util/command_redirector.rb +13 -3
- data/lib/pdk/cli/util/interview.rb +25 -9
- data/lib/pdk/cli/util/option_normalizer.rb +6 -6
- data/lib/pdk/cli/util/option_validator.rb +19 -9
- data/lib/pdk/cli/util/spinner.rb +13 -0
- data/lib/pdk/cli/util/update_manager_printer.rb +82 -0
- data/lib/pdk/cli/util.rb +105 -48
- data/lib/pdk/cli/validate.rb +96 -111
- data/lib/pdk/cli.rb +134 -87
- data/lib/pdk/config/errors.rb +5 -0
- data/lib/pdk/config/ini_file.rb +184 -0
- data/lib/pdk/config/ini_file_setting.rb +35 -0
- data/lib/pdk/config/json.rb +35 -0
- data/lib/pdk/config/json_schema_namespace.rb +137 -0
- data/lib/pdk/config/json_schema_setting.rb +51 -0
- data/lib/pdk/config/json_with_schema.rb +47 -0
- data/lib/pdk/config/namespace.rb +362 -0
- data/lib/pdk/config/setting.rb +134 -0
- data/lib/pdk/config/task_schema.json +116 -0
- data/lib/pdk/config/validator.rb +31 -0
- data/lib/pdk/config/yaml.rb +41 -0
- data/lib/pdk/config/yaml_with_schema.rb +51 -0
- data/lib/pdk/config.rb +304 -0
- data/lib/pdk/context/control_repo.rb +61 -0
- data/lib/pdk/context/module.rb +28 -0
- data/lib/pdk/context/none.rb +22 -0
- data/lib/pdk/context.rb +98 -0
- data/lib/pdk/control_repo.rb +89 -0
- data/lib/pdk/generate/defined_type.rb +27 -33
- data/lib/pdk/generate/fact.rb +26 -0
- data/lib/pdk/generate/function.rb +49 -0
- data/lib/pdk/generate/module.rb +160 -153
- data/lib/pdk/generate/provider.rb +16 -69
- data/lib/pdk/generate/puppet_class.rb +27 -32
- data/lib/pdk/generate/puppet_object.rb +100 -159
- data/lib/pdk/generate/task.rb +34 -51
- data/lib/pdk/generate/transport.rb +34 -0
- data/lib/pdk/generate.rb +21 -8
- data/lib/pdk/logger.rb +24 -6
- data/lib/pdk/module/build.rb +125 -37
- data/lib/pdk/module/convert.rb +146 -65
- data/lib/pdk/module/metadata.rb +72 -71
- data/lib/pdk/module/release.rb +255 -0
- data/lib/pdk/module/update.rb +48 -37
- data/lib/pdk/module/update_manager.rb +75 -39
- data/lib/pdk/module.rb +10 -2
- data/lib/pdk/monkey_patches.rb +268 -0
- data/lib/pdk/report/event.rb +36 -48
- data/lib/pdk/report.rb +35 -22
- data/lib/pdk/template/fetcher/git.rb +84 -0
- data/lib/pdk/template/fetcher/local.rb +29 -0
- data/lib/pdk/template/fetcher.rb +100 -0
- data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +108 -0
- data/lib/pdk/template/renderer/v1/renderer.rb +131 -0
- data/lib/pdk/template/renderer/v1/template_file.rb +100 -0
- data/lib/pdk/template/renderer/v1.rb +25 -0
- data/lib/pdk/template/renderer.rb +97 -0
- data/lib/pdk/template/template_dir.rb +67 -0
- data/lib/pdk/template.rb +52 -0
- data/lib/pdk/tests/unit.rb +101 -51
- data/lib/pdk/util/bundler.rb +44 -42
- data/lib/pdk/util/changelog_generator.rb +138 -0
- data/lib/pdk/util/env.rb +48 -0
- data/lib/pdk/util/filesystem.rb +139 -2
- data/lib/pdk/util/git.rb +108 -8
- data/lib/pdk/util/json_finder.rb +86 -0
- data/lib/pdk/util/puppet_strings.rb +125 -0
- data/lib/pdk/util/puppet_version.rb +71 -87
- data/lib/pdk/util/ruby_version.rb +49 -25
- data/lib/pdk/util/template_uri.rb +283 -0
- data/lib/pdk/util/vendored_file.rb +34 -42
- data/lib/pdk/util/version.rb +11 -10
- data/lib/pdk/util/windows/api_types.rb +74 -44
- data/lib/pdk/util/windows/file.rb +31 -27
- data/lib/pdk/util/windows/process.rb +74 -0
- data/lib/pdk/util/windows/string.rb +19 -12
- data/lib/pdk/util/windows.rb +2 -0
- data/lib/pdk/util.rb +111 -124
- data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -0
- data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -0
- data/lib/pdk/validate/external_command_validator.rb +213 -0
- data/lib/pdk/validate/internal_ruby_validator.rb +101 -0
- data/lib/pdk/validate/invokable_validator.rb +238 -0
- data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +84 -0
- data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +76 -0
- data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -0
- data/lib/pdk/validate/puppet/puppet_epp_validator.rb +131 -0
- data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -0
- data/lib/pdk/validate/puppet/puppet_plan_syntax_validator.rb +38 -0
- data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +135 -0
- data/lib/pdk/validate/puppet/puppet_validator_group.rb +22 -0
- data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +79 -0
- data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -0
- data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +83 -0
- data/lib/pdk/validate/tasks/tasks_name_validator.rb +45 -0
- data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -0
- data/lib/pdk/validate/validator.rb +120 -0
- data/lib/pdk/validate/validator_group.rb +107 -0
- data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +86 -0
- data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -0
- data/lib/pdk/validate.rb +86 -12
- data/lib/pdk/version.rb +2 -2
- data/lib/pdk.rb +60 -10
- metadata +138 -100
- data/lib/pdk/cli/module/build.rb +0 -14
- data/lib/pdk/cli/module/generate.rb +0 -45
- data/lib/pdk/cli/module.rb +0 -14
- data/lib/pdk/i18n.rb +0 -4
- data/lib/pdk/module/templatedir.rb +0 -321
- data/lib/pdk/template_file.rb +0 -95
- data/lib/pdk/validate/base_validator.rb +0 -215
- data/lib/pdk/validate/metadata/metadata_json_lint.rb +0 -86
- data/lib/pdk/validate/metadata/metadata_syntax.rb +0 -109
- data/lib/pdk/validate/metadata_validator.rb +0 -30
- data/lib/pdk/validate/puppet/puppet_lint.rb +0 -67
- data/lib/pdk/validate/puppet/puppet_syntax.rb +0 -112
- data/lib/pdk/validate/puppet_validator.rb +0 -30
- data/lib/pdk/validate/ruby/rubocop.rb +0 -77
- data/lib/pdk/validate/ruby_validator.rb +0 -29
- data/lib/pdk/validate/tasks/metadata_lint.rb +0 -126
- data/lib/pdk/validate/tasks/name.rb +0 -88
- data/lib/pdk/validate/tasks_validator.rb +0 -33
- data/lib/pdk/validate/yaml/syntax.rb +0 -109
- data/lib/pdk/validate/yaml_validator.rb +0 -31
- data/locales/config.yaml +0 -21
- data/locales/pdk.pot +0 -1291
data/lib/pdk/report/event.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'pathname'
|
1
|
+
require 'pdk'
|
3
2
|
|
4
3
|
module PDK
|
5
4
|
class Report
|
@@ -54,7 +53,7 @@ module PDK
|
|
54
53
|
# @raise [ArgumentError] (see #sanitise_data)
|
55
54
|
def initialize(data)
|
56
55
|
sanitise_data(data).each do |key, value|
|
57
|
-
instance_variable_set("@#{key}", value)
|
56
|
+
instance_variable_set(:"@#{key}", value)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
@@ -99,7 +98,7 @@ module PDK
|
|
99
98
|
# results.
|
100
99
|
def rspec_puppet_coverage?
|
101
100
|
@rspec_puppet_coverage_pattern ||= File.join('**', 'lib', 'rspec-puppet', 'coverage.rb')
|
102
|
-
source == 'rspec' &&
|
101
|
+
source == 'rspec' && PDK::Util::Filesystem.fnmatch?(@rspec_puppet_coverage_pattern, PDK::Util::Filesystem.expand_path(file))
|
103
102
|
end
|
104
103
|
|
105
104
|
# Renders the event in a clang style text format.
|
@@ -112,8 +111,8 @@ module PDK
|
|
112
111
|
location = nil if location.empty?
|
113
112
|
|
114
113
|
# TODO: maybe add trace
|
115
|
-
header = [severity, source, location, message].compact.join(': ')
|
116
114
|
if source == 'rspec'
|
115
|
+
header = [severity, source, location, message].compact.join(': ')
|
117
116
|
result = [header, " #{test}"]
|
118
117
|
context = context_lines
|
119
118
|
unless context.nil?
|
@@ -124,7 +123,13 @@ module PDK
|
|
124
123
|
|
125
124
|
result.compact.join("\n")
|
126
125
|
else
|
127
|
-
|
126
|
+
output = ['pdk']
|
127
|
+
output << "(#{severity.upcase}):" unless severity.nil?
|
128
|
+
output << "#{source}:" unless source.nil?
|
129
|
+
output << message unless message.nil?
|
130
|
+
output << "(#{location})" unless location.nil?
|
131
|
+
|
132
|
+
output.join(' ')
|
128
133
|
end
|
129
134
|
end
|
130
135
|
|
@@ -132,6 +137,8 @@ module PDK
|
|
132
137
|
#
|
133
138
|
# @return [REXML::Element] The rendered event.
|
134
139
|
def to_junit
|
140
|
+
require 'rexml/document'
|
141
|
+
|
135
142
|
testcase = REXML::Element.new('testcase')
|
136
143
|
testcase.attributes['classname'] = [source, test].compact.join('.')
|
137
144
|
testcase.attributes['name'] = [file, line, column].compact.join(':')
|
@@ -187,13 +194,12 @@ module PDK
|
|
187
194
|
# @raise [ArgumentError] if the value is nil, an empty String, or not
|
188
195
|
# a String.
|
189
196
|
def sanitise_file(value)
|
190
|
-
if value.nil? || (value.is_a?(String) && value.empty?)
|
191
|
-
raise ArgumentError, _('File not specified.')
|
192
|
-
end
|
197
|
+
raise ArgumentError, 'File not specified.' if value.nil? || (value.is_a?(String) && value.empty?)
|
193
198
|
|
194
|
-
unless value.is_a?(String)
|
195
|
-
|
196
|
-
|
199
|
+
raise ArgumentError, 'File must be a String.' unless value.is_a?(String)
|
200
|
+
|
201
|
+
require 'pathname'
|
202
|
+
require 'pdk/util'
|
197
203
|
|
198
204
|
path = Pathname.new(value)
|
199
205
|
|
@@ -224,22 +230,13 @@ module PDK
|
|
224
230
|
# @raise [ArgumentError] if the value is nil, an empty String, or not
|
225
231
|
# a String or Symbol representation of a valid state.
|
226
232
|
def sanitise_state(value)
|
227
|
-
if value.nil? || (value.is_a?(String) && value.empty?)
|
228
|
-
raise ArgumentError, _('State not specified.')
|
229
|
-
end
|
233
|
+
raise ArgumentError, 'State not specified.' if value.nil? || (value.is_a?(String) && value.empty?)
|
230
234
|
|
231
235
|
value = value.to_sym if value.is_a?(String)
|
232
|
-
unless value.is_a?(Symbol)
|
233
|
-
raise ArgumentError, _('State must be a Symbol, not %{type}') % { type: value.class }
|
234
|
-
end
|
236
|
+
raise ArgumentError, format('State must be a Symbol, not %{type}', type: value.class) unless value.is_a?(Symbol)
|
235
237
|
|
236
238
|
valid_states = [:passed, :error, :failure, :skipped]
|
237
|
-
unless valid_states.include?(value)
|
238
|
-
raise ArgumentError, _('Invalid state %{state}. Valid states are: %{valid}.') % {
|
239
|
-
state: value.inspect,
|
240
|
-
valid: valid_states.map(&:inspect).join(', '),
|
241
|
-
}
|
242
|
-
end
|
239
|
+
raise ArgumentError, format('Invalid state %{state}. Valid states are: %{valid}.', state: value.inspect, valid: valid_states.map(&:inspect).join(', ')) unless valid_states.include?(value)
|
243
240
|
|
244
241
|
value
|
245
242
|
end
|
@@ -253,9 +250,7 @@ module PDK
|
|
253
250
|
#
|
254
251
|
# @raise [ArgumentError] if the value is nil or an empty String.
|
255
252
|
def sanitise_source(value)
|
256
|
-
if value.nil? || (value.is_a?(String) && value.empty?)
|
257
|
-
raise ArgumentError, _('Source not specified.')
|
258
|
-
end
|
253
|
+
raise ArgumentError, 'Source not specified.' if value.nil? || (value.is_a?(String) && value.empty?)
|
259
254
|
|
260
255
|
value.to_s
|
261
256
|
end
|
@@ -267,20 +262,16 @@ module PDK
|
|
267
262
|
# @return [Integer] the provided value, converted into an Integer if
|
268
263
|
# necessary.
|
269
264
|
def sanitise_line(value)
|
270
|
-
return
|
265
|
+
return if value.nil?
|
271
266
|
|
272
267
|
valid_types = [String, Integer]
|
273
268
|
if RUBY_VERSION.split('.')[0..1].join('.').to_f < 2.4
|
274
269
|
valid_types << Fixnum # rubocop:disable Lint/UnifiedInteger
|
275
270
|
end
|
276
271
|
|
277
|
-
unless valid_types.include?(value.class)
|
278
|
-
raise ArgumentError, _('Line must be an Integer or a String representation of an Integer.')
|
279
|
-
end
|
272
|
+
raise ArgumentError, 'Line must be an Integer or a String representation of an Integer.' unless valid_types.include?(value.class)
|
280
273
|
|
281
|
-
if value.is_a?(String) && value !~
|
282
|
-
raise ArgumentError, _('The line number can contain only the digits 0-9.')
|
283
|
-
end
|
274
|
+
raise ArgumentError, 'The line number can contain only the digits 0-9.' if value.is_a?(String) && value !~ /\A[0-9]+\Z/
|
284
275
|
|
285
276
|
value.to_i
|
286
277
|
end
|
@@ -292,20 +283,16 @@ module PDK
|
|
292
283
|
# @return [Integer] the provided value, converted into an Integer if
|
293
284
|
# necessary.
|
294
285
|
def sanitise_column(value)
|
295
|
-
return
|
286
|
+
return if value.nil?
|
296
287
|
|
297
288
|
valid_types = [String, Integer]
|
298
289
|
if RUBY_VERSION.split('.')[0..1].join('.').to_f < 2.4
|
299
290
|
valid_types << Fixnum # rubocop:disable Lint/UnifiedInteger
|
300
291
|
end
|
301
292
|
|
302
|
-
unless valid_types.include?(value.class)
|
303
|
-
raise ArgumentError, _('Column must be an Integer or a String representation of an Integer.')
|
304
|
-
end
|
293
|
+
raise ArgumentError, 'Column must be an Integer or a String representation of an Integer.' unless valid_types.include?(value.class)
|
305
294
|
|
306
|
-
if value.is_a?(String) && value !~
|
307
|
-
raise ArgumentError, _('The column number can contain only the digits 0-9.')
|
308
|
-
end
|
295
|
+
raise ArgumentError, 'The column number can contain only the digits 0-9.' if value.is_a?(String) && value !~ /\A[0-9]+\Z/
|
309
296
|
|
310
297
|
value.to_i
|
311
298
|
end
|
@@ -317,18 +304,16 @@ module PDK
|
|
317
304
|
#
|
318
305
|
# @return [Array] Array of stack trace lines with less relevant lines excluded
|
319
306
|
def sanitise_trace(value)
|
320
|
-
return
|
307
|
+
return if value.nil?
|
321
308
|
|
322
309
|
valid_types = [Array]
|
323
310
|
|
324
|
-
unless valid_types.include?(value.class)
|
325
|
-
raise ArgumentError, _('Trace must be an Array of stack trace lines.')
|
326
|
-
end
|
311
|
+
raise ArgumentError, 'Trace must be an Array of stack trace lines.' unless valid_types.include?(value.class)
|
327
312
|
|
328
313
|
# Drop any stacktrace lines that include '/gems/' in the path or
|
329
314
|
# are the original rspec binstub lines
|
330
315
|
value.reject do |line|
|
331
|
-
(
|
316
|
+
line.include?('/gems/') || line.include?('bin/rspec:')
|
332
317
|
end
|
333
318
|
end
|
334
319
|
|
@@ -342,10 +327,13 @@ module PDK
|
|
342
327
|
def context_lines(max_num_lines = 5)
|
343
328
|
return if file.nil? || line.nil?
|
344
329
|
|
345
|
-
file_path = [file, File.join(PDK::Util.module_root, file)].find
|
330
|
+
file_path = [file, File.join(PDK::Util.module_root, file)].find do |path|
|
331
|
+
PDK::Util::Filesystem.file?(path)
|
332
|
+
end
|
333
|
+
|
346
334
|
return if file_path.nil?
|
347
335
|
|
348
|
-
file_content =
|
336
|
+
file_content = PDK::Util::Filesystem.read_file(file_path).split("\n")
|
349
337
|
delta = (max_num_lines - 1) / 2
|
350
338
|
min = [0, (line - 1) - delta].max
|
351
339
|
max = [(line - 1) + delta, file_content.length].min
|
data/lib/pdk/report.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
require '
|
2
|
-
require 'time'
|
3
|
-
require 'pdk/report/event'
|
4
|
-
require 'socket'
|
1
|
+
require 'pdk'
|
5
2
|
|
6
3
|
module PDK
|
7
4
|
class Report
|
5
|
+
autoload :Event, 'pdk/report/event'
|
6
|
+
|
8
7
|
# @return [Array<String>] the list of supported report formats.
|
9
8
|
def self.formats
|
10
|
-
@report_formats ||=
|
9
|
+
@report_formats ||= ['junit', 'text'].freeze
|
11
10
|
end
|
12
11
|
|
13
12
|
# @return [Symbol] the method name of the default report format.
|
@@ -48,8 +47,9 @@ module PDK
|
|
48
47
|
# @param target [#write] an IO object that the report will be written to.
|
49
48
|
# Defaults to PDK::Report.default_target.
|
50
49
|
def write_junit(target = self.class.default_target)
|
51
|
-
|
52
|
-
|
50
|
+
require 'rexml/document'
|
51
|
+
require 'time'
|
52
|
+
require 'socket'
|
53
53
|
|
54
54
|
document = REXML::Document.new
|
55
55
|
document << REXML::XMLDecl.new
|
@@ -60,9 +60,9 @@ module PDK
|
|
60
60
|
testsuite = REXML::Element.new('testsuite')
|
61
61
|
testsuite.attributes['name'] = testsuite_name
|
62
62
|
testsuite.attributes['tests'] = testcases.length
|
63
|
-
testsuite.attributes['errors'] = testcases.
|
64
|
-
testsuite.attributes['failures'] = testcases.
|
65
|
-
testsuite.attributes['skipped'] = testcases.
|
63
|
+
testsuite.attributes['errors'] = testcases.count(&:error?)
|
64
|
+
testsuite.attributes['failures'] = testcases.count(&:failure?)
|
65
|
+
testsuite.attributes['skipped'] = testcases.count(&:skipped?)
|
66
66
|
testsuite.attributes['time'] = 0
|
67
67
|
testsuite.attributes['timestamp'] = Time.now.strftime('%Y-%m-%dT%H:%M:%S')
|
68
68
|
testsuite.attributes['hostname'] = Socket.gethostname
|
@@ -78,9 +78,14 @@ module PDK
|
|
78
78
|
end
|
79
79
|
|
80
80
|
document.elements << testsuites
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
report = ''
|
82
|
+
document.write(report, 2)
|
83
|
+
|
84
|
+
if target.is_a?(String)
|
85
|
+
PDK::Util::Filesystem.write_file(target, report)
|
86
|
+
else
|
87
|
+
target << report
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
# Renders the report as plain text.
|
@@ -88,25 +93,33 @@ module PDK
|
|
88
93
|
# This report is designed for interactive use by a human and so excludes
|
89
94
|
# all passing events in order to be consise.
|
90
95
|
#
|
91
|
-
# @param target [
|
92
|
-
#
|
96
|
+
# @param target [String, IO] The IO target to write the report to.
|
97
|
+
# If a String is provided, the report will be written to a file with the given path.
|
98
|
+
# If an IO object is provided, the report will be written to the IO object.
|
99
|
+
# If no target is provided, the default target PDK::Report.default_target will be used.
|
100
|
+
#
|
101
|
+
# @return [void]
|
93
102
|
def write_text(target = self.class.default_target)
|
94
|
-
# Open a File Object for IO if target is a string containing a filename or path
|
95
|
-
target = File.open(target, 'w') if target.is_a? String
|
96
103
|
coverage_report = nil
|
104
|
+
report = []
|
97
105
|
|
98
|
-
events.
|
106
|
+
events.each_value do |tool_events|
|
99
107
|
tool_events.each do |event|
|
100
108
|
if event.rspec_puppet_coverage?
|
101
109
|
coverage_report = event.to_text
|
102
110
|
else
|
103
|
-
|
111
|
+
report << event.to_text unless event.pass? || event.skipped?
|
104
112
|
end
|
105
113
|
end
|
106
114
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
115
|
+
|
116
|
+
report << "\n#{coverage_report}" if coverage_report
|
117
|
+
|
118
|
+
if target.is_a?(String)
|
119
|
+
PDK::Util::Filesystem.write_file(target, report.join("\n"))
|
120
|
+
elsif !report.empty?
|
121
|
+
target << report.join("\n") << "\n"
|
122
|
+
end
|
110
123
|
end
|
111
124
|
end
|
112
125
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Template
|
5
|
+
module Fetcher
|
6
|
+
class Git < PDK::Template::Fetcher::AbstractFetcher
|
7
|
+
# Whether the passed uri is fetchable by Git.
|
8
|
+
# @see PDK::Template::Fetcher.instance
|
9
|
+
# @return [Boolean]
|
10
|
+
def self.fetchable?(uri, _options = {})
|
11
|
+
PDK::Util::Git.repo?(uri.bare_uri)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @see PDK::Template::Fetcher::AbstractTemplateFetcher.fetch!
|
15
|
+
def fetch!
|
16
|
+
return if fetched
|
17
|
+
|
18
|
+
super
|
19
|
+
|
20
|
+
# Default metadata for all git fetching methods
|
21
|
+
@metadata['template-url'] = uri.metadata_format
|
22
|
+
|
23
|
+
# We don't do a checkout of local-path repos. There are lots of edge
|
24
|
+
# cases or user un-expectations.
|
25
|
+
if PDK::Util::Git.work_tree?(uri.shell_path)
|
26
|
+
PDK.logger.warn format("Repository '%{repo}' has a work-tree; skipping git reset.", repo: uri.shell_path)
|
27
|
+
@path = uri.shell_path
|
28
|
+
@temporary = false
|
29
|
+
@metadata['template-ref'] = describe_path_and_ref(@path)
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
# This is either a bare local repo or a remote. either way it needs cloning.
|
34
|
+
# A "remote" can also be git repo on the local filsystem.
|
35
|
+
# @todo When switching this over to using rugged, cache the cloned
|
36
|
+
# template repo in `%AppData%` or `$XDG_CACHE_DIR` and update before
|
37
|
+
# use.
|
38
|
+
require 'pdk/util'
|
39
|
+
require 'pdk/util/git'
|
40
|
+
|
41
|
+
temp_dir = PDK::Util.make_tmpdir_name('pdk-templates')
|
42
|
+
@temporary = true
|
43
|
+
origin_repo = uri.bare_uri
|
44
|
+
git_ref = uri.uri_fragment
|
45
|
+
|
46
|
+
# Clone the repository
|
47
|
+
clone_result = PDK::Util::Git.git('clone', origin_repo, temp_dir)
|
48
|
+
unless clone_result[:exit_code].zero?
|
49
|
+
PDK.logger.error clone_result[:stdout]
|
50
|
+
PDK.logger.error clone_result[:stderr]
|
51
|
+
raise PDK::CLI::FatalError, format("Unable to clone git repository at '%{repo}' into '%{dest}'.", repo: origin_repo, dest: temp_dir)
|
52
|
+
end
|
53
|
+
@path = PDK::Util.canonical_path(temp_dir)
|
54
|
+
|
55
|
+
# Checkout the git reference
|
56
|
+
if PDK::Util::Git.work_dir_clean?(temp_dir)
|
57
|
+
Dir.chdir(temp_dir) do
|
58
|
+
full_ref = PDK::Util::Git.ls_remote(temp_dir, git_ref)
|
59
|
+
@metadata['template-ref'] = describe_path_and_ref(temp_dir, full_ref)
|
60
|
+
reset_result = PDK::Util::Git.git('reset', '--hard', full_ref)
|
61
|
+
return if reset_result[:exit_code].zero?
|
62
|
+
|
63
|
+
PDK.logger.error reset_result[:stdout]
|
64
|
+
PDK.logger.error reset_result[:stderr]
|
65
|
+
raise PDK::CLI::FatalError, format("Unable to checkout '%{ref}' of git repository at '%{path}'.", ref: git_ref, path: temp_dir)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
PDK.logger.warn format("Uncommitted changes found when attempting to checkout '%{ref}' of git repository at '%{path}'; skipping git reset.", ref: git_ref, path: temp_dir)
|
69
|
+
@metadata['template-ref'] = describe_path_and_ref(temp_dir)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# :nocov: This is a just a wrapper for another method
|
76
|
+
def describe_path_and_ref(path, ref = nil)
|
77
|
+
require 'pdk/util/git'
|
78
|
+
PDK::Util::Git.describe(File.join(path, '.git'), ref)
|
79
|
+
end
|
80
|
+
# :nocov:
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Template
|
5
|
+
module Fetcher
|
6
|
+
class Local < PDK::Template::Fetcher::AbstractFetcher
|
7
|
+
# Whether the passed uri is fetchable. This is a catch-all and all URIs
|
8
|
+
# are considered on-disk already.
|
9
|
+
#
|
10
|
+
# @see PDK::Template::Fetcher.instance
|
11
|
+
# @return [Boolean]
|
12
|
+
def self.fetchable?(_uri, _options = {})
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
# @see PDK::Template::Fetcher::AbstractTemplateFetcher.fetch!
|
17
|
+
def fetch!
|
18
|
+
return if fetched
|
19
|
+
|
20
|
+
super
|
21
|
+
|
22
|
+
@path = uri.shell_path
|
23
|
+
@temporary = false
|
24
|
+
@metadata['template-url'] = uri.bare_uri
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Template
|
5
|
+
module Fetcher
|
6
|
+
autoload :Git, 'pdk/template/fetcher/git'
|
7
|
+
autoload :Local, 'pdk/template/fetcher/local'
|
8
|
+
|
9
|
+
# Returns a Template Fetcher implementation for the given Template URI
|
10
|
+
# @param uri [PDK::Util::TemplateURI] The URI of the template to fetch
|
11
|
+
# @param options [Hash{Object => Object}] A list of options to pass through to the fetcher.
|
12
|
+
#
|
13
|
+
# @return [PDK::Template::Fetcher::AbstractTemplateFetcher] An instance of a class which implements the AbstractFetcher class
|
14
|
+
def self.instance(uri, options = {})
|
15
|
+
return Git.new(uri, options) if Git.fetchable?(uri, options)
|
16
|
+
|
17
|
+
Local.new(uri, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Creates an instance of a PDK::Template::Fetcher::AbstractTemplateFetcher object with the path or URL to the template
|
21
|
+
# and the block of code to run to be run while the template is fetched.
|
22
|
+
#
|
23
|
+
# The fetched directory is only guaranteed to be available on disk
|
24
|
+
# within the scope of the block passed to this method.
|
25
|
+
#
|
26
|
+
# @param uri [PDK::Util::TemplateURI] The URI of the template to fetch.
|
27
|
+
# @param options [Hash{Object => Object}] A list of options to pass through to the fetcher.
|
28
|
+
#
|
29
|
+
# @yieldparam fetcher [PDK::Template::Fetcher::AbstractTemplateFetcher] The initialised fetcher with
|
30
|
+
# the template already fetched
|
31
|
+
#
|
32
|
+
# @example Using a git repository as a template
|
33
|
+
# PDK::Template::Fetcher.with('https://github.com/puppetlabs/pdk-templates') do |fetcher|
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# @raise [ArgumentError] If no block is given to this method.
|
37
|
+
# @return [void]
|
38
|
+
def self.with(uri, options = {})
|
39
|
+
raise ArgumentError, format('%{class_name}.with must be passed a block.', class_name: name) unless block_given?
|
40
|
+
|
41
|
+
fetcher = instance(uri, options)
|
42
|
+
|
43
|
+
begin
|
44
|
+
fetcher.fetch!
|
45
|
+
yield fetcher
|
46
|
+
ensure
|
47
|
+
# If the the path is temporary, clean it up
|
48
|
+
PDK::Util::Filesystem.rm_rf(fetcher.path) if fetcher.temporary
|
49
|
+
end
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# An abstract class which all Template Fetchers should subclass. This class is responsible for
|
54
|
+
# downloading or copying a Template Directory that is pointed to by a Template URI
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
# @abstract
|
58
|
+
class AbstractFetcher
|
59
|
+
# @return [PDK::Util::TemplateURI] The URI of the template that is to be fetched
|
60
|
+
attr_reader :uri
|
61
|
+
|
62
|
+
# @return [String] The local filesystem path of the fetched template
|
63
|
+
attr_reader :path
|
64
|
+
|
65
|
+
# @return [Boolean] Whether the fetched path should be considered temporary and be deleted after use
|
66
|
+
attr_reader :temporary
|
67
|
+
|
68
|
+
# @return [Boolean] Whether the template has been fetched yet
|
69
|
+
attr_reader :fetched
|
70
|
+
|
71
|
+
# @return [Hash] The metadata hash for this template.
|
72
|
+
attr_reader :metadata
|
73
|
+
|
74
|
+
# @param uri [PDK::Util::TemplateURI] The URI of the template to fetch
|
75
|
+
# @param options [Hash{Object => Object}] A list of options to pass through to the fetcher.
|
76
|
+
def initialize(uri, options)
|
77
|
+
@uri = uri
|
78
|
+
# Defaults
|
79
|
+
@path = nil
|
80
|
+
@metadata = {
|
81
|
+
'pdk-version' => PDK::Util::Version.version_string,
|
82
|
+
'template-url' => nil,
|
83
|
+
'template-ref' => nil
|
84
|
+
}
|
85
|
+
@fetched = false
|
86
|
+
@temporary = false
|
87
|
+
@options = options
|
88
|
+
end
|
89
|
+
|
90
|
+
# Fetches the template directory and populates the path property
|
91
|
+
#
|
92
|
+
# @return [void]
|
93
|
+
# @abstract
|
94
|
+
def fetch!
|
95
|
+
@fetched = true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
|
3
|
+
module PDK
|
4
|
+
module Template
|
5
|
+
module Renderer
|
6
|
+
module V1
|
7
|
+
# The old templating code in the PDK passed through a TemplateDir object. This class mimics the methods
|
8
|
+
# of that old class so that existing custom templates will still function with the newer refactor templating code.
|
9
|
+
# Methods which have no use in custom templates exist but do no nothing, for example `def render; end`
|
10
|
+
#
|
11
|
+
# @see https://raw.githubusercontent.com/puppetlabs/pdk/4ffd58062c77ad1e54d2fe16b16015f7207bcee8/lib/pdk/module/template_dir/base.rb
|
12
|
+
# :nocov: This class is tested in the packaging and acceptance testing suites
|
13
|
+
class LegacyTemplateDir
|
14
|
+
attr_accessor :module_metadata
|
15
|
+
attr_reader :uri
|
16
|
+
|
17
|
+
def initialize(context, uri, path, module_metadata = {})
|
18
|
+
@uri = uri
|
19
|
+
@module_metadata = module_metadata
|
20
|
+
@context = context
|
21
|
+
@path = path
|
22
|
+
end
|
23
|
+
|
24
|
+
def metadata; end
|
25
|
+
|
26
|
+
def render; end
|
27
|
+
|
28
|
+
def object_template_for; end
|
29
|
+
|
30
|
+
def object_config
|
31
|
+
config_for(nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generate a hash of data to be used when rendering the specified
|
35
|
+
# template.
|
36
|
+
#
|
37
|
+
# @param dest_path [String] The destination path of the file that the
|
38
|
+
# data is for, relative to the root of the module.
|
39
|
+
#
|
40
|
+
# @return [Hash] The data that will be available to the template via the
|
41
|
+
# `@configs` instance variable.
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
def config_for(dest_path, sync_config_path = nil)
|
45
|
+
require 'pdk/util'
|
46
|
+
|
47
|
+
module_root = PDK::Util.module_root
|
48
|
+
sync_config_path ||= File.join(module_root, '.sync.yml') unless module_root.nil?
|
49
|
+
config_path = File.join(@path, 'config_defaults.yml')
|
50
|
+
|
51
|
+
if @config.nil?
|
52
|
+
require 'deep_merge'
|
53
|
+
conf_defaults = read_config(config_path)
|
54
|
+
@sync_config = read_config(sync_config_path) unless sync_config_path.nil?
|
55
|
+
@config = conf_defaults
|
56
|
+
@config.deep_merge!(@sync_config, knockout_prefix: '---') unless @sync_config.nil?
|
57
|
+
end
|
58
|
+
file_config = @config.fetch('common', {}).clone
|
59
|
+
file_config['module_metadata'] = @module_metadata
|
60
|
+
file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
|
61
|
+
file_config.merge!(@config).tap do |c|
|
62
|
+
if uri.default?
|
63
|
+
if c['unmanaged']
|
64
|
+
'unmanaged'
|
65
|
+
elsif c['delete']
|
66
|
+
'deleted'
|
67
|
+
elsif @sync_config&.key?(dest_path)
|
68
|
+
'customized'
|
69
|
+
else
|
70
|
+
'default'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Generates a hash of data from a given yaml file location.
|
77
|
+
#
|
78
|
+
# @param loc [String] The path of the yaml config file.
|
79
|
+
#
|
80
|
+
# @warn If the specified path is not a valid yaml file. Returns an empty Hash
|
81
|
+
# if so.
|
82
|
+
#
|
83
|
+
# @return [Hash] The data that has been read in from the given yaml file.
|
84
|
+
#
|
85
|
+
# @api private
|
86
|
+
def read_config(loc)
|
87
|
+
if PDK::Util::Filesystem.file?(loc) && PDK::Util::Filesystem.readable?(loc)
|
88
|
+
require 'yaml'
|
89
|
+
|
90
|
+
begin
|
91
|
+
YAML.safe_load(PDK::Util::Filesystem.read_file(loc), permitted_classes: [], permitted_symbols: [], aliases: true)
|
92
|
+
rescue Psych::SyntaxError => e
|
93
|
+
PDK.logger.warn format("'%{file}' is not a valid YAML file: %{problem} %{context} at line %{line} column %{column}", file: loc, problem: e.problem, context: e.context, line: e.line,
|
94
|
+
column: e.column)
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
else
|
98
|
+
{}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def template_path(_uri); end
|
103
|
+
end
|
104
|
+
# :nocov:
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|