puppet-lint 2.2.1 → 2.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/CHANGELOG.md +40 -19
- data/README.md +181 -174
- data/Rakefile +1 -1
- data/lib/puppet-lint/bin.rb +6 -0
- data/lib/puppet-lint/lexer.rb +1 -1
- data/lib/puppet-lint/plugins.rb +16 -10
- data/lib/puppet-lint/plugins/check_classes/arrow_on_right_operand_line.rb +46 -0
- data/lib/puppet-lint/plugins/check_classes/autoloader_layout.rb +33 -0
- data/lib/puppet-lint/plugins/check_classes/class_inherits_from_params_class.rb +20 -0
- data/lib/puppet-lint/plugins/check_classes/code_on_top_scope.rb +20 -0
- data/lib/puppet-lint/plugins/check_classes/inherits_across_namespaces.rb +22 -0
- data/lib/puppet-lint/plugins/check_classes/names_containing_dash.rb +23 -0
- data/lib/puppet-lint/plugins/check_classes/names_containing_uppercase.rb +28 -0
- data/lib/puppet-lint/plugins/check_classes/nested_classes_or_defines.rb +28 -0
- data/lib/puppet-lint/plugins/check_classes/parameter_order.rb +44 -0
- data/lib/puppet-lint/plugins/check_classes/right_to_left_relationship.rb +15 -0
- data/lib/puppet-lint/plugins/check_classes/variable_scope.rb +143 -0
- data/lib/puppet-lint/plugins/check_comments/slash_comments.rb +22 -0
- data/lib/puppet-lint/plugins/{check_comments.rb → check_comments/star_comments.rb} +1 -24
- data/lib/puppet-lint/plugins/{check_conditionals.rb → check_conditionals/case_without_default.rb} +1 -27
- data/lib/puppet-lint/plugins/check_conditionals/selector_inside_resource.rb +25 -0
- data/lib/puppet-lint/plugins/{check_documentation.rb → check_documentation/documentation.rb} +0 -0
- data/lib/puppet-lint/plugins/{check_nodes.rb → check_nodes/unquoted_node_name.rb} +0 -0
- data/lib/puppet-lint/plugins/check_resources/duplicate_params.rb +37 -0
- data/lib/puppet-lint/plugins/check_resources/ensure_first_param.rb +70 -0
- data/lib/puppet-lint/plugins/check_resources/ensure_not_symlink_target.rb +44 -0
- data/lib/puppet-lint/plugins/check_resources/file_mode.rb +42 -0
- data/lib/puppet-lint/plugins/check_resources/unquoted_file_mode.rb +31 -0
- data/lib/puppet-lint/plugins/check_resources/unquoted_resource_title.rb +22 -0
- data/lib/puppet-lint/plugins/check_strings/double_quoted_strings.rb +27 -0
- data/lib/puppet-lint/plugins/check_strings/only_variable_string.rb +63 -0
- data/lib/puppet-lint/plugins/check_strings/puppet_url_without_modules.rb +25 -0
- data/lib/puppet-lint/plugins/check_strings/quoted_booleans.rb +26 -0
- data/lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb +17 -0
- data/lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb +23 -0
- data/lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb +21 -0
- data/lib/puppet-lint/plugins/{check_variables.rb → check_variables/variable_is_lowercase.rb} +0 -22
- data/lib/puppet-lint/plugins/check_whitespace/140chars.rb +21 -0
- data/lib/puppet-lint/plugins/check_whitespace/2sp_soft_tabs.rb +19 -0
- data/lib/puppet-lint/plugins/check_whitespace/80chars.rb +21 -0
- data/lib/puppet-lint/plugins/{check_whitespace.rb → check_whitespace/arrow_alignment.rb} +0 -118
- data/lib/puppet-lint/plugins/check_whitespace/hard_tabs.rb +24 -0
- data/lib/puppet-lint/plugins/check_whitespace/trailing_whitespace.rb +28 -0
- data/lib/puppet-lint/tasks/puppet-lint.rb +4 -0
- data/lib/puppet-lint/version.rb +1 -1
- data/spec/puppet-lint/bin_spec.rb +18 -1
- data/spec/puppet-lint/lexer_spec.rb +19 -0
- metadata +41 -68
- data/lib/puppet-lint/plugins/check_classes.rb +0 -433
- data/lib/puppet-lint/plugins/check_resources.rb +0 -251
- data/lib/puppet-lint/plugins/check_strings.rb +0 -186
@@ -0,0 +1,22 @@
|
|
1
|
+
# Public: Check the manifest tokens for any comments started with slashes
|
2
|
+
# (//) and record a warning for each instance found.
|
3
|
+
#
|
4
|
+
# https://docs.puppet.com/guides/style_guide.html#comments
|
5
|
+
PuppetLint.new_check(:slash_comments) do
|
6
|
+
def check
|
7
|
+
tokens.select { |token|
|
8
|
+
token.type == :SLASH_COMMENT
|
9
|
+
}.each do |token|
|
10
|
+
notify :warning, {
|
11
|
+
:message => '// comment found',
|
12
|
+
:line => token.line,
|
13
|
+
:column => token.column,
|
14
|
+
:token => token,
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fix(problem)
|
20
|
+
problem[:token].type = :COMMENT
|
21
|
+
end
|
22
|
+
end
|
@@ -1,26 +1,3 @@
|
|
1
|
-
# Public: Check the manifest tokens for any comments started with slashes
|
2
|
-
# (//) and record a warning for each instance found.
|
3
|
-
#
|
4
|
-
# https://docs.puppet.com/guides/style_guide.html#comments
|
5
|
-
PuppetLint.new_check(:slash_comments) do
|
6
|
-
def check
|
7
|
-
tokens.select { |token|
|
8
|
-
token.type == :SLASH_COMMENT
|
9
|
-
}.each do |token|
|
10
|
-
notify :warning, {
|
11
|
-
:message => '// comment found',
|
12
|
-
:line => token.line,
|
13
|
-
:column => token.column,
|
14
|
-
:token => token,
|
15
|
-
}
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def fix(problem)
|
20
|
-
problem[:token].type = :COMMENT
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
1
|
# Public: Check the manifest tokens for any comments encapsulated with
|
25
2
|
# slash-asterisks (/* */) and record a warning for each instance found.
|
26
3
|
#
|
@@ -41,7 +18,7 @@ PuppetLint.new_check(:star_comments) do
|
|
41
18
|
|
42
19
|
def fix(problem)
|
43
20
|
comment_lines = problem[:token].value.strip.split("\n").map(&:strip)
|
44
|
-
|
21
|
+
|
45
22
|
first_line = comment_lines.shift
|
46
23
|
problem[:token].type = :COMMENT
|
47
24
|
problem[:token].value = " #{first_line}"
|
data/lib/puppet-lint/plugins/{check_conditionals.rb → check_conditionals/case_without_default.rb}
RENAMED
@@ -1,29 +1,3 @@
|
|
1
|
-
# Public: Test the manifest tokens for any selectors embedded within resource
|
2
|
-
# declarations and record a warning for each instance found.
|
3
|
-
#
|
4
|
-
# https://docs.puppet.com/guides/style_guide.html#keep-resource-declarations-simple
|
5
|
-
PuppetLint.new_check(:selector_inside_resource) do
|
6
|
-
def check
|
7
|
-
resource_indexes.each do |resource|
|
8
|
-
resource[:tokens].each do |token|
|
9
|
-
if token.type == :FARROW
|
10
|
-
if token.next_code_token.type == :VARIABLE
|
11
|
-
unless token.next_code_token.next_code_token.nil?
|
12
|
-
if token.next_code_token.next_code_token.type == :QMARK
|
13
|
-
notify :warning, {
|
14
|
-
:message => 'selector inside resource block',
|
15
|
-
:line => token.line,
|
16
|
-
:column => token.column,
|
17
|
-
}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
1
|
# Public: Test the manifest tokens for any case statements that do not
|
28
2
|
# contain a "default" case and record a warning for each instance found.
|
29
3
|
#
|
@@ -54,7 +28,7 @@ PuppetLint.new_check(:case_without_default) do
|
|
54
28
|
case_tokens = tokens[kase[:start]..kase[:end]]
|
55
29
|
|
56
30
|
case_indexes[(kase_index + 1)..-1].each do |successor_kase|
|
57
|
-
|
31
|
+
case_tokens -= tokens[successor_kase[:start]..successor_kase[:end]]
|
58
32
|
end
|
59
33
|
|
60
34
|
unless case_tokens.index { |r| r.type == :DEFAULT }
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Public: Test the manifest tokens for any selectors embedded within resource
|
2
|
+
# declarations and record a warning for each instance found.
|
3
|
+
#
|
4
|
+
# https://docs.puppet.com/guides/style_guide.html#keep-resource-declarations-simple
|
5
|
+
PuppetLint.new_check(:selector_inside_resource) do
|
6
|
+
def check
|
7
|
+
resource_indexes.each do |resource|
|
8
|
+
resource[:tokens].each do |token|
|
9
|
+
if token.type == :FARROW
|
10
|
+
if token.next_code_token.type == :VARIABLE
|
11
|
+
unless token.next_code_token.next_code_token.nil?
|
12
|
+
if token.next_code_token.next_code_token.type == :QMARK
|
13
|
+
notify :warning, {
|
14
|
+
:message => 'selector inside resource block',
|
15
|
+
:line => token.line,
|
16
|
+
:column => token.column,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/puppet-lint/plugins/{check_documentation.rb → check_documentation/documentation.rb}
RENAMED
File without changes
|
File without changes
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Public: Check the tokens of each resource instance for any duplicate
|
2
|
+
# parameters and record a warning for each instance found.
|
3
|
+
#
|
4
|
+
# No style guide reference
|
5
|
+
PuppetLint.new_check(:duplicate_params) do
|
6
|
+
def check
|
7
|
+
resource_indexes.each do |resource|
|
8
|
+
seen_params = {}
|
9
|
+
level = 0
|
10
|
+
|
11
|
+
resource[:tokens].each_with_index do |token, idx|
|
12
|
+
case token.type
|
13
|
+
when :LBRACE
|
14
|
+
level += 1
|
15
|
+
next
|
16
|
+
when :RBRACE
|
17
|
+
seen_params.delete(level)
|
18
|
+
level -= 1
|
19
|
+
next
|
20
|
+
when :FARROW
|
21
|
+
prev_token = token.prev_code_token
|
22
|
+
next unless prev_token.type == :NAME
|
23
|
+
|
24
|
+
if (seen_params[level] ||= Set.new).include?(prev_token.value)
|
25
|
+
notify :error, {
|
26
|
+
:message => 'duplicate parameter found in resource',
|
27
|
+
:line => prev_token.line,
|
28
|
+
:column => prev_token.column,
|
29
|
+
}
|
30
|
+
else
|
31
|
+
seen_params[level] << prev_token.value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Public: Check the tokens of each resource instance for an ensure parameter
|
2
|
+
# and if found, check that it is the first parameter listed. If it is not
|
3
|
+
# the first parameter, record a warning.
|
4
|
+
#
|
5
|
+
# https://docs.puppet.com/guides/style_guide.html#attribute-ordering
|
6
|
+
PuppetLint.new_check(:ensure_first_param) do
|
7
|
+
def check
|
8
|
+
resource_indexes.each do |resource|
|
9
|
+
next if [:CLASS].include? resource[:type].type
|
10
|
+
ensure_attr_index = resource[:param_tokens].index { |param_token|
|
11
|
+
param_token.value == 'ensure'
|
12
|
+
}
|
13
|
+
|
14
|
+
unless ensure_attr_index.nil?
|
15
|
+
if ensure_attr_index > 0
|
16
|
+
ensure_token = resource[:param_tokens][ensure_attr_index]
|
17
|
+
notify :warning, {
|
18
|
+
:message => "ensure found on line but it's not the first attribute",
|
19
|
+
:line => ensure_token.line,
|
20
|
+
:column => ensure_token.column,
|
21
|
+
:resource => resource,
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def fix(problem)
|
29
|
+
first_param_name_token = tokens[problem[:resource][:start]].next_token_of(:NAME)
|
30
|
+
first_param_comma_token = first_param_name_token.next_token_of(:COMMA)
|
31
|
+
ensure_param_name_token = first_param_comma_token.next_token_of(:NAME, :value => 'ensure')
|
32
|
+
ensure_param_comma_token = ensure_param_name_token.next_token_of([:COMMA, :SEMIC])
|
33
|
+
|
34
|
+
if first_param_name_token.nil? or first_param_comma_token.nil? or ensure_param_name_token.nil? or ensure_param_comma_token.nil?
|
35
|
+
raise PuppetLint::NoFix
|
36
|
+
end
|
37
|
+
|
38
|
+
first_param_name_idx = tokens.index(first_param_name_token)
|
39
|
+
first_param_comma_idx = tokens.index(first_param_comma_token)
|
40
|
+
ensure_param_name_idx = tokens.index(ensure_param_name_token)
|
41
|
+
ensure_param_comma_idx = tokens.index(ensure_param_comma_token)
|
42
|
+
|
43
|
+
# Flip params
|
44
|
+
prev_token = first_param_name_token.prev_token
|
45
|
+
first_param_name_token.prev_token = ensure_param_name_token.prev_token
|
46
|
+
ensure_param_name_token.prev_token = prev_token
|
47
|
+
|
48
|
+
prev_code_token = first_param_name_token.prev_code_token
|
49
|
+
first_param_name_token.prev_code_token = ensure_param_name_token.prev_code_token
|
50
|
+
ensure_param_name_token.prev_code_token = prev_code_token
|
51
|
+
|
52
|
+
next_token = first_param_comma_token.next_token
|
53
|
+
first_param_comma_token = ensure_param_comma_token.next_token
|
54
|
+
ensure_param_comma_token.next_token = next_token
|
55
|
+
|
56
|
+
next_code_token = first_param_comma_token.next_code_token
|
57
|
+
first_param_comma_code_token = ensure_param_comma_token.next_code_token
|
58
|
+
ensure_param_comma_token.next_code_token = next_code_token
|
59
|
+
|
60
|
+
# Update index
|
61
|
+
ensure_tmp = tokens.slice!(ensure_param_name_idx..ensure_param_comma_idx-1)
|
62
|
+
first_tmp = tokens.slice!(first_param_name_idx..first_param_comma_idx-1)
|
63
|
+
ensure_tmp.reverse_each do |item|
|
64
|
+
tokens.insert(first_param_name_idx, item)
|
65
|
+
end
|
66
|
+
first_tmp.reverse_each do |item|
|
67
|
+
tokens.insert(ensure_param_name_idx + ensure_tmp.length - first_tmp.length, item)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Public: Check the tokens of each File resource instance for an ensure
|
2
|
+
# parameter and record a warning if the value of that parameter looks like
|
3
|
+
# a symlink target (starts with a '/').
|
4
|
+
#
|
5
|
+
# https://docs.puppet.com/guides/style_guide.html#symbolic-links
|
6
|
+
PuppetLint.new_check(:ensure_not_symlink_target) do
|
7
|
+
def check
|
8
|
+
resource_indexes.each do |resource|
|
9
|
+
if resource[:type].value == "file"
|
10
|
+
resource[:param_tokens].select { |param_token|
|
11
|
+
param_token.value == 'ensure'
|
12
|
+
}.each do |ensure_token|
|
13
|
+
value_token = ensure_token.next_code_token.next_code_token
|
14
|
+
if value_token.value.start_with? '/'
|
15
|
+
notify :warning, {
|
16
|
+
:message => 'symlink target specified in ensure attr',
|
17
|
+
:line => value_token.line,
|
18
|
+
:column => value_token.column,
|
19
|
+
:param_token => ensure_token,
|
20
|
+
:value_token => value_token,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def fix(problem)
|
29
|
+
index = tokens.index(problem[:value_token])
|
30
|
+
|
31
|
+
[
|
32
|
+
PuppetLint::Lexer::Token.new(:NAME, 'symlink', 0, 0),
|
33
|
+
PuppetLint::Lexer::Token.new(:COMMA, ',', 0, 0),
|
34
|
+
PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0),
|
35
|
+
PuppetLint::Lexer::Token.new(:INDENT, problem[:param_token].prev_token.value.dup, 0, 0),
|
36
|
+
PuppetLint::Lexer::Token.new(:NAME, 'target', 0, 0),
|
37
|
+
PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
|
38
|
+
PuppetLint::Lexer::Token.new(:FARROW, '=>', 0, 0),
|
39
|
+
PuppetLint::Lexer::Token.new(:WHITESPACE, ' ', 0, 0),
|
40
|
+
].reverse.each do |new_token|
|
41
|
+
tokens.insert(index, new_token)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Public: Check the tokens of each File resource instance for a mode
|
2
|
+
# parameter and if found, record a warning if the value of that parameter is
|
3
|
+
# not a 4 digit octal value (0755) or a symbolic mode ('o=rwx,g+r').
|
4
|
+
#
|
5
|
+
# https://docs.puppet.com/guides/style_guide.html#file-modes
|
6
|
+
PuppetLint.new_check(:file_mode) do
|
7
|
+
MSG = 'mode should be represented as a 4 digit octal value or symbolic mode'
|
8
|
+
SYM_RE = "([ugoa]*[-=+][-=+rstwxXugo]*)(,[ugoa]*[-=+][-=+rstwxXugo]*)*"
|
9
|
+
IGNORE_TYPES = Set[:VARIABLE, :UNDEF, :FUNCTION_NAME]
|
10
|
+
MODE_RE = Regexp.new(/\A([0-7]{4}|#{SYM_RE})\Z/)
|
11
|
+
|
12
|
+
def check
|
13
|
+
resource_indexes.each do |resource|
|
14
|
+
if resource[:type].value == "file" or resource[:type].value == "concat"
|
15
|
+
resource[:param_tokens].select { |param_token|
|
16
|
+
param_token.value == 'mode'
|
17
|
+
}.each do |param_token|
|
18
|
+
value_token = param_token.next_code_token.next_code_token
|
19
|
+
|
20
|
+
break if IGNORE_TYPES.include?(value_token.type)
|
21
|
+
break if value_token.value =~ MODE_RE
|
22
|
+
|
23
|
+
notify :warning, {
|
24
|
+
:message => MSG,
|
25
|
+
:line => value_token.line,
|
26
|
+
:column => value_token.column,
|
27
|
+
:token => value_token,
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def fix(problem)
|
35
|
+
if problem[:token].value =~ /\A[0-7]{3}\Z/
|
36
|
+
problem[:token].type = :SSTRING
|
37
|
+
problem[:token].value = "0#{problem[:token].value.to_s}"
|
38
|
+
else
|
39
|
+
raise PuppetLint::NoFix
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Public: Check the tokens of each File resource instance for a mode
|
2
|
+
# parameter and if found, record a warning if the value of that parameter is
|
3
|
+
# not a quoted string.
|
4
|
+
#
|
5
|
+
# https://docs.puppet.com/guides/style_guide.html#file-modes
|
6
|
+
PuppetLint.new_check(:unquoted_file_mode) do
|
7
|
+
TOKEN_TYPES = Set[:NAME, :NUMBER]
|
8
|
+
|
9
|
+
def check
|
10
|
+
resource_indexes.each do |resource|
|
11
|
+
if resource[:type].value == "file" or resource[:type].value == "concat"
|
12
|
+
resource[:param_tokens].select { |param_token|
|
13
|
+
param_token.value == 'mode' &&
|
14
|
+
TOKEN_TYPES.include?(param_token.next_code_token.next_code_token.type)
|
15
|
+
}.each do |param_token|
|
16
|
+
value_token = param_token.next_code_token.next_code_token
|
17
|
+
notify :warning, {
|
18
|
+
:message => 'unquoted file mode',
|
19
|
+
:line => value_token.line,
|
20
|
+
:column => value_token.column,
|
21
|
+
:token => value_token,
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def fix(problem)
|
29
|
+
problem[:token].type = :SSTRING
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Public: Check the manifest tokens for any resource titles / namevars that
|
2
|
+
# are not quoted and record a warning for each instance found.
|
3
|
+
#
|
4
|
+
# https://docs.puppet.com/guides/style_guide.html#resource-names
|
5
|
+
PuppetLint.new_check(:unquoted_resource_title) do
|
6
|
+
def check
|
7
|
+
title_tokens.each do |token|
|
8
|
+
if token.type == :NAME
|
9
|
+
notify :warning, {
|
10
|
+
:message => 'unquoted resource title',
|
11
|
+
:line => token.line,
|
12
|
+
:column => token.column,
|
13
|
+
:token => token,
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fix(problem)
|
20
|
+
problem[:token].type = :SSTRING
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Public: Check the manifest tokens for any double quoted strings that don't
|
2
|
+
# contain any variables or common escape characters and record a warning for
|
3
|
+
# each instance found.
|
4
|
+
#
|
5
|
+
# https://docs.puppet.com/guides/style_guide.html#quoting
|
6
|
+
PuppetLint.new_check(:double_quoted_strings) do
|
7
|
+
def check
|
8
|
+
tokens.select { |token|
|
9
|
+
token.type == :STRING
|
10
|
+
}.map { |token|
|
11
|
+
[token, token.value.gsub(' '*token.column, "\n")]
|
12
|
+
}.select { |token, sane_value|
|
13
|
+
sane_value[/(\\\$|\\"|\\'|'|\r|\t|\\t|\n|\\n|\\\\)/].nil?
|
14
|
+
}.each do |token, sane_value|
|
15
|
+
notify :warning, {
|
16
|
+
:message => 'double quoted string containing no variables',
|
17
|
+
:line => token.line,
|
18
|
+
:column => token.column,
|
19
|
+
:token => token,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def fix(problem)
|
25
|
+
problem[:token].type = :SSTRING
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Public: Check the manifest tokens for double quoted strings that contain
|
2
|
+
# a single variable only and record a warning for each instance found.
|
3
|
+
#
|
4
|
+
# https://docs.puppet.com/guides/style_guide.html#quoting
|
5
|
+
PuppetLint.new_check(:only_variable_string) do
|
6
|
+
VAR_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
|
7
|
+
|
8
|
+
def check
|
9
|
+
tokens.each_with_index do |start_token, start_token_idx|
|
10
|
+
if start_token.type == :DQPRE and start_token.value == ''
|
11
|
+
var_token = start_token.next_token
|
12
|
+
if VAR_TYPES.include? var_token.type
|
13
|
+
eos_offset = 2
|
14
|
+
loop do
|
15
|
+
eos_token = tokens[start_token_idx + eos_offset]
|
16
|
+
case eos_token.type
|
17
|
+
when :LBRACK
|
18
|
+
eos_offset += 3
|
19
|
+
when :DQPOST
|
20
|
+
if eos_token.value == ''
|
21
|
+
if eos_token.next_code_token && eos_token.next_code_token.type == :FARROW
|
22
|
+
break
|
23
|
+
end
|
24
|
+
notify :warning, {
|
25
|
+
:message => 'string containing only a variable',
|
26
|
+
:line => var_token.line,
|
27
|
+
:column => var_token.column,
|
28
|
+
:start_token => start_token,
|
29
|
+
:var_token => var_token,
|
30
|
+
:end_token => eos_token,
|
31
|
+
}
|
32
|
+
end
|
33
|
+
break
|
34
|
+
else
|
35
|
+
break
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def fix(problem)
|
44
|
+
prev_token = problem[:start_token].prev_token
|
45
|
+
prev_code_token = problem[:start_token].prev_code_token
|
46
|
+
next_token = problem[:end_token].next_token
|
47
|
+
next_code_token = problem[:end_token].next_code_token
|
48
|
+
var_token = problem[:var_token]
|
49
|
+
|
50
|
+
tokens.delete(problem[:start_token])
|
51
|
+
tokens.delete(problem[:end_token])
|
52
|
+
|
53
|
+
prev_token.next_token = var_token unless prev_token.nil?
|
54
|
+
prev_code_token.next_code_token = var_token unless prev_code_token.nil?
|
55
|
+
next_code_token.prev_code_token = var_token unless next_code_token.nil?
|
56
|
+
next_token.prev_token = var_token unless next_token.nil?
|
57
|
+
var_token.type = :VARIABLE
|
58
|
+
var_token.next_token = next_token
|
59
|
+
var_token.next_code_token = next_code_token
|
60
|
+
var_token.prev_code_token = prev_code_token
|
61
|
+
var_token.prev_token = prev_token
|
62
|
+
end
|
63
|
+
end
|