puppet-lint 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|