pdk-akerl 1.8.0.1

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +826 -0
  3. data/LICENSE +201 -0
  4. data/README.md +133 -0
  5. data/exe/pdk +10 -0
  6. data/lib/pdk.rb +10 -0
  7. data/lib/pdk/answer_file.rb +121 -0
  8. data/lib/pdk/cli.rb +113 -0
  9. data/lib/pdk/cli/build.rb +76 -0
  10. data/lib/pdk/cli/bundle.rb +42 -0
  11. data/lib/pdk/cli/convert.rb +41 -0
  12. data/lib/pdk/cli/errors.rb +23 -0
  13. data/lib/pdk/cli/exec.rb +246 -0
  14. data/lib/pdk/cli/exec_group.rb +67 -0
  15. data/lib/pdk/cli/module.rb +14 -0
  16. data/lib/pdk/cli/module/build.rb +14 -0
  17. data/lib/pdk/cli/module/generate.rb +45 -0
  18. data/lib/pdk/cli/new.rb +17 -0
  19. data/lib/pdk/cli/new/class.rb +32 -0
  20. data/lib/pdk/cli/new/defined_type.rb +30 -0
  21. data/lib/pdk/cli/new/module.rb +41 -0
  22. data/lib/pdk/cli/new/provider.rb +27 -0
  23. data/lib/pdk/cli/new/task.rb +31 -0
  24. data/lib/pdk/cli/test.rb +12 -0
  25. data/lib/pdk/cli/test/unit.rb +88 -0
  26. data/lib/pdk/cli/update.rb +32 -0
  27. data/lib/pdk/cli/util.rb +193 -0
  28. data/lib/pdk/cli/util/command_redirector.rb +26 -0
  29. data/lib/pdk/cli/util/interview.rb +63 -0
  30. data/lib/pdk/cli/util/option_normalizer.rb +53 -0
  31. data/lib/pdk/cli/util/option_validator.rb +56 -0
  32. data/lib/pdk/cli/validate.rb +124 -0
  33. data/lib/pdk/generate.rb +11 -0
  34. data/lib/pdk/generate/defined_type.rb +49 -0
  35. data/lib/pdk/generate/module.rb +318 -0
  36. data/lib/pdk/generate/provider.rb +82 -0
  37. data/lib/pdk/generate/puppet_class.rb +48 -0
  38. data/lib/pdk/generate/puppet_object.rb +288 -0
  39. data/lib/pdk/generate/task.rb +86 -0
  40. data/lib/pdk/i18n.rb +4 -0
  41. data/lib/pdk/logger.rb +28 -0
  42. data/lib/pdk/module.rb +21 -0
  43. data/lib/pdk/module/build.rb +214 -0
  44. data/lib/pdk/module/convert.rb +209 -0
  45. data/lib/pdk/module/metadata.rb +193 -0
  46. data/lib/pdk/module/templatedir.rb +313 -0
  47. data/lib/pdk/module/update.rb +111 -0
  48. data/lib/pdk/module/update_manager.rb +210 -0
  49. data/lib/pdk/report.rb +112 -0
  50. data/lib/pdk/report/event.rb +357 -0
  51. data/lib/pdk/template_file.rb +89 -0
  52. data/lib/pdk/tests/unit.rb +213 -0
  53. data/lib/pdk/util.rb +271 -0
  54. data/lib/pdk/util/bundler.rb +253 -0
  55. data/lib/pdk/util/filesystem.rb +12 -0
  56. data/lib/pdk/util/git.rb +74 -0
  57. data/lib/pdk/util/puppet_version.rb +242 -0
  58. data/lib/pdk/util/ruby_version.rb +147 -0
  59. data/lib/pdk/util/vendored_file.rb +88 -0
  60. data/lib/pdk/util/version.rb +42 -0
  61. data/lib/pdk/util/windows.rb +13 -0
  62. data/lib/pdk/util/windows/api_types.rb +57 -0
  63. data/lib/pdk/util/windows/file.rb +36 -0
  64. data/lib/pdk/util/windows/string.rb +16 -0
  65. data/lib/pdk/validate.rb +14 -0
  66. data/lib/pdk/validate/base_validator.rb +209 -0
  67. data/lib/pdk/validate/metadata/metadata_json_lint.rb +86 -0
  68. data/lib/pdk/validate/metadata/metadata_syntax.rb +109 -0
  69. data/lib/pdk/validate/metadata_validator.rb +30 -0
  70. data/lib/pdk/validate/puppet/puppet_lint.rb +67 -0
  71. data/lib/pdk/validate/puppet/puppet_syntax.rb +112 -0
  72. data/lib/pdk/validate/puppet_validator.rb +30 -0
  73. data/lib/pdk/validate/ruby/rubocop.rb +77 -0
  74. data/lib/pdk/validate/ruby_validator.rb +29 -0
  75. data/lib/pdk/validate/tasks/metadata_lint.rb +126 -0
  76. data/lib/pdk/validate/tasks/name.rb +88 -0
  77. data/lib/pdk/validate/tasks_validator.rb +33 -0
  78. data/lib/pdk/version.rb +4 -0
  79. data/locales/config.yaml +21 -0
  80. data/locales/pdk.pot +1283 -0
  81. metadata +304 -0
@@ -0,0 +1,86 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validate/base_validator'
4
+ require 'pdk/util/bundler'
5
+ require 'pathname'
6
+
7
+ module PDK
8
+ module Validate
9
+ class MetadataJSONLint < BaseValidator
10
+ # Validate each metadata file separately, as metadata-json-lint does not
11
+ # support multiple targets.
12
+ INVOKE_STYLE = :per_target
13
+
14
+ def self.name
15
+ 'metadata-json-lint'
16
+ end
17
+
18
+ def self.cmd
19
+ 'metadata-json-lint'
20
+ end
21
+
22
+ def self.spinner_text(targets = [])
23
+ _('Checking module metadata style (%{targets}).') % {
24
+ targets: PDK::Util.targets_relative_to_pwd(targets).join(' '),
25
+ }
26
+ end
27
+
28
+ def self.pattern
29
+ 'metadata.json'
30
+ end
31
+
32
+ def self.parse_options(_options, targets)
33
+ cmd_options = ['--format', 'json']
34
+ cmd_options << '--strict-dependencies'
35
+
36
+ cmd_options.concat(targets)
37
+ end
38
+
39
+ def self.parse_output(report, result, targets)
40
+ raise ArgumentError, _('More than 1 target provided to PDK::Validate::MetadataJSONLint.') if targets.count > 1
41
+
42
+ if result[:stdout].strip.empty?
43
+ # metadata-json-lint will print nothing if there are no problems with
44
+ # the file being linted. This should be handled separately to
45
+ # metadata-json-lint generating output that can not be parsed as JSON
46
+ # (unhandled exception in metadata-json-lint).
47
+ json_data = {}
48
+ else
49
+ begin
50
+ json_data = JSON.parse(result[:stdout])
51
+ rescue JSON::ParserError
52
+ raise PDK::Validate::ParseOutputError, result[:stdout]
53
+ end
54
+ end
55
+
56
+ if json_data.empty?
57
+ report.add_event(
58
+ file: targets.first,
59
+ source: name,
60
+ state: :passed,
61
+ severity: :ok,
62
+ )
63
+ else
64
+ json_data.delete('result')
65
+ json_data.keys.each do |type|
66
+ json_data[type].each do |offense|
67
+ # metadata-json-lint groups the offenses by type, so the type ends
68
+ # up being `warnings` or `errors`. We want to convert that to the
69
+ # singular noun for the event.
70
+ event_type = type[%r{\A(.+?)s?\Z}, 1]
71
+
72
+ report.add_event(
73
+ file: targets.first,
74
+ source: name,
75
+ message: offense['msg'],
76
+ test: offense['check'],
77
+ severity: event_type,
78
+ state: :failure,
79
+ )
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,109 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validate/base_validator'
4
+ require 'pathname'
5
+
6
+ module PDK
7
+ module Validate
8
+ class MetadataSyntax < BaseValidator
9
+ def self.name
10
+ 'metadata-syntax'
11
+ end
12
+
13
+ def self.pattern
14
+ ['metadata.json', 'tasks/*.json']
15
+ end
16
+
17
+ def self.spinner_text(_targets = [])
18
+ _('Checking metadata syntax (%{targets}).') % {
19
+ targets: pattern.join(' '),
20
+ }
21
+ end
22
+
23
+ def self.create_spinner(targets = [], options = {})
24
+ return unless PDK::CLI::Util.interactive?
25
+ options = options.merge(PDK::CLI::Util.spinner_opts_for_platform)
26
+
27
+ exec_group = options[:exec_group]
28
+ @spinner = if exec_group
29
+ exec_group.add_spinner(spinner_text(targets), options)
30
+ else
31
+ TTY::Spinner.new("[:spinner] #{spinner_text(targets)}", options)
32
+ end
33
+ @spinner.auto_spin
34
+ end
35
+
36
+ def self.stop_spinner(exit_code)
37
+ if exit_code.zero? && @spinner
38
+ @spinner.success
39
+ elsif @spinner
40
+ @spinner.error
41
+ end
42
+ end
43
+
44
+ def self.invoke(report, options = {})
45
+ targets, skipped, invalid = parse_targets(options)
46
+
47
+ process_skipped(report, skipped)
48
+ process_invalid(report, invalid)
49
+
50
+ return 0 if targets.empty?
51
+
52
+ return_val = 0
53
+ create_spinner(targets, options)
54
+
55
+ # The pure ruby JSON parser gives much nicer parse error messages than
56
+ # the C extension at the cost of slightly slower parsing. We require it
57
+ # here and restore the C extension at the end of the method (if it was
58
+ # being used).
59
+ require 'json/pure'
60
+ JSON.parser = JSON::Pure::Parser
61
+
62
+ targets.each do |target|
63
+ unless File.readable?(target)
64
+ report.add_event(
65
+ file: target,
66
+ source: name,
67
+ state: :failure,
68
+ severity: 'error',
69
+ message: _('Could not be read.'),
70
+ )
71
+ return_val = 1
72
+ next
73
+ end
74
+
75
+ begin
76
+ JSON.parse(File.read(target))
77
+
78
+ report.add_event(
79
+ file: target,
80
+ source: name,
81
+ state: :passed,
82
+ severity: 'ok',
83
+ )
84
+ rescue JSON::ParserError => e
85
+ # Because the message contains a raw segment of the file, we use
86
+ # String#dump here to unescape any escape characters like newlines.
87
+ # We then strip out the surrounding quotes and the exclaimation
88
+ # point that json_pure likes to put in exception messages.
89
+ sane_message = e.message.dump[%r{\A"(.+?)!?"\Z}, 1]
90
+
91
+ report.add_event(
92
+ file: target,
93
+ source: name,
94
+ state: :failure,
95
+ severity: 'error',
96
+ message: sane_message,
97
+ )
98
+ return_val = 1
99
+ end
100
+ end
101
+
102
+ stop_spinner(return_val)
103
+ return_val
104
+ ensure
105
+ JSON.parser = JSON::Ext::Parser if defined?(JSON::Ext::Parser)
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,30 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validate/base_validator'
4
+ require 'pdk/validate/metadata/metadata_json_lint'
5
+ require 'pdk/validate/metadata/metadata_syntax'
6
+
7
+ module PDK
8
+ module Validate
9
+ class MetadataValidator < BaseValidator
10
+ def self.name
11
+ 'metadata'
12
+ end
13
+
14
+ def self.metadata_validators
15
+ [MetadataSyntax, MetadataJSONLint]
16
+ end
17
+
18
+ def self.invoke(report, options = {})
19
+ exit_code = 0
20
+
21
+ metadata_validators.each do |validator|
22
+ exit_code = validator.invoke(report, options)
23
+ break if exit_code != 0
24
+ end
25
+
26
+ exit_code
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,67 @@
1
+ require 'pdk'
2
+ require 'pdk/util'
3
+ require 'pdk/cli/exec'
4
+ require 'pdk/validate/base_validator'
5
+
6
+ module PDK
7
+ module Validate
8
+ class PuppetLint < BaseValidator
9
+ def self.name
10
+ 'puppet-lint'
11
+ end
12
+
13
+ def self.cmd
14
+ 'puppet-lint'
15
+ end
16
+
17
+ def self.pattern
18
+ '**/*.pp'
19
+ end
20
+
21
+ def self.spinner_text(_targets = nil)
22
+ _('Checking Puppet manifest style (%{pattern}).') % { pattern: pattern }
23
+ end
24
+
25
+ def self.parse_options(options, targets)
26
+ cmd_options = ['--json', '--relative']
27
+
28
+ cmd_options << '--fix' if options[:auto_correct]
29
+
30
+ cmd_options.concat(targets)
31
+ end
32
+
33
+ def self.parse_output(report, result, targets)
34
+ begin
35
+ json_data = JSON.parse(result[:stdout]).flatten
36
+ rescue JSON::ParserError
37
+ raise PDK::Validate::ParseOutputError, result[:stdout]
38
+ end
39
+
40
+ # puppet-lint does not include files without problems in its JSON
41
+ # output, so we need to go through the list of targets and add passing
42
+ # events to the report for any target not listed in the JSON output.
43
+ targets.reject { |target| json_data.any? { |j| j['path'] == target } }.each do |target|
44
+ report.add_event(
45
+ file: target,
46
+ source: name,
47
+ severity: 'ok',
48
+ state: :passed,
49
+ )
50
+ end
51
+
52
+ json_data.each do |offense|
53
+ report.add_event(
54
+ file: offense['path'],
55
+ source: name,
56
+ line: offense['line'],
57
+ column: offense['column'],
58
+ message: offense['message'],
59
+ test: offense['check'],
60
+ severity: (offense['kind'] == 'fixed') ? 'corrected' : offense['kind'],
61
+ state: :failure,
62
+ )
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,112 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validate/base_validator'
4
+
5
+ module PDK
6
+ module Validate
7
+ class PuppetSyntax < BaseValidator
8
+ # In Puppet >= 5.3.4, the error context formatting was changed to facilitate localization
9
+ ERROR_CONTEXT = %r{(?:file:\s(?<file>.+?)|line:\s(?<line>.+?)|column:\s(?<column>.+?))}
10
+ # In Puppet < 5.3.3, the error context was formatted in these variations:
11
+ # - "at file_path:line_num:col_num"
12
+ # - "at file_path:line_num"
13
+ # - "at line line_num"
14
+ # - "in file_path"
15
+ ERROR_CONTEXT_LEGACY = %r{(?:at\sline\s(?<line>\d+)|at\s(?<file>.+?):(?<line>\d+):(?<column>\d+)|at\s(?<file>.+?):(?<line>\d+)|in\s(?<file>.+?))}
16
+
17
+ PUPPET_LOGGER_PREFIX = %r{^(debug|info|notice|warning|error|alert|critical):\s.+?$}i
18
+ PUPPET_SYNTAX_PATTERN = %r{^
19
+ (?<severity>.+?):\s
20
+ (?<message>.+?)
21
+ (?:
22
+ \s\(#{ERROR_CONTEXT}(,\s#{ERROR_CONTEXT})*\)| # attempt to match the new localisation friendly location
23
+ \s#{ERROR_CONTEXT_LEGACY}| # attempt to match the old " at file:line:column" location
24
+ $ # handle cases where the output has no location
25
+ )
26
+ $}x
27
+
28
+ def self.name
29
+ 'puppet-syntax'
30
+ end
31
+
32
+ def self.cmd
33
+ 'puppet'
34
+ end
35
+
36
+ def self.pattern
37
+ '**/**.pp'
38
+ end
39
+
40
+ def self.pattern_ignore
41
+ '/plans/**/*.pp'
42
+ end
43
+
44
+ def self.spinner_text(_targets = nil)
45
+ _('Checking Puppet manifest syntax (%{pattern}).') % { pattern: pattern }
46
+ end
47
+
48
+ def self.parse_options(_options, targets)
49
+ ['parser', 'validate', '--config', null_file].concat(targets)
50
+ end
51
+
52
+ def self.null_file
53
+ Gem.win_platform? ? 'NUL' : '/dev/null'
54
+ end
55
+
56
+ def self.parse_output(report, result, targets)
57
+ # Due to PUP-7504, we will have to programmatically construct the json
58
+ # object from the text output for now.
59
+ output = result[:stderr].split("\n").reject { |entry| entry.empty? }
60
+
61
+ results_data = []
62
+ output.each do |offense|
63
+ offense_data = parse_offense(offense)
64
+ results_data << offense_data
65
+ end
66
+
67
+ # puppet parser validate does not include files without problems in its
68
+ # output, so we need to go through the list of targets and add passing
69
+ # events to the report for any target not listed in the output.
70
+ targets.reject { |target| results_data.any? { |j| j[:file] =~ %r{#{target}} } }.each do |target|
71
+ report.add_event(
72
+ file: target,
73
+ source: name,
74
+ severity: :ok,
75
+ state: :passed,
76
+ )
77
+ end
78
+
79
+ results_data.each do |offense|
80
+ report.add_event(offense)
81
+ end
82
+ end
83
+
84
+ def self.parse_offense(offense)
85
+ sanitize_console_output(offense)
86
+
87
+ offense_data = {
88
+ source: name,
89
+ state: :failure,
90
+ }
91
+
92
+ if offense.match(PUPPET_LOGGER_PREFIX)
93
+ attributes = offense.match(PUPPET_SYNTAX_PATTERN)
94
+
95
+ unless attributes.nil?
96
+ attributes.names.each do |name|
97
+ offense_data[name.to_sym] = attributes[name] unless attributes[name].nil?
98
+ end
99
+ end
100
+ else
101
+ offense_data[:message] = offense
102
+ end
103
+
104
+ offense_data
105
+ end
106
+
107
+ def self.sanitize_console_output(line)
108
+ line.gsub!(%r{\e\[([;\d]+)?m}, '')
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,30 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/validate/base_validator'
4
+ require 'pdk/validate/puppet/puppet_lint'
5
+ require 'pdk/validate/puppet/puppet_syntax'
6
+
7
+ module PDK
8
+ module Validate
9
+ class PuppetValidator < BaseValidator
10
+ def self.name
11
+ 'puppet'
12
+ end
13
+
14
+ def self.puppet_validators
15
+ [PuppetSyntax, PuppetLint]
16
+ end
17
+
18
+ def self.invoke(report, options = {})
19
+ exit_code = 0
20
+
21
+ puppet_validators.each do |validator|
22
+ exit_code = validator.invoke(report, options)
23
+ break if exit_code != 0
24
+ end
25
+
26
+ exit_code
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,77 @@
1
+ require 'pdk'
2
+ require 'pdk/cli/exec'
3
+ require 'pdk/util'
4
+ require 'pdk/util/bundler'
5
+ require 'pdk/validate/base_validator'
6
+ require 'pdk/validate/ruby_validator'
7
+
8
+ module PDK
9
+ module Validate
10
+ class Rubocop < BaseValidator
11
+ ALLOW_EMPTY_TARGETS = true
12
+
13
+ def self.name
14
+ 'rubocop'
15
+ end
16
+
17
+ def self.cmd
18
+ 'rubocop'
19
+ end
20
+
21
+ def self.pattern
22
+ '**/**.rb'
23
+ end
24
+
25
+ def self.spinner_text(_targets = nil)
26
+ _('Checking Ruby code style (%{pattern}).') % { pattern: pattern }
27
+ end
28
+
29
+ def self.parse_options(options, targets)
30
+ cmd_options = ['--format', 'json']
31
+
32
+ if options[:auto_correct]
33
+ cmd_options << '--auto-correct'
34
+ end
35
+
36
+ cmd_options.concat(targets)
37
+ end
38
+
39
+ def self.parse_output(report, result, _targets)
40
+ return if result[:stdout].empty?
41
+
42
+ begin
43
+ json_data = JSON.parse(result[:stdout])
44
+ rescue JSON::ParserError
45
+ raise PDK::Validate::ParseOutputError, result[:stdout]
46
+ end
47
+
48
+ return unless json_data.key?('files')
49
+
50
+ json_data['files'].each do |file_info|
51
+ next unless file_info.key?('offenses')
52
+ result = {
53
+ file: file_info['path'],
54
+ source: 'rubocop',
55
+ }
56
+
57
+ if file_info['offenses'].empty?
58
+ report.add_event(result.merge(state: :passed, severity: :ok))
59
+ else
60
+ file_info['offenses'].each do |offense|
61
+ report.add_event(
62
+ result.merge(
63
+ line: offense['location']['line'],
64
+ column: offense['location']['column'],
65
+ message: offense['message'],
66
+ severity: (offense['corrected']) ? 'corrected' : offense['severity'],
67
+ test: offense['cop_name'],
68
+ state: :failure,
69
+ ),
70
+ )
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end