pdk 2.3.0 → 2.4.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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1329 -1321
  3. data/LICENSE +201 -201
  4. data/README.md +163 -163
  5. data/exe/pdk +10 -10
  6. data/lib/pdk/analytics/client/google_analytics.rb +143 -143
  7. data/lib/pdk/analytics/client/noop.rb +25 -25
  8. data/lib/pdk/analytics/util.rb +19 -19
  9. data/lib/pdk/analytics.rb +30 -30
  10. data/lib/pdk/answer_file.rb +12 -12
  11. data/lib/pdk/bolt.rb +19 -19
  12. data/lib/pdk/cli/build.rb +82 -82
  13. data/lib/pdk/cli/bundle.rb +48 -48
  14. data/lib/pdk/cli/config/get.rb +26 -26
  15. data/lib/pdk/cli/config.rb +22 -22
  16. data/lib/pdk/cli/console.rb +148 -148
  17. data/lib/pdk/cli/convert.rb +52 -52
  18. data/lib/pdk/cli/env.rb +52 -52
  19. data/lib/pdk/cli/errors.rb +25 -25
  20. data/lib/pdk/cli/exec/command.rb +293 -293
  21. data/lib/pdk/cli/exec/interactive_command.rb +114 -114
  22. data/lib/pdk/cli/exec.rb +84 -84
  23. data/lib/pdk/cli/exec_group.rb +104 -104
  24. data/lib/pdk/cli/get/config.rb +24 -24
  25. data/lib/pdk/cli/get.rb +20 -20
  26. data/lib/pdk/cli/module/build.rb +12 -12
  27. data/lib/pdk/cli/module/generate.rb +47 -47
  28. data/lib/pdk/cli/module.rb +14 -14
  29. data/lib/pdk/cli/new/class.rb +32 -32
  30. data/lib/pdk/cli/new/defined_type.rb +32 -32
  31. data/lib/pdk/cli/new/fact.rb +29 -29
  32. data/lib/pdk/cli/new/function.rb +29 -29
  33. data/lib/pdk/cli/new/module.rb +53 -53
  34. data/lib/pdk/cli/new/provider.rb +29 -29
  35. data/lib/pdk/cli/new/task.rb +34 -34
  36. data/lib/pdk/cli/new/test.rb +52 -52
  37. data/lib/pdk/cli/new/transport.rb +27 -27
  38. data/lib/pdk/cli/new.rb +21 -21
  39. data/lib/pdk/cli/release/prep.rb +39 -39
  40. data/lib/pdk/cli/release/publish.rb +50 -50
  41. data/lib/pdk/cli/release.rb +194 -194
  42. data/lib/pdk/cli/remove/config.rb +80 -80
  43. data/lib/pdk/cli/remove.rb +20 -20
  44. data/lib/pdk/cli/set/config.rb +119 -119
  45. data/lib/pdk/cli/set.rb +20 -20
  46. data/lib/pdk/cli/test/unit.rb +90 -90
  47. data/lib/pdk/cli/test.rb +11 -11
  48. data/lib/pdk/cli/update.rb +64 -64
  49. data/lib/pdk/cli/util/command_redirector.rb +27 -27
  50. data/lib/pdk/cli/util/interview.rb +72 -72
  51. data/lib/pdk/cli/util/option_normalizer.rb +55 -55
  52. data/lib/pdk/cli/util/option_validator.rb +68 -68
  53. data/lib/pdk/cli/util/spinner.rb +13 -13
  54. data/lib/pdk/cli/util/update_manager_printer.rb +82 -82
  55. data/lib/pdk/cli/util.rb +305 -305
  56. data/lib/pdk/cli/validate.rb +116 -116
  57. data/lib/pdk/cli.rb +175 -175
  58. data/lib/pdk/config/analytics_schema.json +26 -26
  59. data/lib/pdk/config/errors.rb +5 -5
  60. data/lib/pdk/config/ini_file.rb +183 -183
  61. data/lib/pdk/config/ini_file_setting.rb +39 -39
  62. data/lib/pdk/config/json.rb +34 -34
  63. data/lib/pdk/config/json_schema_namespace.rb +142 -142
  64. data/lib/pdk/config/json_schema_setting.rb +53 -53
  65. data/lib/pdk/config/json_with_schema.rb +49 -49
  66. data/lib/pdk/config/namespace.rb +354 -354
  67. data/lib/pdk/config/setting.rb +135 -135
  68. data/lib/pdk/config/validator.rb +31 -31
  69. data/lib/pdk/config/yaml.rb +46 -46
  70. data/lib/pdk/config/yaml_with_schema.rb +59 -59
  71. data/lib/pdk/config.rb +390 -390
  72. data/lib/pdk/context/control_repo.rb +60 -60
  73. data/lib/pdk/context/module.rb +28 -28
  74. data/lib/pdk/context/none.rb +22 -22
  75. data/lib/pdk/context.rb +99 -99
  76. data/lib/pdk/control_repo.rb +90 -90
  77. data/lib/pdk/generate/defined_type.rb +43 -43
  78. data/lib/pdk/generate/fact.rb +25 -25
  79. data/lib/pdk/generate/function.rb +48 -48
  80. data/lib/pdk/generate/module.rb +352 -352
  81. data/lib/pdk/generate/provider.rb +28 -28
  82. data/lib/pdk/generate/puppet_class.rb +43 -43
  83. data/lib/pdk/generate/puppet_object.rb +232 -232
  84. data/lib/pdk/generate/task.rb +68 -68
  85. data/lib/pdk/generate/transport.rb +33 -33
  86. data/lib/pdk/generate.rb +24 -24
  87. data/lib/pdk/i18n.rb +4 -4
  88. data/lib/pdk/logger.rb +45 -45
  89. data/lib/pdk/module/build.rb +322 -322
  90. data/lib/pdk/module/convert.rb +296 -296
  91. data/lib/pdk/module/metadata.rb +202 -202
  92. data/lib/pdk/module/release.rb +260 -260
  93. data/lib/pdk/module/update.rb +131 -131
  94. data/lib/pdk/module/update_manager.rb +227 -227
  95. data/lib/pdk/module.rb +30 -30
  96. data/lib/pdk/report/event.rb +370 -370
  97. data/lib/pdk/report.rb +121 -121
  98. data/lib/pdk/template/fetcher/git.rb +85 -85
  99. data/lib/pdk/template/fetcher/local.rb +28 -28
  100. data/lib/pdk/template/fetcher.rb +98 -98
  101. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +116 -116
  102. data/lib/pdk/template/renderer/v1/renderer.rb +132 -132
  103. data/lib/pdk/template/renderer/v1/template_file.rb +102 -102
  104. data/lib/pdk/template/renderer/v1.rb +25 -25
  105. data/lib/pdk/template/renderer.rb +96 -96
  106. data/lib/pdk/template/template_dir.rb +67 -67
  107. data/lib/pdk/template.rb +59 -59
  108. data/lib/pdk/tests/unit.rb +252 -252
  109. data/lib/pdk/util/bundler.rb +259 -259
  110. data/lib/pdk/util/changelog_generator.rb +137 -137
  111. data/lib/pdk/util/env.rb +47 -47
  112. data/lib/pdk/util/filesystem.rb +138 -138
  113. data/lib/pdk/util/git.rb +179 -179
  114. data/lib/pdk/util/json_finder.rb +85 -85
  115. data/lib/pdk/util/puppet_strings.rb +125 -125
  116. data/lib/pdk/util/puppet_version.rb +266 -266
  117. data/lib/pdk/util/ruby_version.rb +179 -179
  118. data/lib/pdk/util/template_uri.rb +295 -295
  119. data/lib/pdk/util/vendored_file.rb +93 -93
  120. data/lib/pdk/util/version.rb +43 -43
  121. data/lib/pdk/util/windows/api_types.rb +82 -82
  122. data/lib/pdk/util/windows/file.rb +36 -36
  123. data/lib/pdk/util/windows/process.rb +79 -79
  124. data/lib/pdk/util/windows/string.rb +16 -16
  125. data/lib/pdk/util/windows.rb +15 -15
  126. data/lib/pdk/util.rb +278 -277
  127. data/lib/pdk/validate/control_repo/control_repo_validator_group.rb +23 -23
  128. data/lib/pdk/validate/control_repo/environment_conf_validator.rb +98 -98
  129. data/lib/pdk/validate/external_command_validator.rb +208 -208
  130. data/lib/pdk/validate/internal_ruby_validator.rb +100 -100
  131. data/lib/pdk/validate/invokable_validator.rb +228 -228
  132. data/lib/pdk/validate/metadata/metadata_json_lint_validator.rb +86 -86
  133. data/lib/pdk/validate/metadata/metadata_syntax_validator.rb +78 -78
  134. data/lib/pdk/validate/metadata/metadata_validator_group.rb +20 -20
  135. data/lib/pdk/validate/puppet/puppet_epp_validator.rb +133 -133
  136. data/lib/pdk/validate/puppet/puppet_lint_validator.rb +66 -66
  137. data/lib/pdk/validate/puppet/puppet_syntax_validator.rb +137 -137
  138. data/lib/pdk/validate/puppet/puppet_validator_group.rb +21 -21
  139. data/lib/pdk/validate/ruby/ruby_rubocop_validator.rb +80 -80
  140. data/lib/pdk/validate/ruby/ruby_validator_group.rb +19 -19
  141. data/lib/pdk/validate/tasks/tasks_metadata_lint_validator.rb +88 -88
  142. data/lib/pdk/validate/tasks/tasks_name_validator.rb +50 -50
  143. data/lib/pdk/validate/tasks/tasks_validator_group.rb +20 -20
  144. data/lib/pdk/validate/validator.rb +118 -118
  145. data/lib/pdk/validate/validator_group.rb +104 -104
  146. data/lib/pdk/validate/yaml/yaml_syntax_validator.rb +95 -95
  147. data/lib/pdk/validate/yaml/yaml_validator_group.rb +19 -19
  148. data/lib/pdk/validate.rb +94 -94
  149. data/lib/pdk/version.rb +4 -4
  150. data/lib/pdk.rb +76 -76
  151. data/locales/config.yaml +21 -21
  152. data/locales/pdk.pot +2094 -2094
  153. metadata +5 -6
@@ -1,86 +1,86 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Validate
5
- module Metadata
6
- class MetadataJSONLintValidator < ExternalCommandValidator
7
- # Validate each metadata file separately, as metadata-json-lint does not
8
- # support multiple targets.
9
- def invoke_style
10
- :per_target
11
- end
12
-
13
- def name
14
- 'metadata-json-lint'
15
- end
16
-
17
- def cmd
18
- 'metadata-json-lint'
19
- end
20
-
21
- def spinner_text_for_targets(targets)
22
- _('Checking module metadata style (%{targets}).') % {
23
- targets: PDK::Util.targets_relative_to_pwd(targets.flatten).join(' '),
24
- }
25
- end
26
-
27
- def pattern
28
- contextual_pattern('metadata.json')
29
- end
30
-
31
- def parse_options(targets)
32
- cmd_options = ['--format', 'json']
33
- cmd_options << '--strict-dependencies'
34
-
35
- cmd_options.concat(targets)
36
- end
37
-
38
- def parse_output(report, result, targets)
39
- raise ArgumentError, _('More than 1 target provided to PDK::Validate::MetadataJSONLintValidator.') if targets.count > 1
40
-
41
- if result[:stdout].strip.empty?
42
- # metadata-json-lint will print nothing if there are no problems with
43
- # the file being linted. This should be handled separately to
44
- # metadata-json-lint generating output that can not be parsed as JSON
45
- # (unhandled exception in metadata-json-lint).
46
- json_data = {}
47
- else
48
- begin
49
- json_data = JSON.parse(result[:stdout])
50
- rescue JSON::ParserError
51
- raise PDK::Validate::ParseOutputError, result[:stdout]
52
- end
53
- end
54
-
55
- if json_data.empty?
56
- report.add_event(
57
- file: targets.first,
58
- source: name,
59
- state: :passed,
60
- severity: :ok,
61
- )
62
- else
63
- json_data.delete('result')
64
- json_data.keys.each do |type|
65
- json_data[type].each do |offense|
66
- # metadata-json-lint groups the offenses by type, so the type ends
67
- # up being `warnings` or `errors`. We want to convert that to the
68
- # singular noun for the event.
69
- event_type = type[%r{\A(.+?)s?\Z}, 1]
70
-
71
- report.add_event(
72
- file: targets.first,
73
- source: name,
74
- message: offense['msg'],
75
- test: offense['check'],
76
- severity: event_type,
77
- state: :failure,
78
- )
79
- end
80
- end
81
- end
82
- end
83
- end
84
- end
85
- end
86
- end
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Validate
5
+ module Metadata
6
+ class MetadataJSONLintValidator < ExternalCommandValidator
7
+ # Validate each metadata file separately, as metadata-json-lint does not
8
+ # support multiple targets.
9
+ def invoke_style
10
+ :per_target
11
+ end
12
+
13
+ def name
14
+ 'metadata-json-lint'
15
+ end
16
+
17
+ def cmd
18
+ 'metadata-json-lint'
19
+ end
20
+
21
+ def spinner_text_for_targets(targets)
22
+ _('Checking module metadata style (%{targets}).') % {
23
+ targets: PDK::Util.targets_relative_to_pwd(targets.flatten).join(' '),
24
+ }
25
+ end
26
+
27
+ def pattern
28
+ contextual_pattern('metadata.json')
29
+ end
30
+
31
+ def parse_options(targets)
32
+ cmd_options = ['--format', 'json']
33
+ cmd_options << '--strict-dependencies'
34
+
35
+ cmd_options.concat(targets)
36
+ end
37
+
38
+ def parse_output(report, result, targets)
39
+ raise ArgumentError, _('More than 1 target provided to PDK::Validate::MetadataJSONLintValidator.') if targets.count > 1
40
+
41
+ if result[:stdout].strip.empty?
42
+ # metadata-json-lint will print nothing if there are no problems with
43
+ # the file being linted. This should be handled separately to
44
+ # metadata-json-lint generating output that can not be parsed as JSON
45
+ # (unhandled exception in metadata-json-lint).
46
+ json_data = {}
47
+ else
48
+ begin
49
+ json_data = JSON.parse(result[:stdout])
50
+ rescue JSON::ParserError
51
+ raise PDK::Validate::ParseOutputError, result[:stdout]
52
+ end
53
+ end
54
+
55
+ if json_data.empty?
56
+ report.add_event(
57
+ file: targets.first,
58
+ source: name,
59
+ state: :passed,
60
+ severity: :ok,
61
+ )
62
+ else
63
+ json_data.delete('result')
64
+ json_data.keys.each do |type|
65
+ json_data[type].each do |offense|
66
+ # metadata-json-lint groups the offenses by type, so the type ends
67
+ # up being `warnings` or `errors`. We want to convert that to the
68
+ # singular noun for the event.
69
+ event_type = type[%r{\A(.+?)s?\Z}, 1]
70
+
71
+ report.add_event(
72
+ file: targets.first,
73
+ source: name,
74
+ message: offense['msg'],
75
+ test: offense['check'],
76
+ severity: event_type,
77
+ state: :failure,
78
+ )
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,78 +1,78 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Validate
5
- module Metadata
6
- class MetadataSyntaxValidator < InternalRubyValidator
7
- def name
8
- 'metadata-syntax'
9
- end
10
-
11
- def pattern
12
- contextual_pattern(['metadata.json', 'tasks/*.json'])
13
- end
14
-
15
- def spinner_text
16
- _('Checking metadata syntax (%{patterns}).') % {
17
- patterns: pattern.join(' '),
18
- }
19
- end
20
-
21
- def invoke(report)
22
- super
23
- ensure
24
- JSON.parser = JSON::Ext::Parser if defined?(JSON::Ext::Parser)
25
- end
26
-
27
- def before_validation
28
- # The pure ruby JSON parser gives much nicer parse error messages than
29
- # the C extension at the cost of slightly slower parsing. We require it
30
- # here and restore the C extension at the end of the method (if it was
31
- # being used).
32
- require 'json/pure'
33
- JSON.parser = JSON::Pure::Parser
34
- end
35
-
36
- def validate_target(report, target)
37
- unless PDK::Util::Filesystem.readable?(target)
38
- report.add_event(
39
- file: target,
40
- source: name,
41
- state: :failure,
42
- severity: 'error',
43
- message: _('Could not be read.'),
44
- )
45
- return 1
46
- end
47
-
48
- begin
49
- JSON.parse(PDK::Util::Filesystem.read_file(target))
50
-
51
- report.add_event(
52
- file: target,
53
- source: name,
54
- state: :passed,
55
- severity: 'ok',
56
- )
57
- return 0
58
- rescue JSON::ParserError => e
59
- # Because the message contains a raw segment of the file, we use
60
- # String#dump here to unescape any escape characters like newlines.
61
- # We then strip out the surrounding quotes and the exclaimation
62
- # point that json_pure likes to put in exception messages.
63
- sane_message = e.message.dump[%r{\A"(.+?)!?"\Z}, 1]
64
-
65
- report.add_event(
66
- file: target,
67
- source: name,
68
- state: :failure,
69
- severity: 'error',
70
- message: sane_message,
71
- )
72
- return 1
73
- end
74
- end
75
- end
76
- end
77
- end
78
- end
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Validate
5
+ module Metadata
6
+ class MetadataSyntaxValidator < InternalRubyValidator
7
+ def name
8
+ 'metadata-syntax'
9
+ end
10
+
11
+ def pattern
12
+ contextual_pattern(['metadata.json', 'tasks/*.json'])
13
+ end
14
+
15
+ def spinner_text
16
+ _('Checking metadata syntax (%{patterns}).') % {
17
+ patterns: pattern.join(' '),
18
+ }
19
+ end
20
+
21
+ def invoke(report)
22
+ super
23
+ ensure
24
+ JSON.parser = JSON::Ext::Parser if defined?(JSON::Ext::Parser)
25
+ end
26
+
27
+ def before_validation
28
+ # The pure ruby JSON parser gives much nicer parse error messages than
29
+ # the C extension at the cost of slightly slower parsing. We require it
30
+ # here and restore the C extension at the end of the method (if it was
31
+ # being used).
32
+ require 'json/pure'
33
+ JSON.parser = JSON::Pure::Parser
34
+ end
35
+
36
+ def validate_target(report, target)
37
+ unless PDK::Util::Filesystem.readable?(target)
38
+ report.add_event(
39
+ file: target,
40
+ source: name,
41
+ state: :failure,
42
+ severity: 'error',
43
+ message: _('Could not be read.'),
44
+ )
45
+ return 1
46
+ end
47
+
48
+ begin
49
+ JSON.parse(PDK::Util::Filesystem.read_file(target))
50
+
51
+ report.add_event(
52
+ file: target,
53
+ source: name,
54
+ state: :passed,
55
+ severity: 'ok',
56
+ )
57
+ return 0
58
+ rescue JSON::ParserError => e
59
+ # Because the message contains a raw segment of the file, we use
60
+ # String#dump here to unescape any escape characters like newlines.
61
+ # We then strip out the surrounding quotes and the exclaimation
62
+ # point that json_pure likes to put in exception messages.
63
+ sane_message = e.message.dump[%r{\A"(.+?)!?"\Z}, 1]
64
+
65
+ report.add_event(
66
+ file: target,
67
+ source: name,
68
+ state: :failure,
69
+ severity: 'error',
70
+ message: sane_message,
71
+ )
72
+ return 1
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,20 +1,20 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Validate
5
- module Metadata
6
- class MetadataValidatorGroup < ValidatorGroup
7
- def name
8
- 'metadata'
9
- end
10
-
11
- def validators
12
- [
13
- MetadataSyntaxValidator,
14
- MetadataJSONLintValidator,
15
- ].freeze
16
- end
17
- end
18
- end
19
- end
20
- end
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Validate
5
+ module Metadata
6
+ class MetadataValidatorGroup < ValidatorGroup
7
+ def name
8
+ 'metadata'
9
+ end
10
+
11
+ def validators
12
+ [
13
+ MetadataSyntaxValidator,
14
+ MetadataJSONLintValidator,
15
+ ].freeze
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,133 +1,133 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Validate
5
- module Puppet
6
- class PuppetEPPValidator < ExternalCommandValidator
7
- # In Puppet >= 5.3.4, the error context formatting was changed to facilitate localization
8
- ERROR_CONTEXT = %r{(?:file:\s(?<file>.+?)|line:\s(?<line>.+?)|column:\s(?<column>.+?))}
9
- # In Puppet < 5.3.3, the error context was formatted in these variations:
10
- # - "at file_path:line_num:col_num"
11
- # - "at file_path:line_num"
12
- # - "at line line_num"
13
- # - "in file_path"
14
- ERROR_CONTEXT_LEGACY = %r{(?:at\sline\s(?<line>\d+)|at\s(?<file>.+?):(?<line>\d+):(?<column>\d+)|at\s(?<file>.+?):(?<line>\d+)|in\s(?<file>.+?))}
15
-
16
- PUPPET_LOGGER_PREFIX = %r{^(debug|info|notice|warning|error|alert|critical):\s.+?$}i
17
- PUPPET_SYNTAX_PATTERN = %r{^
18
- (?<severity>.+?):\s
19
- (?<message>.+?)
20
- (?:
21
- \s\(#{ERROR_CONTEXT}(,\s#{ERROR_CONTEXT})*\)| # attempt to match the new localisation friendly location
22
- \s#{ERROR_CONTEXT_LEGACY}| # attempt to match the old " at file:line:column" location
23
- $ # handle cases where the output has no location
24
- )
25
- $}x
26
-
27
- def name
28
- 'puppet-epp'
29
- end
30
-
31
- def cmd
32
- 'puppet'
33
- end
34
-
35
- def pattern
36
- contextual_pattern('**/*.epp')
37
- end
38
-
39
- def spinner_text_for_targets(_targets)
40
- _('Checking Puppet EPP syntax (%{pattern}).') % { pattern: pattern.join(' ') }
41
- end
42
-
43
- def parse_options(targets)
44
- # Due to PDK-1266 we need to run `puppet parser validate` with an empty
45
- # modulepath. On *nix, Ruby treats `/dev/null` as an empty directory
46
- # however it doesn't do so with `NUL` on Windows. The workaround for
47
- # this to ensure consistent behaviour is to create an empty temporary
48
- # directory and use that as the modulepath.
49
- ['epp', 'validate', '--config', null_file, '--modulepath', validate_tmpdir].concat(targets)
50
- end
51
-
52
- def invoke(report)
53
- super
54
- ensure
55
- remove_validate_tmpdir
56
- end
57
-
58
- def validate_tmpdir
59
- require 'tmpdir'
60
-
61
- @validate_tmpdir ||= Dir.mktmpdir('puppet-epp-validate')
62
- end
63
-
64
- def remove_validate_tmpdir
65
- return unless @validate_tmpdir
66
- return unless PDK::Util::Filesystem.directory?(@validate_tmpdir)
67
-
68
- PDK::Util::Filesystem.remove_entry_secure(@validate_tmpdir)
69
- @validate_tmpdir = nil
70
- end
71
-
72
- def null_file
73
- Gem.win_platform? ? 'NUL' : '/dev/null'
74
- end
75
-
76
- def parse_output(report, result, targets)
77
- # Due to PUP-7504, we will have to programmatically construct the json
78
- # object from the text output for now.
79
- output = result[:stderr].split(%r{\r?\n}).reject { |entry| entry.empty? }
80
-
81
- results_data = []
82
- output.each do |offense|
83
- offense_data = parse_offense(offense)
84
- results_data << offense_data
85
- end
86
-
87
- # puppet parser validate does not include files without problems in its
88
- # output, so we need to go through the list of targets and add passing
89
- # events to the report for any target not listed in the output.
90
- targets.reject { |target| results_data.any? { |j| j[:file] =~ %r{#{target}} } }.each do |target|
91
- report.add_event(
92
- file: target,
93
- source: name,
94
- severity: :ok,
95
- state: :passed,
96
- )
97
- end
98
-
99
- results_data.each do |offense|
100
- report.add_event(offense)
101
- end
102
- end
103
-
104
- def parse_offense(offense)
105
- sanitize_console_output(offense)
106
-
107
- offense_data = {
108
- source: name,
109
- state: :failure,
110
- }
111
-
112
- if offense.match(PUPPET_LOGGER_PREFIX)
113
- attributes = offense.match(PUPPET_SYNTAX_PATTERN)
114
-
115
- unless attributes.nil?
116
- attributes.names.each do |name|
117
- offense_data[name.to_sym] = attributes[name] unless attributes[name].nil?
118
- end
119
- end
120
- else
121
- offense_data[:message] = offense
122
- end
123
-
124
- offense_data
125
- end
126
-
127
- def sanitize_console_output(line)
128
- line.gsub!(%r{\e\[([;\d]+)?m}, '')
129
- end
130
- end
131
- end
132
- end
133
- end
1
+ require 'pdk'
2
+
3
+ module PDK
4
+ module Validate
5
+ module Puppet
6
+ class PuppetEPPValidator < ExternalCommandValidator
7
+ # In Puppet >= 5.3.4, the error context formatting was changed to facilitate localization
8
+ ERROR_CONTEXT = %r{(?:file:\s(?<file>.+?)|line:\s(?<line>.+?)|column:\s(?<column>.+?))}
9
+ # In Puppet < 5.3.3, the error context was formatted in these variations:
10
+ # - "at file_path:line_num:col_num"
11
+ # - "at file_path:line_num"
12
+ # - "at line line_num"
13
+ # - "in file_path"
14
+ ERROR_CONTEXT_LEGACY = %r{(?:at\sline\s(?<line>\d+)|at\s(?<file>.+?):(?<line>\d+):(?<column>\d+)|at\s(?<file>.+?):(?<line>\d+)|in\s(?<file>.+?))}
15
+
16
+ PUPPET_LOGGER_PREFIX = %r{^(debug|info|notice|warning|error|alert|critical):\s.+?$}i
17
+ PUPPET_SYNTAX_PATTERN = %r{^
18
+ (?<severity>.+?):\s
19
+ (?<message>.+?)
20
+ (?:
21
+ \s\(#{ERROR_CONTEXT}(,\s#{ERROR_CONTEXT})*\)| # attempt to match the new localisation friendly location
22
+ \s#{ERROR_CONTEXT_LEGACY}| # attempt to match the old " at file:line:column" location
23
+ $ # handle cases where the output has no location
24
+ )
25
+ $}x
26
+
27
+ def name
28
+ 'puppet-epp'
29
+ end
30
+
31
+ def cmd
32
+ 'puppet'
33
+ end
34
+
35
+ def pattern
36
+ contextual_pattern('**/*.epp')
37
+ end
38
+
39
+ def spinner_text_for_targets(_targets)
40
+ _('Checking Puppet EPP syntax (%{pattern}).') % { pattern: pattern.join(' ') }
41
+ end
42
+
43
+ def parse_options(targets)
44
+ # Due to PDK-1266 we need to run `puppet parser validate` with an empty
45
+ # modulepath. On *nix, Ruby treats `/dev/null` as an empty directory
46
+ # however it doesn't do so with `NUL` on Windows. The workaround for
47
+ # this to ensure consistent behaviour is to create an empty temporary
48
+ # directory and use that as the modulepath.
49
+ ['epp', 'validate', '--config', null_file, '--modulepath', validate_tmpdir].concat(targets)
50
+ end
51
+
52
+ def invoke(report)
53
+ super
54
+ ensure
55
+ remove_validate_tmpdir
56
+ end
57
+
58
+ def validate_tmpdir
59
+ require 'tmpdir'
60
+
61
+ @validate_tmpdir ||= Dir.mktmpdir('puppet-epp-validate')
62
+ end
63
+
64
+ def remove_validate_tmpdir
65
+ return unless @validate_tmpdir
66
+ return unless PDK::Util::Filesystem.directory?(@validate_tmpdir)
67
+
68
+ PDK::Util::Filesystem.remove_entry_secure(@validate_tmpdir)
69
+ @validate_tmpdir = nil
70
+ end
71
+
72
+ def null_file
73
+ Gem.win_platform? ? 'NUL' : '/dev/null'
74
+ end
75
+
76
+ def parse_output(report, result, targets)
77
+ # Due to PUP-7504, we will have to programmatically construct the json
78
+ # object from the text output for now.
79
+ output = result[:stderr].split(%r{\r?\n}).reject { |entry| entry.empty? }
80
+
81
+ results_data = []
82
+ output.each do |offense|
83
+ offense_data = parse_offense(offense)
84
+ results_data << offense_data
85
+ end
86
+
87
+ # puppet parser validate does not include files without problems in its
88
+ # output, so we need to go through the list of targets and add passing
89
+ # events to the report for any target not listed in the output.
90
+ targets.reject { |target| results_data.any? { |j| j[:file] =~ %r{#{target}} } }.each do |target|
91
+ report.add_event(
92
+ file: target,
93
+ source: name,
94
+ severity: :ok,
95
+ state: :passed,
96
+ )
97
+ end
98
+
99
+ results_data.each do |offense|
100
+ report.add_event(offense)
101
+ end
102
+ end
103
+
104
+ def parse_offense(offense)
105
+ sanitize_console_output(offense)
106
+
107
+ offense_data = {
108
+ source: name,
109
+ state: :failure,
110
+ }
111
+
112
+ if offense.match(PUPPET_LOGGER_PREFIX)
113
+ attributes = offense.match(PUPPET_SYNTAX_PATTERN)
114
+
115
+ unless attributes.nil?
116
+ attributes.names.each do |name|
117
+ offense_data[name.to_sym] = attributes[name] unless attributes[name].nil?
118
+ end
119
+ end
120
+ else
121
+ offense_data[:message] = offense
122
+ end
123
+
124
+ offense_data
125
+ end
126
+
127
+ def sanitize_console_output(line)
128
+ line.gsub!(%r{\e\[([;\d]+)?m}, '')
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end