puppet-lint 4.2.4 → 4.3.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.
- checksums.yaml +4 -4
- data/README.md +21 -1
- data/lib/puppet-lint/bin.rb +4 -1
- data/lib/puppet-lint/checks.rb +18 -8
- data/lib/puppet-lint/data.rb +1 -1
- data/lib/puppet-lint/lexer/token.rb +9 -9
- data/lib/puppet-lint/lexer.rb +1 -1
- data/lib/puppet-lint/optparser.rb +4 -0
- data/lib/puppet-lint/plugins/check_whitespace/space_before_arrow.rb +72 -0
- data/lib/puppet-lint/plugins/legacy_facts/legacy_facts.rb +47 -0
- data/lib/puppet-lint/tasks/puppet-lint.rb +1 -1
- data/lib/puppet-lint/version.rb +1 -1
- data/rubocop_baseline.yml +0 -7
- data/spec/fixtures/test/manifests/top_scope_variables.pp +4 -0
- data/spec/unit/puppet-lint/bin_spec.rb +12 -0
- data/spec/unit/puppet-lint/checks_spec.rb +54 -0
- data/spec/unit/puppet-lint/lexer_spec.rb +14 -12
- data/spec/unit/puppet-lint/plugins/check_whitespace/space_before_arrow_spec.rb +126 -0
- data/spec/unit/puppet-lint/plugins/legacy_facts/legacy_facts_spec.rb +59 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe9befaf41d2eaff6047b13dc030938b29002ce29382312862571133e1b75138
|
4
|
+
data.tar.gz: 655bc012b63ae3659262cfeea02c4e9b35c1af65a1831c5df839b30ea3307934
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6684deef64a18afb534b4004106fc946bcb67e4f8d406912b2bdf0851c495b1feaf35938268c7f1854686e2114c803f7f31b37a9d61df85d175cbf8eb8df14d
|
7
|
+
data.tar.gz: 92f9e92fb27df8abe9b28c116eefa9f901a64b13b6e0de98c6a39cd58451f726ceb142e85daa1958fad2d88388505634d18bee02cc242e023e1bdab51b5a9943
|
data/README.md
CHANGED
@@ -41,6 +41,8 @@ To instruct Lint to automatically fix any issues that it detects, use the `--fix
|
|
41
41
|
puppet-lint --fix /modules
|
42
42
|
```
|
43
43
|
|
44
|
+
Note: The auto-fix functionality is available for Puppet manifest files only.
|
45
|
+
|
44
46
|
### Modify which checks to run
|
45
47
|
|
46
48
|
Puppet Lint options allow you to modify which checks to run. You can disable any of the checks temporarily or permanently, or you can limit testing to specific checks.
|
@@ -117,7 +119,7 @@ Any flag that can be specified on the command line can also be specified in the
|
|
117
119
|
Or to specify an allowlist of allowed checks, include a line like:
|
118
120
|
|
119
121
|
```
|
120
|
-
--only-checks=trailing_whitespace,hard_tabs,duplicate_params,double_quoted_strings,unquoted_file_mode,only_variable_string,variables_not_enclosed,single_quote_string_with_variables,variable_contains_dash,ensure_not_symlink_target,unquoted_resource_title,relative_classname_inclusion,file_mode,resource_reference_without_title_capital,leading_zero,arrow_alignment,variable_is_lowercase,ensure_first_param,resource_reference_without_whitespace,file_ensure,trailing_comma,leading_zero
|
122
|
+
--only-checks=trailing_whitespace,hard_tabs,duplicate_params,double_quoted_strings,unquoted_file_mode,only_variable_string,variables_not_enclosed,single_quote_string_with_variables,variable_contains_dash,ensure_not_symlink_target,unquoted_resource_title,relative_classname_inclusion,file_mode,resource_reference_without_title_capital,leading_zero,arrow_alignment,space_before_arrow,variable_is_lowercase,ensure_first_param,resource_reference_without_whitespace,file_ensure,trailing_comma,leading_zero
|
121
123
|
```
|
122
124
|
|
123
125
|
Please note that there is an important difference between reading options from the command line and reading options from a configuration file: In the former case the shell interprets one level of quotes. That does not happen in the latter case. So, it would make sense to quote some configuration values on the command line, like so:
|
@@ -245,6 +247,23 @@ See `puppet-lint --help` for a full list of command line options and checks.
|
|
245
247
|
|
246
248
|
For a complete list of checks, and how to resolve errors on each check, see the Puppet Lint [checks](http://puppet-lint.com/checks/) page.
|
247
249
|
|
250
|
+
### YAML Checks
|
251
|
+
|
252
|
+
Puppet Lint can check Hiera YAML files for legacy facts.
|
253
|
+
|
254
|
+
For example, the following YAML would trigger warnings:
|
255
|
+
|
256
|
+
```yaml
|
257
|
+
hierarchy:
|
258
|
+
- name: "Legacy Facts Example"
|
259
|
+
paths:
|
260
|
+
- "os/%{facts.hostname}.yaml"
|
261
|
+
- "/var/www/%{::hostname}.yaml"
|
262
|
+
- "%{::bios_vendor}.yaml"
|
263
|
+
```
|
264
|
+
|
265
|
+
Refer to the [Puppet Core Facts documentation](https://www.puppet.com/docs/puppet/8/core_facts.html) for a complete list of available core facts.
|
266
|
+
|
248
267
|
### Spacing, Indentation, and Whitespace
|
249
268
|
|
250
269
|
* Must use two-space soft tabs.
|
@@ -253,6 +272,7 @@ For a complete list of checks, and how to resolve errors on each check, see the
|
|
253
272
|
* Should not exceed an 140-character line width.
|
254
273
|
* An exception has been made for `source => 'puppet://...'` lines as splitting these over multiple lines decreases the readability of the manifests.
|
255
274
|
* Should align arrows (`=>`) within blocks of attributes.
|
275
|
+
* Should contain at most a single space before an arrows(`=>`) where the parameter block contains exactly one parameter.
|
256
276
|
|
257
277
|
### Quoting
|
258
278
|
|
data/lib/puppet-lint/bin.rb
CHANGED
@@ -66,7 +66,10 @@ class PuppetLint::Bin
|
|
66
66
|
|
67
67
|
path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
68
68
|
path = if File.directory?(path)
|
69
|
-
Dir.glob(
|
69
|
+
Dir.glob([
|
70
|
+
"#{path}/**/*.pp",
|
71
|
+
"#{path}/**/*.{yaml,yml}",
|
72
|
+
])
|
70
73
|
else
|
71
74
|
@args
|
72
75
|
end
|
data/lib/puppet-lint/checks.rb
CHANGED
@@ -6,6 +6,8 @@ class PuppetLint::Checks
|
|
6
6
|
# Public: Get an Array of problem Hashes.
|
7
7
|
attr_accessor :problems
|
8
8
|
|
9
|
+
YAML_COMPATIBLE_CHECKS = [:legacy_facts].freeze
|
10
|
+
|
9
11
|
# Public: Initialise a new PuppetLint::Checks object.
|
10
12
|
def initialize
|
11
13
|
@problems = []
|
@@ -45,23 +47,31 @@ class PuppetLint::Checks
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
# Internal: Run the lint checks over the manifest code.
|
50
|
+
# Internal: Run the lint checks over the manifest or YAML code.
|
49
51
|
#
|
50
52
|
# fileinfo - The path to the file as passed to puppet-lint as a String.
|
51
|
-
# data - The String manifest code to be checked.
|
53
|
+
# data - The String manifest or YAML code to be checked.
|
52
54
|
#
|
53
55
|
# Returns an Array of problem Hashes.
|
54
56
|
def run(fileinfo, data)
|
55
57
|
load_data(fileinfo, data)
|
56
58
|
|
57
59
|
checks_run = []
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
if File.extname(fileinfo).downcase.match?(%r{\.ya?ml$})
|
61
|
+
enabled_checks.select { |check| YAML_COMPATIBLE_CHECKS.include?(check) }.each do |check|
|
62
|
+
klass = PuppetLint.configuration.check_object[check].new
|
63
|
+
# FIXME: shadowing #problems
|
64
|
+
problems = klass.run
|
65
|
+
checks_run << [klass, problems]
|
66
|
+
end
|
67
|
+
else
|
68
|
+
enabled_checks.each do |check|
|
69
|
+
klass = PuppetLint.configuration.check_object[check].new
|
70
|
+
# FIXME: shadowing #problems
|
71
|
+
problems = klass.run
|
72
|
+
checks_run << [klass, problems]
|
73
|
+
end
|
63
74
|
end
|
64
|
-
|
65
75
|
checks_run.each do |klass, problems|
|
66
76
|
if PuppetLint.configuration.fix
|
67
77
|
@problems.concat(klass.fix_problems)
|
data/lib/puppet-lint/data.rb
CHANGED
@@ -386,7 +386,7 @@ class PuppetLint::Data
|
|
386
386
|
@function_indexes ||= begin
|
387
387
|
functions = []
|
388
388
|
tokens.each_with_index do |token, token_idx|
|
389
|
-
next unless token.type == :
|
389
|
+
next unless token.type == :FUNCTION_NAME
|
390
390
|
next unless token_idx.zero? ||
|
391
391
|
(token_idx == 1 && tokens[0].type == :WHITESPACE) ||
|
392
392
|
[:NEWLINE, :INDENT].include?(token.prev_token.type) ||
|
@@ -172,9 +172,9 @@ class PuppetLint::Lexer
|
|
172
172
|
return nil unless [:next, :prev].include?(direction)
|
173
173
|
|
174
174
|
opts[:skip_blocks] ||= true
|
175
|
-
to_find =
|
175
|
+
to_find = [*type]
|
176
176
|
|
177
|
-
token_iter = send("#{direction}_token"
|
177
|
+
token_iter = send(:"#{direction}_token")
|
178
178
|
until token_iter.nil?
|
179
179
|
return token_iter if to_find.include?(token_iter.type) && (opts[:value].nil? || token_iter.value == opts[:value])
|
180
180
|
|
@@ -183,18 +183,18 @@ class PuppetLint::Lexer
|
|
183
183
|
|
184
184
|
if opts[:skip_blocks]
|
185
185
|
case token_iter.type
|
186
|
-
when "#{opening_token}BRACE"
|
187
|
-
token_iter = token_iter.send("#{direction}_token_of"
|
188
|
-
when "#{opening_token}BRACK"
|
189
|
-
token_iter = token_iter.send("#{direction}_token_of"
|
190
|
-
when "#{opening_token}PAREN"
|
191
|
-
token_iter = token_iter.send("#{direction}_token_of"
|
186
|
+
when :"#{opening_token}BRACE"
|
187
|
+
token_iter = token_iter.send(:"#{direction}_token_of", [:"#{closing_token}BRACE", opts])
|
188
|
+
when :"#{opening_token}BRACK"
|
189
|
+
token_iter = token_iter.send(:"#{direction}_token_of", [:"#{closing_token}BRACK", opts])
|
190
|
+
when :"#{opening_token}PAREN"
|
191
|
+
token_iter = token_iter.send(:"#{direction}_token_of", [:"#{closing_token}PAREN", opts])
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
195
|
return nil if token_iter.nil?
|
196
196
|
|
197
|
-
token_iter = token_iter.send("#{direction}_token"
|
197
|
+
token_iter = token_iter.send(:"#{direction}_token")
|
198
198
|
end
|
199
199
|
nil
|
200
200
|
end
|
data/lib/puppet-lint/lexer.rb
CHANGED
@@ -123,7 +123,7 @@ class PuppetLint::Lexer
|
|
123
123
|
[:WHITESPACE, %r{\A(#{WHITESPACE_RE}+)}],
|
124
124
|
# FIXME: Future breaking change, the following :TYPE tokens conflict with
|
125
125
|
# the :TYPE keyword token.
|
126
|
-
[:TYPE, %r{\A(
|
126
|
+
[:TYPE, %r{\A(Any|Array|Binary|Boolean|Callable|CatalogEntry|Class|Collection|Data|Default|Enum|Error|Float|Hash|Integer|NotUndef|Numeric|Optional|Pattern|Regexp|Resource|Runtime|Scalar|Sensitive|String|Struct|Tuple|Type|Undef|Variant)\b}], # rubocop:disable Layout/LineLength
|
127
127
|
[:CLASSREF, %r{\A(((::){0,1}[A-Z][-\w]*)+)}],
|
128
128
|
[:NUMBER, %r{\A\b((?:0[xX][0-9A-Fa-f]+|0?\d+(?:\.\d+)?(?:[eE]-?\d+)?))\b}],
|
129
129
|
[:FUNCTION_NAME, %r{#{NAME_RE}(?=\()}],
|
@@ -128,6 +128,10 @@ class PuppetLint::OptParser
|
|
128
128
|
PuppetLint.configuration.ignore_paths = paths.split(',')
|
129
129
|
end
|
130
130
|
|
131
|
+
opts.on('--top-scope-variables VARS', 'A comma separated list of allowed top scope variables') do |vars|
|
132
|
+
PuppetLint.configuration.top_scope_variables = vars.split(',')
|
133
|
+
end
|
134
|
+
|
131
135
|
PuppetLint.configuration.checks.each do |check|
|
132
136
|
opts.on("--no-#{check}-check", "Skip the #{check} check.") do
|
133
137
|
PuppetLint.configuration.send(:"disable_#{check}")
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Check the manifest tokens for any arrows (=>) that have too much space
|
4
|
+
# before them in situations when a given resource has at most one line with
|
5
|
+
# such arrows. For example:
|
6
|
+
|
7
|
+
# file {
|
8
|
+
# # too much space after "foo"
|
9
|
+
# foo⎵⎵=>⎵'bar'
|
10
|
+
# }
|
11
|
+
#
|
12
|
+
# file {
|
13
|
+
# # too much space after 'bar'
|
14
|
+
# foo⎵=>⎵{ bar⎵⎵=>⎵'baz' }
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
|
18
|
+
# Linting multi-parameter resources like this:
|
19
|
+
#
|
20
|
+
# package { 'xxx':
|
21
|
+
# foo => 'bar',
|
22
|
+
# bar => 'baz',
|
23
|
+
# }
|
24
|
+
#
|
25
|
+
# is handled by the "arrow_alignment" plugin.
|
26
|
+
|
27
|
+
PuppetLint.new_check(:space_before_arrow) do
|
28
|
+
def check
|
29
|
+
resource_indexes.each do |res_idx|
|
30
|
+
resource_tokens = res_idx[:tokens]
|
31
|
+
resource_tokens.reject! do |token|
|
32
|
+
Set[:COMMENT, :SLASH_COMMENT, :MLCOMMENT].include?(token.type)
|
33
|
+
end
|
34
|
+
|
35
|
+
first_arrow = resource_tokens.index { |r| r.type == :FARROW }
|
36
|
+
last_arrow = resource_tokens.rindex { |r| r.type == :FARROW }
|
37
|
+
next if first_arrow.nil?
|
38
|
+
next if last_arrow.nil?
|
39
|
+
|
40
|
+
# If this is a single line resource, skip it
|
41
|
+
next unless resource_tokens[first_arrow].line == resource_tokens[last_arrow].line
|
42
|
+
|
43
|
+
resource_tokens.select { |token| token.type == :FARROW }.each do |token|
|
44
|
+
prev_token = token.prev_token
|
45
|
+
next unless prev_token
|
46
|
+
next if prev_token.value == ' '
|
47
|
+
|
48
|
+
line = prev_token.line
|
49
|
+
column = prev_token.column
|
50
|
+
|
51
|
+
notify(
|
52
|
+
:warning,
|
53
|
+
message: "there should be a single space before '=>' on line #{line}, column #{column}",
|
54
|
+
line: line,
|
55
|
+
column: column,
|
56
|
+
token: prev_token,
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def fix(problem)
|
63
|
+
token = problem[:token]
|
64
|
+
|
65
|
+
if token.type == :WHITESPACE
|
66
|
+
token.value = ' '
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
add_token(tokens.index(token), PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0))
|
71
|
+
end
|
72
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
# Public: A puppet-lint custom check to detect legacy facts.
|
2
4
|
#
|
3
5
|
# This check will optionally convert from legacy facts like $::operatingsystem
|
@@ -112,6 +114,51 @@ HASH_KEY_TYPES = Set[
|
|
112
114
|
|
113
115
|
PuppetLint.new_check(:legacy_facts) do
|
114
116
|
def check
|
117
|
+
if File.extname(PuppetLint::Data.path).downcase.match?(%r{\.ya?ml$})
|
118
|
+
content = PuppetLint::Data.manifest_lines
|
119
|
+
yaml_content = content.join("\n")
|
120
|
+
data = YAML.safe_load(yaml_content, aliases: true, permitted_classes: [Symbol])
|
121
|
+
search_yaml(data)
|
122
|
+
else
|
123
|
+
check_puppet
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def search_yaml(data, path = [])
|
128
|
+
case data
|
129
|
+
when Hash
|
130
|
+
data.each do |k, v|
|
131
|
+
search_value(k.to_s, path)
|
132
|
+
search_yaml(v, path + [k.to_s])
|
133
|
+
end
|
134
|
+
when Array
|
135
|
+
data.each_with_index { |v, i| search_yaml(v, path + [i]) }
|
136
|
+
when String
|
137
|
+
search_value(data, path)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def search_value(value, _path)
|
142
|
+
value.scan(%r{%{(?:(?:::?)?|facts\.)([a-zA-Z0-9_]+)(?!\.[a-zA-Z])}}) do |match|
|
143
|
+
base_fact = match[0].split('.').first
|
144
|
+
next unless EASY_FACTS.include?(base_fact) || UNCONVERTIBLE_FACTS.include?(base_fact) || base_fact.match(Regexp.union(REGEX_FACTS))
|
145
|
+
|
146
|
+
notify :warning, {
|
147
|
+
message: "legacy fact '#{base_fact}'",
|
148
|
+
line: find_line_for_content(value),
|
149
|
+
column: 1
|
150
|
+
}
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def find_line_for_content(content)
|
155
|
+
PuppetLint::Data.manifest_lines.each_with_index do |line, index|
|
156
|
+
return index + 1 if line.include?(content)
|
157
|
+
end
|
158
|
+
1
|
159
|
+
end
|
160
|
+
|
161
|
+
def check_puppet
|
115
162
|
tokens.select { |x| LEGACY_FACTS_VAR_TYPES.include?(x.type) }.each do |token|
|
116
163
|
fact_name = ''
|
117
164
|
|
@@ -65,7 +65,7 @@ class PuppetLint::RakeTask < Rake::TaskLib
|
|
65
65
|
|
66
66
|
['with_filename', 'fail_on_warnings', 'error_level', 'log_format', 'with_context', 'fix', 'show_ignored', 'relative'].each do |config|
|
67
67
|
value = instance_variable_get(:"@#{config}")
|
68
|
-
PuppetLint.configuration.send("#{config}="
|
68
|
+
PuppetLint.configuration.send(:"#{config}=", value) unless value.nil?
|
69
69
|
end
|
70
70
|
|
71
71
|
@ignore_paths = PuppetLint.configuration.ignore_paths if PuppetLint.configuration.ignore_paths && @ignore_paths.empty?
|
data/lib/puppet-lint/version.rb
CHANGED
data/rubocop_baseline.yml
CHANGED
@@ -81,10 +81,3 @@ Style/Documentation:
|
|
81
81
|
- spec/**/*
|
82
82
|
Style/WordArray:
|
83
83
|
EnforcedStyle: brackets
|
84
|
-
####################################################
|
85
|
-
# Cops below here due for deprecation
|
86
|
-
####################################################
|
87
|
-
# ``Rspec/FilePath`` is going to be deprecated in the next major release of rubocop >=3.0.0: see <https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FilePath>
|
88
|
-
# As the new cops are already present, e.g., Rspec/SpecFilePathPathFormat, then disabling this in preparation
|
89
|
-
RSpec/FilePath:
|
90
|
-
Enabled: false
|
@@ -121,6 +121,18 @@ describe PuppetLint::Bin do
|
|
121
121
|
its(:stdout) { is_expected.to eq('') }
|
122
122
|
end
|
123
123
|
|
124
|
+
context 'when passed top scope variables option' do
|
125
|
+
let(:args) do
|
126
|
+
[
|
127
|
+
'--top-scope-variables=role',
|
128
|
+
'spec/fixtures/test/manifests/top_scope_variables.pp',
|
129
|
+
]
|
130
|
+
end
|
131
|
+
|
132
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
133
|
+
its(:stdout) { is_expected.to eq('') }
|
134
|
+
end
|
135
|
+
|
124
136
|
context 'when limited to errors only' do
|
125
137
|
let(:args) do
|
126
138
|
[
|
@@ -196,6 +196,60 @@ describe PuppetLint::Checks do
|
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
|
+
describe '#run_yaml' do
|
200
|
+
let(:fileinfo) { File.join('path', 'to', 'test.yaml') }
|
201
|
+
let(:data) do
|
202
|
+
<<~EOS
|
203
|
+
---
|
204
|
+
version: 5
|
205
|
+
defaults:
|
206
|
+
datadir: data
|
207
|
+
data_hash: yaml_data
|
208
|
+
hierarchy:
|
209
|
+
- name: "LEGACY FACT PATH"
|
210
|
+
paths:
|
211
|
+
- "os/%{facts.hostname}.yaml"
|
212
|
+
- name: "osfamily/major release"
|
213
|
+
paths:
|
214
|
+
- "os/%{facts.os.name}/%{facts.os.release.major}.yaml"
|
215
|
+
- name: 'common'
|
216
|
+
path: 'common.yaml'
|
217
|
+
EOS
|
218
|
+
end
|
219
|
+
let(:enabled_checks) { [:legacy_facts] }
|
220
|
+
|
221
|
+
before(:each) do
|
222
|
+
allow(instance).to receive(:enabled_checks).and_return(enabled_checks) # rubocop: disable RSpec/SubjectStub
|
223
|
+
allow(File).to receive(:extname).with(fileinfo).and_return('.yaml')
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'loads the yaml data' do
|
227
|
+
expect(instance).to receive(:load_data).with(fileinfo, data).and_call_original # rubocop: disable RSpec/SubjectStub
|
228
|
+
instance.run(fileinfo, data)
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'when there are checks enabled' do
|
232
|
+
let(:enabled_checks) { [:legacy_facts] }
|
233
|
+
let(:enabled_check_classes) { enabled_checks.map { |r| PuppetLint.configuration.check_object[r] } }
|
234
|
+
let(:disabled_checks) { PuppetLint.configuration.checks - enabled_checks }
|
235
|
+
let(:disabled_check_classes) { disabled_checks.map { |r| PuppetLint.configuration.check_object[r] } }
|
236
|
+
|
237
|
+
it 'runs the enabled checks' do
|
238
|
+
expect(enabled_check_classes).to all(receive(:new).and_call_original)
|
239
|
+
|
240
|
+
instance.run(fileinfo, data)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'does not run the disabled checks' do
|
244
|
+
disabled_check_classes.each do |check_class|
|
245
|
+
expect(check_class).not_to receive(:new)
|
246
|
+
end
|
247
|
+
|
248
|
+
instance.run(fileinfo, data)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
199
253
|
describe '#enabled_checks' do
|
200
254
|
subject(:enabled_checks) { instance.enabled_checks }
|
201
255
|
|
@@ -256,7 +256,7 @@ describe PuppetLint::Lexer do
|
|
256
256
|
end
|
257
257
|
|
258
258
|
context 'treats a variable named the same as the keyword as a variable' do
|
259
|
-
|
259
|
+
described_class::KEYWORDS.each_key do |keyword|
|
260
260
|
context "for '#{keyword}'" do
|
261
261
|
let(:segments) do
|
262
262
|
[
|
@@ -1359,6 +1359,14 @@ END
|
|
1359
1359
|
end
|
1360
1360
|
|
1361
1361
|
context ':TYPE' do
|
1362
|
+
shared_examples 'a type matcher' do |type|
|
1363
|
+
it "matches #{type}" do
|
1364
|
+
token = lexer.tokenise(type).first
|
1365
|
+
expect(token.type).to eq(:TYPE)
|
1366
|
+
expect(token.value).to eq(type)
|
1367
|
+
end
|
1368
|
+
end
|
1369
|
+
|
1362
1370
|
it 'matches Data Types' do
|
1363
1371
|
token = lexer.tokenise('Integer').first
|
1364
1372
|
expect(token.type).to eq(:TYPE)
|
@@ -1378,18 +1386,12 @@ END
|
|
1378
1386
|
end
|
1379
1387
|
|
1380
1388
|
describe 'Platform Types' do
|
1381
|
-
|
1382
|
-
|
1383
|
-
expect(token.type).to eq(:TYPE)
|
1384
|
-
expect(token.value).to eq('Callable')
|
1385
|
-
end
|
1386
|
-
|
1387
|
-
it 'matches Sensitive' do
|
1388
|
-
token = lexer.tokenise('Sensitive').first
|
1389
|
-
expect(token.type).to eq(:TYPE)
|
1390
|
-
expect(token.value).to eq('Sensitive')
|
1391
|
-
end
|
1389
|
+
it_behaves_like 'a type matcher', 'Callable'
|
1390
|
+
it_behaves_like 'a type matcher', 'Sensitive'
|
1392
1391
|
end
|
1392
|
+
|
1393
|
+
it_behaves_like 'a type matcher', 'Error'
|
1394
|
+
it_behaves_like 'a type matcher', 'Binary'
|
1393
1395
|
end
|
1394
1396
|
|
1395
1397
|
context ':HEREDOC without interpolation' do
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'space_before_arrow' do
|
4
|
+
let(:msg) { "there should be a single space before '=>' on line %d, column %d" }
|
5
|
+
|
6
|
+
context 'with code that should not trigger any warnings' do
|
7
|
+
context 'resource with multiple parameters on different lines' do
|
8
|
+
let(:code) do
|
9
|
+
<<-END
|
10
|
+
file { 'foo':
|
11
|
+
foo => bar,
|
12
|
+
bar => buzz,
|
13
|
+
}
|
14
|
+
END
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not detect any problems' do
|
18
|
+
expect(problems).to be_empty
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'resource with single param and normal spacing' do
|
23
|
+
let(:code) do
|
24
|
+
<<-END
|
25
|
+
file { 'foo':
|
26
|
+
foo => bar,
|
27
|
+
}
|
28
|
+
END
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'does not detect any problems' do
|
32
|
+
expect(problems).to be_empty
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'resource with multiple params and normal spacing' do
|
37
|
+
let(:code) do
|
38
|
+
<<-END
|
39
|
+
file { 'foo':
|
40
|
+
foo => { "bar" => "baz" },
|
41
|
+
}
|
42
|
+
END
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'does not detect any problems' do
|
46
|
+
expect(problems).to be_empty
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'resource with a single param and simple value with too much space before arrow' do
|
52
|
+
let(:code) do
|
53
|
+
<<-END
|
54
|
+
file { 'foo':
|
55
|
+
foo => bar,
|
56
|
+
}
|
57
|
+
END
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with fix disabled' do
|
61
|
+
it 'detects extra space before arrow' do
|
62
|
+
expect(problems.size).to eq(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'produces 1 warning' do
|
66
|
+
expect(problems).to contain_warning(msg % [2, 14]).on_line(2).in_column(14)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'with fix enabled' do
|
71
|
+
before(:each) do
|
72
|
+
PuppetLint.configuration.fix = true
|
73
|
+
end
|
74
|
+
|
75
|
+
after(:each) do
|
76
|
+
PuppetLint.configuration.fix = false
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'detects the problem' do
|
80
|
+
expect(problems.size).to eq(1)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'fixes the manifest' do
|
84
|
+
expect(problems).to contain_fixed(msg % [2, 14])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'resource with a single param, a hash as value and bad spacing within the hash' do
|
90
|
+
let(:code) do
|
91
|
+
<<-END
|
92
|
+
file { 'foo':
|
93
|
+
foo => { "bar" => "baz" },
|
94
|
+
}
|
95
|
+
END
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'with fix disabled' do
|
99
|
+
it 'detects extra space before arrow' do
|
100
|
+
expect(problems.size).to eq(1)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'produces a warning' do
|
104
|
+
expect(problems).to contain_warning(msg % [2, 25]).on_line(2).in_column(25)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'with fix enabled' do
|
109
|
+
before(:each) do
|
110
|
+
PuppetLint.configuration.fix = true
|
111
|
+
end
|
112
|
+
|
113
|
+
after(:each) do
|
114
|
+
PuppetLint.configuration.fix = false
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'detects the problem' do
|
118
|
+
expect(problems.size).to eq(1)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'fixes the manifest' do
|
122
|
+
expect(problems).to contain_fixed(msg % [2, 25])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -129,6 +129,65 @@ describe 'legacy_facts' do
|
|
129
129
|
expect(problems.size).to eq(1)
|
130
130
|
end
|
131
131
|
end
|
132
|
+
|
133
|
+
context 'YAML file processing' do
|
134
|
+
before(:each) do
|
135
|
+
allow(File).to receive(:extname).and_return('.yaml')
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'with YAML string containing legacy fact' do
|
139
|
+
let(:code) { 'some_key: "%{::osfamily}"' }
|
140
|
+
|
141
|
+
it 'detects a single problem' do
|
142
|
+
expect(problems.size).to eq(1)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'with YAML string not containing legacy fact' do
|
147
|
+
let(:code) { 'some_key: "%{facts.os.name}"' }
|
148
|
+
|
149
|
+
it 'does not detect any problems' do
|
150
|
+
expect(problems).to be_empty
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'with YAML nested structure containing legacy fact' do
|
155
|
+
let(:code) { "nested:\n value: \"%{::architecture}\"" }
|
156
|
+
|
157
|
+
it 'detects a single problem' do
|
158
|
+
expect(problems.size).to eq(1)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'with YAML array containing legacy facts' do
|
163
|
+
let(:code) do
|
164
|
+
[
|
165
|
+
'array:',
|
166
|
+
' - "%{::processor0}"',
|
167
|
+
' - "%{::ipaddress_eth0}"',
|
168
|
+
].join("\n")
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'detects multiple problems' do
|
172
|
+
expect(problems.size).to eq(2)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'with YAML alias containing legacy fact' do
|
177
|
+
let(:code) do
|
178
|
+
[
|
179
|
+
'template: &template',
|
180
|
+
' fact: "%{::osfamily}"',
|
181
|
+
'instance:',
|
182
|
+
' <<: *template',
|
183
|
+
].join("\n")
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'detects multiple instances' do
|
187
|
+
expect(problems.size).to eq(2)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
132
191
|
end
|
133
192
|
|
134
193
|
context 'with fix enabled' do
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppet-lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Sharpe
|
8
8
|
- Puppet, Inc.
|
9
9
|
- Community Contributors
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2025-03-06 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: " Checks your Puppet manifests against the Puppetlabs style guide
|
16
16
|
and alerts you to any discrepancies.\n"
|
@@ -74,6 +74,7 @@ files:
|
|
74
74
|
- lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb
|
75
75
|
- lib/puppet-lint/plugins/check_whitespace/hard_tabs.rb
|
76
76
|
- lib/puppet-lint/plugins/check_whitespace/line_length.rb
|
77
|
+
- lib/puppet-lint/plugins/check_whitespace/space_before_arrow.rb
|
77
78
|
- lib/puppet-lint/plugins/check_whitespace/trailing_whitespace.rb
|
78
79
|
- lib/puppet-lint/plugins/legacy_facts/legacy_facts.rb
|
79
80
|
- lib/puppet-lint/plugins/top_scope_facts/top_scope_facts.rb
|
@@ -94,6 +95,7 @@ files:
|
|
94
95
|
- spec/fixtures/test/manifests/init.pp
|
95
96
|
- spec/fixtures/test/manifests/malformed.pp
|
96
97
|
- spec/fixtures/test/manifests/mismatched_control_comment.pp
|
98
|
+
- spec/fixtures/test/manifests/top_scope_variables.pp
|
97
99
|
- spec/fixtures/test/manifests/two_warnings.pp
|
98
100
|
- spec/fixtures/test/manifests/unterminated_control_comment.pp
|
99
101
|
- spec/fixtures/test/manifests/url_interpolation.pp
|
@@ -146,6 +148,7 @@ files:
|
|
146
148
|
- spec/unit/puppet-lint/plugins/check_whitespace/80chars_spec.rb
|
147
149
|
- spec/unit/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb
|
148
150
|
- spec/unit/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb
|
151
|
+
- spec/unit/puppet-lint/plugins/check_whitespace/space_before_arrow_spec.rb
|
149
152
|
- spec/unit/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb
|
150
153
|
- spec/unit/puppet-lint/plugins/legacy_facts/legacy_facts_spec.rb
|
151
154
|
- spec/unit/puppet-lint/plugins/top_scope_facts/top_scope_facts_spec.rb
|
@@ -154,7 +157,7 @@ homepage: https://github.com/puppetlabs/puppet-lint/
|
|
154
157
|
licenses:
|
155
158
|
- MIT
|
156
159
|
metadata: {}
|
157
|
-
post_install_message:
|
160
|
+
post_install_message:
|
158
161
|
rdoc_options: []
|
159
162
|
require_paths:
|
160
163
|
- lib
|
@@ -170,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
170
173
|
version: '0'
|
171
174
|
requirements: []
|
172
175
|
rubygems_version: 3.1.6
|
173
|
-
signing_key:
|
176
|
+
signing_key:
|
174
177
|
specification_version: 4
|
175
178
|
summary: Ensure your Puppet manifests conform with the Puppetlabs style guide
|
176
179
|
test_files: []
|