puppet-lint-nine-check 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bd04cd6c797fc8dfcfa90947cf9fa8464765f17da05128333b5d60ef24d7bd5
4
- data.tar.gz: ebbb400e531834f99523e76881e0b874c0d0b341323714ed20d6555bcca2c981
3
+ metadata.gz: c4708a12e4b0252d046a69e52f62ca9296daab1e6f0d356a16f712df5d56df5b
4
+ data.tar.gz: a903c154bc715a5dfd8c21a77eccff6ceb2baaeeaf4412a794d4b6bcea83bf44
5
5
  SHA512:
6
- metadata.gz: a195b46f95951a594d854b5301e5093734d044f1d24fc1d4c3fd1f1c72bfa2c482e6feefd625df9cd331255c10724135aa8da5f43a610d2d06e270b263b13f9a
7
- data.tar.gz: 632e08c48a1a0a1549c14c4b7738a7a77390c4d09d80e55a95d0b517b8c68186fe030587d1244faf613eb61cf5cf50cc319180586f9ba7c7fb97a57516d06e98
6
+ metadata.gz: b56ffb029e88553a11a87a9c4f819cb54e985dc19e62e50032f4c5b8c2ab5efce592073405a809ed53d153aa26087fb67bb3e0553789256b16facf196cf33fee
7
+ data.tar.gz: 677c848e83b23cbc1b2488e922b75a6471e31145a9ac6c7961be63442369cfba9bc3308d8a8b387df76048f5dac936b380fa3305ad885ab719903d947ec87d57
@@ -0,0 +1,158 @@
1
+ # https://github.com/anhpt379/puppet-lint-class_alignment-check/blob/961d5457b0b6aa1eb10f3ceb543f90115b572f37/lib/puppet-lint/plugins/check_class_helper.rb
2
+ #
3
+ # Copyright (c) 2011 Tim Sharpe
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+
25
+ module ClassAlignment
26
+ class Helper
27
+ class << self
28
+ def a_param?(token)
29
+ if token&.prev_code_token&.type == :EQUALS
30
+ false
31
+ elsif token&.prev_code_token&.type == :FARROW
32
+ false
33
+ elsif %i[DQPRE DQMID].include?(token&.prev_code_token&.type)
34
+ false
35
+ elsif token&.type == :VARIABLE
36
+ # first var in the class
37
+ return true if token&.prev_token_of(:CLASS)&.next_token_of(:LPAREN)&.next_token_of(:VARIABLE) == token
38
+ return true if token&.prev_token_of(:DEFINE)&.next_token_of(:LPAREN)&.next_token_of(:VARIABLE) == token
39
+
40
+ count = 0
41
+ saw_a_comma = false
42
+ while token&.prev_token
43
+ token = token.prev_token
44
+
45
+ saw_a_comma = true if token.type == :COMMA
46
+
47
+ return false if token.type == :EQUALS && count == 0 && saw_a_comma == false
48
+
49
+ if %i[RPAREN RBRACK RBRACE].include?(token.type)
50
+ count -= 1
51
+ elsif %i[LPAREN LBRACK LBRACE].include?(token.type)
52
+ count += 1
53
+ end
54
+
55
+ break if %i[CLASS DEFINE].include?(token.type)
56
+ end
57
+
58
+ true if count == 1
59
+ end
60
+ end
61
+
62
+ def first_on_the_line?(token, type)
63
+ origin = token
64
+ while token&.prev_token
65
+ token = token.prev_token
66
+
67
+ break if token.type == :NEWLINE
68
+ end
69
+
70
+ while token&.next_token
71
+ token = token.next_token
72
+
73
+ break if token.type == type
74
+ end
75
+
76
+ origin == token
77
+ end
78
+
79
+ def the_one?(token, character)
80
+ case character
81
+ when "="
82
+ true if token.type == :EQUALS && first_on_the_line?(token, :EQUALS)
83
+ when "$"
84
+ true if a_param?(token) && first_on_the_line?(token, :VARIABLE)
85
+ end
86
+ end
87
+
88
+ def get_the_first_param(token)
89
+ while token&.prev_code_token
90
+ token = token.prev_code_token
91
+ break if token.type == :CLASS
92
+ end
93
+
94
+ while token&.next_code_token
95
+ token = token.next_code_token
96
+ return token if token.type == :VARIABLE
97
+ end
98
+ end
99
+
100
+ def get_prev_code_token(token, character)
101
+ case character
102
+ when "="
103
+ token.prev_code_token
104
+ when "$"
105
+ if token.prev_code_token
106
+ if %i[CLASSREF RBRACK].include?(token.prev_code_token.type)
107
+ token.prev_code_token
108
+ elsif token.prev_code_token.type == :LPAREN
109
+ token
110
+ elsif token.prev_code_token.type == :COMMA
111
+ get_the_first_param(token)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ def get_param_start_token(token)
118
+ return nil unless a_param?(token)
119
+
120
+ case token&.prev_code_token&.type
121
+
122
+ # Integer $db_port
123
+ when :TYPE
124
+ token.prev_code_token
125
+
126
+ when :CLASSREF
127
+ token.prev_code_token
128
+
129
+ # Variant[Undef, Enum['UNSET'], Stdlib::Port] $db_port
130
+ when :RBRACK
131
+ count = 0
132
+ while token&.prev_code_token
133
+ token = token.prev_code_token
134
+ case token.type
135
+ when :RBRACK
136
+ count += 1
137
+ when :LBRACK
138
+ count -= 1
139
+ end
140
+
141
+ break if count.zero?
142
+ end
143
+ token.prev_code_token
144
+
145
+ else
146
+ token
147
+ end
148
+ end
149
+
150
+ def get_prev_param_token(token)
151
+ while token&.prev_code_token
152
+ token = token.prev_code_token
153
+ return token if a_param?(token)
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,155 @@
1
+ # https://github.com/anhpt379/puppet-lint-class_alignment-check/blob/b62e5c52568fca00413669df745453ff80c76a91/lib/puppet-lint/plugins/check_class_alignment.rb
2
+ #
3
+ # Copyright (c) 2011 Tim Sharpe
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ # Parameters to classes or defined types must be uniformly indented in two
25
+ # spaces from the title. The equals sign should be aligned.
26
+ #
27
+ # https://puppet.com/docs/puppet/7/style_guide.html#style_guide_classes-param-indentation-alignment
28
+
29
+ require_relative "class_alignment/helper"
30
+
31
+ # This function is copied & modified from puppet-lint arrow_alignment check
32
+ # https://github.com/puppetlabs/puppet-lint/blob/020143b705b023946739eb44e7c7d99fcd087527/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb#L8
33
+ def check_for(character)
34
+ # I intentionally didn't rename `arrow` to another name, to keep the code as
35
+ # similar as the original one, to easier to update in the future.
36
+ (class_indexes + defined_type_indexes).each do |res_idx|
37
+ arrow_column = [0]
38
+ level_idx = 0
39
+ level_tokens = []
40
+ param_column = [nil]
41
+ resource_tokens = res_idx[:param_tokens]
42
+ next if resource_tokens.nil?
43
+
44
+ resource_tokens.reject! do |token|
45
+ COMMENT_TYPES.include?(token.type)
46
+ end
47
+
48
+ # If this is a single line resource, skip it
49
+ first_arrow = resource_tokens.index { |r| ClassAlignment::Helper.the_one?(r, character) }
50
+ last_arrow = resource_tokens.rindex { |r| ClassAlignment::Helper.the_one?(r, character) }
51
+ next if first_arrow.nil?
52
+ next if last_arrow.nil?
53
+ next if resource_tokens[first_arrow].line == resource_tokens[last_arrow].line
54
+
55
+ resource_tokens.each do |token|
56
+ if ClassAlignment::Helper.the_one?(token, character)
57
+ param_token = ClassAlignment::Helper.get_prev_code_token(token, character)
58
+ param_token = token if param_token.nil?
59
+
60
+ param_length = param_token.to_manifest.length
61
+
62
+ param_column[level_idx] = param_token.column if param_column[level_idx].nil?
63
+
64
+ if (level_tokens[level_idx] ||= []).any? { |t| t.line == token.line }
65
+ this_arrow_column = param_column[level_idx] + param_length + 1
66
+ elsif character == "$" && param_token.type == :VARIABLE
67
+ this_arrow_column = param_token.column
68
+ else
69
+ this_arrow_column = param_token.column + param_token.to_manifest.length
70
+ this_arrow_column += 1 if param_token.type != :INDENT
71
+ end
72
+
73
+ arrow_column[level_idx] = this_arrow_column if arrow_column[level_idx] < this_arrow_column
74
+
75
+ (level_tokens[level_idx] ||= []) << token
76
+ elsif token == resource_tokens[0]
77
+ level_idx += 1
78
+ arrow_column << 0
79
+ level_tokens[level_idx] ||= []
80
+ param_column << nil
81
+ elsif token == resource_tokens[-1]
82
+ if (level_tokens[level_idx] ||= []).map(&:line).uniq.length > 1
83
+ level_tokens[level_idx].each do |arrow_tok|
84
+ next if arrow_tok.column == arrow_column[level_idx] || level_tokens[level_idx].size == 1
85
+
86
+ arrows_on_line = level_tokens[level_idx].select { |t| t.line == arrow_tok.line }
87
+ notify(
88
+ :warning,
89
+ message: "indentation of #{character} is not properly aligned (expected in column #{arrow_column[level_idx]}, but found it in column #{arrow_tok.column})",
90
+ line: arrow_tok.line,
91
+ column: arrow_tok.column,
92
+ token: arrow_tok,
93
+ arrow_column: arrow_column[level_idx],
94
+ newline: arrows_on_line.index(arrow_tok) != 0,
95
+ newline_indent: param_column[level_idx] - 1
96
+ )
97
+ end
98
+ end
99
+ arrow_column[level_idx] = 0
100
+ level_tokens[level_idx].clear
101
+ param_column[level_idx] = nil
102
+ level_idx -= 1
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ # This function is copied & modified from puppet-lint arrow_alignment fix
109
+ # https://github.com/puppetlabs/puppet-lint/blob/020143b705b023946739eb44e7c7d99fcd087527/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb#L94
110
+ def fix_for(problem)
111
+ raise PuppetLint::NoFix if problem[:newline]
112
+
113
+ new_ws_len = if problem[:token].prev_token.type == :WHITESPACE
114
+ problem[:token].prev_token.to_manifest.length
115
+ else
116
+ 0
117
+ end
118
+ new_ws_len += (problem[:arrow_column] - problem[:token].column)
119
+
120
+ if new_ws_len.negative?
121
+ raise PuppetLint::NoFix if problem[:token].prev_token.type != :INDENT
122
+
123
+ new_ws = problem[:token].prev_token.to_manifest[0...new_ws_len]
124
+ problem[:token].prev_token.value = new_ws
125
+ else
126
+ new_ws = " " * new_ws_len
127
+
128
+ if problem[:token].prev_token.type == :WHITESPACE
129
+ problem[:token].prev_token.value = new_ws
130
+ else
131
+ index = tokens.index(problem[:token].prev_token)
132
+ tokens.insert(index + 1, PuppetLint::Lexer::Token.new(:WHITESPACE, new_ws, 0, 0))
133
+ end
134
+ end
135
+ end
136
+
137
+ PuppetLint.new_check(:class_alignment_params) do
138
+ def check
139
+ check_for("$")
140
+ end
141
+
142
+ def fix(problem)
143
+ fix_for(problem)
144
+ end
145
+ end
146
+
147
+ PuppetLint.new_check(:class_alignment_equals) do
148
+ def check
149
+ check_for("=")
150
+ end
151
+
152
+ def fix(problem)
153
+ fix_for(problem)
154
+ end
155
+ end
@@ -0,0 +1,108 @@
1
+ # https://github.com/anhpt379/puppet-lint-class_alignment-check/blob/961d5457b0b6aa1eb10f3ceb543f90115b572f37/lib/puppet-lint/plugins/check_class_helper.rb
2
+ #
3
+ # Copyright (c) 2011 Tim Sharpe
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+
25
+ require_relative "class_alignment/helper"
26
+
27
+ PuppetLint.new_check(:class_alignment_params_newline) do
28
+ def check
29
+ (class_indexes + defined_type_indexes).each do |item|
30
+ tokens = item[:param_tokens]
31
+ next if tokens.nil?
32
+
33
+ # Skip if line length < 80 chars
34
+ first_paren = tokens[0]&.prev_token_of(:LPAREN)
35
+ last_paren = tokens[-1]&.next_token_of(:RPAREN)
36
+ next if first_paren.nil?
37
+ next if last_paren.nil?
38
+ next if first_paren.line == last_paren.line && last_paren.column < 80
39
+
40
+ tokens.each do |token|
41
+ if token == tokens[-1]
42
+ rparen = token.next_token_of(:RPAREN)
43
+
44
+ last_code_token = token
45
+ while last_code_token&.prev_token
46
+ break unless %i[WHITESPACE INDENT NEWLINE].include?(last_code_token.type)
47
+
48
+ last_code_token = last_code_token.prev_token
49
+ end
50
+
51
+ next if rparen.line != last_code_token.line
52
+
53
+ notify(
54
+ :warning,
55
+ message: "`)` should be in a new line (expected in line #{token.line + 1}, but found it in line #{token.line})",
56
+ line: rparen.line,
57
+ column: rparen.column,
58
+ token: rparen,
59
+ newline: true,
60
+ newline_indent: item[:tokens][0].column - 1
61
+ )
62
+ end
63
+
64
+ next unless ClassAlignment::Helper.a_param?(token)
65
+
66
+ if ClassAlignment::Helper.get_param_start_token(token)&.prev_code_token&.type == :LPAREN
67
+ next if token.line != ClassAlignment::Helper.get_param_start_token(token).prev_code_token.line
68
+ elsif token.line != ClassAlignment::Helper.get_prev_param_token(token)&.line
69
+ next
70
+ end
71
+
72
+ notify(
73
+ :warning,
74
+ message: "`#{token.to_manifest}` should be in a new line (expected in line #{token.line + 1}, but found it in line #{token.line})",
75
+ line: token.line,
76
+ column: token.column,
77
+ token: token,
78
+ newline: true,
79
+ newline_indent: item[:tokens][0].column + 1
80
+ )
81
+ end
82
+ end
83
+ end
84
+
85
+ def fix(problem)
86
+ token = problem[:token]
87
+ token = ClassAlignment::Helper.get_param_start_token(token) if token.type == :VARIABLE
88
+
89
+ last_non_whitespace_token = token.prev_token
90
+ while last_non_whitespace_token&.prev_token
91
+ break unless %i[WHITESPACE INDENT NEWLINE].include?(last_non_whitespace_token.type)
92
+
93
+ last_non_whitespace_token = last_non_whitespace_token.prev_token
94
+ end
95
+
96
+ index = tokens.index(last_non_whitespace_token) + 1
97
+ tokens.insert(index, PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0))
98
+
99
+ # When there's no space at the beginning of the param
100
+ # e.g. class foo($bar="aaa") {}
101
+ if token.prev_code_token.next_token == token
102
+ tokens.insert(index + 1, PuppetLint::Lexer::Token.new(:INDENT, " " * problem[:newline_indent], 0, 0))
103
+
104
+ elsif %i[WHITESPACE INDENT].include?(token.prev_token.type)
105
+ token.prev_token.value = " " * problem[:newline_indent]
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,51 @@
1
+ # https://github.com/deanwilson/puppet-lint-no_symbolic_file_modes-check/blob/bf06d542b222ba4748ec935346a95b628a527f00/lib/puppet-lint/plugins/no_symbolic_file_modes.rb
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2016 Dean Wilson
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ PuppetLint.new_check(:no_symbolic_file_modes) do
26
+ def ignore_type?(type)
27
+ Set[:VARIABLE, :UNDEF].include?(type)
28
+ end
29
+
30
+ def check
31
+ resource_indexes.each do |resource|
32
+ next unless resource[:type].value == "file"
33
+
34
+ param_tokens = resource[:param_tokens].select { |pt| pt.value == "mode" }
35
+
36
+ param_tokens.each do |param_token|
37
+ value_token = param_token.next_code_token.next_code_token
38
+
39
+ break if ignore_type?(value_token.type)
40
+ break if /^[0-7]{4}$/.match?(value_token.value)
41
+
42
+ notify :warning, {
43
+ message: "mode should be a 4 digit octal value, not a symbolic mode",
44
+ line: value_token.line,
45
+ column: value_token.column,
46
+ token: value_token
47
+ }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,70 @@
1
+ # https://github.com/deanwilson/puppet-lint-template_file_extension-check/blob/ae9f1e850293e0c204f1abd876df4be4d560cf81/lib/puppet-lint/plugins/template_file_extension.rb
2
+ #
3
+ # The MIT License (MIT)
4
+ #
5
+ # Copyright (c) 2017 Dean Wilson
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ PuppetLint.new_check(:template_file_extension) do
26
+ def check
27
+ template_extensions = {
28
+ epp: ".epp",
29
+ template: ".erb"
30
+ }
31
+
32
+ # the types a filename may be in a `template()` call
33
+ name_types = %i[DQPOST SSTRING]
34
+
35
+ resource_indexes.each do |resource|
36
+ next unless resource[:type].value == "file"
37
+
38
+ param_tokens = resource[:param_tokens].select { |pt| pt.value == "content" }
39
+
40
+ param_tokens.each do |content_token|
41
+ value_token = content_token.next_code_token.next_code_token
42
+
43
+ if (matched = value_token.value.match(/^(template|epp)$/))
44
+ template_function = matched[1]
45
+ extension = template_extensions[template_function.to_sym]
46
+
47
+ current_token = value_token.next_token
48
+ current_token = current_token.next_token while current_token.type == :WHITESPACE
49
+
50
+ # iterate over all the code tokens until we hit the closing ')'
51
+ until current_token.type == :RPAREN || current_token.type == :LBRACE
52
+ current_token = current_token.next_code_token
53
+
54
+ if (name_types.include? current_token.type) && !current_token.value.end_with?(extension)
55
+ warning = "all #{template_function} file names should end with #{extension}"
56
+
57
+ notify :warning, {
58
+ message: warning,
59
+ line: value_token.line,
60
+ column: value_token.column,
61
+ param_token: content_token,
62
+ value_token: value_token
63
+ }
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end