puppet-lint 4.0.0 → 4.1.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: a7cd6dad7a05e7eefb19f4c9efedc5815b1f83376a77def6fd54b321945c520c
4
- data.tar.gz: d82288ffc965a3f001269abdb42efe6bb71041575b1106e3331b4a70f2a0fe84
3
+ metadata.gz: 3953f32f31f48881c186abdd6a5ce57c2debaf28d24afc4b207a2a84a2065ccf
4
+ data.tar.gz: 60730e1ecb6cbf54f72f23bbb96769d181b9132a2fb756bdc858949e953d3467
5
5
  SHA512:
6
- metadata.gz: b1571f76174d7afaca3da45f692b681aedb4e99a52563c3f3a0171d6db9bbddb9c409f5f21223fbfe249b7254f2d41edb01331b9c154afafb35572f3fdff7e7c
7
- data.tar.gz: e594e8917a7ce55bab177449d1a6db41454dbbaacb37eb4a4f1b0ec9a8cf4e82f5ee023d112ca629d83bceceaba413d281d242f45388207a4c707e7380afc3ab
6
+ metadata.gz: 2421fd601c8e371f8bcfa8ffff3f5f9674fa1334d7ced66e1c0bd4a376c8365822f57b11a6d3ad80e134ea2b6faf6c20281e3497715b34c3c22db163e424cb2e
7
+ data.tar.gz: 5ab8e9650e45521eb84ea8c8f89d0970c90f919bd51e82dc6be73fc5a2b0944875673a16058ad0894288730358772ef82f07540a8ac0230bdb32aa5727abab46
@@ -30,7 +30,7 @@ class PuppetLint::Lexer
30
30
  # etc) in the manifest.
31
31
  attr_accessor :next_code_token
32
32
 
33
- # Public: Gets/sets the previous code tokne (skips whitespace,
33
+ # Public: Gets/sets the previous code token (skips whitespace,
34
34
  # comments, etc) in the manifest.
35
35
  attr_accessor :prev_code_token
36
36
 
@@ -37,7 +37,7 @@ PuppetLint.new_check(:parameter_order) do
37
37
  column: token.column,
38
38
  description: 'Test the manifest tokens for any parameterised classes or defined types that take ' \
39
39
  'parameters and record a warning if there are any optional parameters listed before required parameters.',
40
- help_uri: 'https://puppet.com/docs/puppet/latest/style_guide.html#display-order-of-parameters',
40
+ help_uri: 'https://puppet.com/docs/puppet/latest/style_guide.html#params-display-order',
41
41
  )
42
42
  end
43
43
  end
@@ -48,17 +48,15 @@ PuppetLint.new_check(:parameter_order) do
48
48
  return false unless token.prev_code_token
49
49
 
50
50
  [
51
- :LPAREN, # First parameter, no type specification
52
- :COMMA, # Subsequent parameter, no type specification
53
- :TYPE, # Parameter with simple type specification
54
- :RBRACK, # Parameter with complex type specification
51
+ :LPAREN, # First parameter, no type specification
52
+ :COMMA, # Subsequent parameter, no type specification
53
+ :TYPE, # Parameter with simple type specification
54
+ :RBRACK, # Parameter with complex type specification
55
+ :CLASSREF, # Parameter with custom type specification
55
56
  ].include?(token.prev_code_token.type)
56
57
  end
57
58
 
58
59
  def required_parameter?(token)
59
- data_type = token.prev_token_of(:TYPE, skip_blocks: true)
60
- return false if data_type && data_type.value == 'Optional'
61
-
62
60
  return !(token.prev_code_token && token.prev_code_token.type == :EQUALS) if token.next_code_token.nil? || [:COMMA, :RPAREN].include?(token.next_code_token.type)
63
61
 
64
62
  false
@@ -0,0 +1,130 @@
1
+ COMMANDS = Array['command', 'onlyif', 'unless']
2
+ INTERPOLATED_STRINGS = Array[:DQPRE, :DQMID]
3
+ USELESS_CHARS = Array[:WHITESPACE, :COMMA]
4
+
5
+ PuppetLint.new_check(:check_unsafe_interpolations) do
6
+ def check
7
+ # Gather any exec commands' resources into an array
8
+ exec_resources = resource_indexes.filter_map do |resource|
9
+ resource_parameters = resource[:param_tokens].map(&:value)
10
+ resource if resource[:type].value == 'exec' && !(COMMANDS & resource_parameters).empty?
11
+ end
12
+
13
+ # Iterate over title tokens and raise a warning if any are variables
14
+ unless get_exec_titles.empty?
15
+ get_exec_titles.each do |title|
16
+ check_unsafe_title(title)
17
+ end
18
+ end
19
+
20
+ # Iterate over each command found in any exec
21
+ exec_resources.each do |command_resources|
22
+ check_unsafe_interpolations(command_resources)
23
+ end
24
+ end
25
+
26
+ # Iterate over the tokens in a title and raise a warning if an interpolated variable is found
27
+ def check_unsafe_title(title)
28
+ title.each do |token|
29
+ notify_warning(token.next_code_token) if interpolated?(token)
30
+ end
31
+ end
32
+
33
+ # Iterates over an exec resource and if a command, onlyif or unless paramter is found, it is checked for unsafe interpolations
34
+ def check_unsafe_interpolations(command_resources)
35
+ command_resources[:tokens].each do |token|
36
+ # Skip iteration if token isn't a command of type :NAME
37
+ next unless COMMANDS.include?(token.value) && token.type == :NAME
38
+ # Don't check the command if it is parameterised
39
+ next if parameterised?(token)
40
+
41
+ check_command(token).each do |t|
42
+ notify_warning(t)
43
+ end
44
+ end
45
+ end
46
+
47
+ # Raises a warning given a token and message
48
+ def notify_warning(token)
49
+ notify :warning,
50
+ message: "unsafe interpolation of variable '#{token.value}' in exec command",
51
+ line: token.line,
52
+ column: token.column
53
+ end
54
+
55
+ # Iterates over the tokens in a command and adds it to an array of violations if it is an input variable
56
+ def check_command(token)
57
+ # Initialise variables needed in while loop
58
+ rule_violations = []
59
+ current_token = token
60
+
61
+ # Iterate through tokens in command
62
+ while current_token.type != :NEWLINE
63
+ # Check if token is a varibale and if it is parameterised
64
+ rule_violations.append(current_token.next_code_token) if interpolated?(current_token)
65
+ current_token = current_token.next_token
66
+ end
67
+
68
+ rule_violations
69
+ end
70
+
71
+ # A command is parameterised if its args are placed in an array
72
+ # This function checks if the current token is a :FARROW and if so, if it is followed by an LBRACK
73
+ def parameterised?(token)
74
+ current_token = token
75
+ while current_token.type != :NEWLINE
76
+ return true if current_token.type == :FARROW && current_token.next_token.next_token.type == :LBRACK
77
+
78
+ current_token = current_token.next_token
79
+ end
80
+ end
81
+
82
+ # This function is a replacement for puppet_lint's title_tokens function which assumes titles have single quotes
83
+ # This function adds a check for titles in double quotes where there could be interpolated variables
84
+ def get_exec_titles
85
+ result = []
86
+ tokens.each_with_index do |_token, token_idx|
87
+ next if tokens[token_idx].value != 'exec'
88
+
89
+ # We have a resource declaration. Now find the title
90
+ tokens_array = []
91
+ # Check if title is an array
92
+ if tokens[token_idx]&.next_code_token&.next_code_token&.type == :LBRACK
93
+ # Get the start and end indices of the array of titles
94
+ array_start_idx = tokens.rindex { |r| r.type == :LBRACK }
95
+ array_end_idx = tokens.rindex { |r| r.type == :RBRACK }
96
+
97
+ # Grab everything within the array
98
+ title_array_tokens = tokens[(array_start_idx + 1)..(array_end_idx - 1)]
99
+ tokens_array.concat(title_array_tokens.reject do |token|
100
+ USELESS_CHARS.include?(token.type)
101
+ end)
102
+ result << tokens_array
103
+ # Check if title is double quotes string
104
+ elsif tokens[token_idx].next_code_token.next_code_token.type == :DQPRE
105
+ # Find the start and end of the title
106
+ title_start_idx = tokens.find_index(tokens[token_idx].next_code_token.next_code_token)
107
+ title_end_idx = title_start_idx + index_offset_for(':', tokens[title_start_idx..tokens.length])
108
+
109
+ result << tokens[title_start_idx..title_end_idx]
110
+ # Title is in single quotes
111
+ else
112
+ tokens_array.concat([tokens[token_idx].next_code_token.next_code_token])
113
+
114
+ result << tokens_array
115
+ end
116
+ end
117
+ result
118
+ end
119
+
120
+ def interpolated?(token)
121
+ INTERPOLATED_STRINGS.include?(token.type)
122
+ end
123
+
124
+ # Finds the index offset of the next instance of `value` in `tokens_slice` from the original index
125
+ def index_offset_for(value, tokens_slice)
126
+ tokens_slice.each_with_index do |token, i|
127
+ return i if value.include?(token.value)
128
+ end
129
+ end
130
+ end
@@ -115,14 +115,9 @@ PuppetLint.new_check(:legacy_facts) do
115
115
  tokens.select { |x| LEGACY_FACTS_VAR_TYPES.include?(x.type) }.each do |token|
116
116
  fact_name = ''
117
117
 
118
- # This matches legacy facts defined in the fact hash that use the top scope
119
- # fact assignment.
120
- if token.value.start_with?('::facts[')
121
- fact_name = token.value.match(%r{::facts\['(.*)'\]})[1]
122
-
123
118
  # This matches legacy facts defined in the fact hash.
124
- elsif token.value.start_with?("facts['")
125
- fact_name = token.value.match(%r{facts\['(.*)'\]})[1]
119
+ if (match = (token.value.match(%r{(::)?facts\['(.*)'\]}) || token.value.match(%r{(::)?facts\[(.*)\]})))
120
+ fact_name = match[2]
126
121
 
127
122
  # This matches using legacy facts in a the new structured fact. For
128
123
  # example this would match 'uuid' in $facts['uuid'] so it can be converted
@@ -17,7 +17,17 @@ TOP_SCOPE_FACTS_VAR_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
17
17
 
18
18
  PuppetLint.new_check(:top_scope_facts) do
19
19
  def check
20
- whitelist = ['trusted', 'facts'] + (PuppetLint.configuration.top_scope_variables || [])
20
+ whitelist = ['trusted', 'facts', 'architecture', 'augeasversion', 'bios_release_date', 'bios_vendor', 'bios_version',
21
+ 'boardassettag', 'boardmanufacturer', 'boardproductname', 'boardserialnumber', 'chassisassettag', 'chassistype', 'domain',
22
+ 'fqdn', 'gid', 'hardwareisa', 'hardwaremodel', 'hostname', 'id', 'ipaddress', 'ipaddress6', 'lsbdistcodename',
23
+ 'lsbdistdescription', 'lsbdistid', 'lsbdistrelease', 'lsbmajdistrelease', 'lsbminordistrelease', 'lsbrelease',
24
+ 'macaddress', 'macosx_buildversion', 'macosx_productname', 'macosx_productversion', 'macosx_productversion_major',
25
+ 'macosx_productversion_minor', 'manufacturer', 'memoryfree', 'memorysize', 'netmask', 'netmask6', 'network', 'network6',
26
+ 'operatingsystem', 'operatingsystemmajrelease', 'operatingsystemrelease', 'osfamily', 'physicalprocessorcount',
27
+ 'processorcount', 'productname', 'rubyplatform', 'rubysitedir', 'rubyversion', 'selinux', 'selinux_config_mode',
28
+ 'selinux_config_policy', 'selinux_current_mode', 'selinux_enforced', 'selinux_policyversion', 'serialnumber',
29
+ 'swapencrypted', 'swapfree', 'swapsize', 'system32', 'uptime', 'uptime_days', 'uptime_hours', 'uptime_seconds',
30
+ 'uuid', 'xendomains', 'zonename'] + (PuppetLint.configuration.top_scope_variables || [])
21
31
  whitelist = whitelist.join('|')
22
32
  tokens.select { |x| TOP_SCOPE_FACTS_VAR_TYPES.include?(x.type) }.each do |token|
23
33
  next unless %r{^::}.match?(token.value)
@@ -1,3 +1,3 @@
1
1
  class PuppetLint
2
- VERSION = '4.0.0'.freeze
2
+ VERSION = '4.1.0'.freeze
3
3
  end
@@ -33,6 +33,6 @@
33
33
  }
34
34
  },
35
35
  "fingerprint": "e34cf289e008446b633d1be7cf58120e",
36
- "content": "Test the manifest tokens for any parameterised classes or defined types that take parameters and record a warning if there are any optional parameters listed before required parameters. See [this page](https://puppet.com/docs/puppet/latest/style_guide.html#display-order-of-parameters) for more information about the `parameter_order` check."
36
+ "content": "Test the manifest tokens for any parameterised classes or defined types that take parameters and record a warning if there are any optional parameters listed before required parameters. See [this page](https://puppet.com/docs/puppet/latest/style_guide.html#params-display-order) for more information about the `parameter_order` check."
37
37
  }
38
38
  ]
@@ -135,19 +135,6 @@ describe 'parameter_order' do
135
135
  it { expect(problems).to have(0).problem }
136
136
  end
137
137
 
138
- context "#{type} parameter with Optional data type" do
139
- let(:code) do
140
- <<-END
141
- #{type} test(
142
- String $test = 'value',
143
- Optional[String] $optional,
144
- ) { }
145
- END
146
- end
147
-
148
- it { expect(problems).to have(0).problems }
149
- end
150
-
151
138
  context "#{type} parameter with array operation" do
152
139
  let(:code) do
153
140
  <<-END
@@ -165,5 +152,72 @@ describe 'parameter_order' do
165
152
 
166
153
  it { expect(problems).to have(0).problems }
167
154
  end
155
+
156
+ context "#{type} parameters of Optional type are just regular parameters" do
157
+ let(:code) do
158
+ <<-END
159
+ #{type} test (
160
+ String $param1 = '',
161
+ Optional[Boolean] $param2,
162
+ ) { }
163
+ END
164
+ end
165
+
166
+ it { expect(problems).to have(1).problems }
167
+ end
168
+
169
+ [['Custom::Type1', 'Custom::Type2'], ['Custom::Type1', 'String'], ['String', 'Custom::Type2']].each_with_index do |testtypes, i| # rubocop:disable Performance/CollectionLiteralInLoop
170
+ context "#{type} parameters of custom type - no values - #{i}" do
171
+ let(:code) do
172
+ <<-END
173
+ #{type} test (
174
+ #{testtypes[0]} $param1,
175
+ #{testtypes[0]} $param2,
176
+ ) { }
177
+ END
178
+ end
179
+
180
+ it { expect(problems).to have(0).problems }
181
+ end
182
+
183
+ context "#{type} parameters of custom type - two values - #{i}" do
184
+ let(:code) do
185
+ <<-END
186
+ #{type} test (
187
+ #{testtypes[0]} $param1 = 'foo',
188
+ #{testtypes[1]} $param2 = 'bar',
189
+ ) { }
190
+ END
191
+ end
192
+
193
+ it { expect(problems).to have(0).problems }
194
+ end
195
+
196
+ context "#{type} parameters of custom type - one value, wrong order - #{i}" do
197
+ let(:code) do
198
+ <<-END
199
+ #{type} test (
200
+ #{testtypes[0]} $param1 = 'foo',
201
+ #{testtypes[1]} $param2,
202
+ ) { }
203
+ END
204
+ end
205
+
206
+ it { expect(problems).to have(1).problems }
207
+ end
208
+
209
+ context "#{type} parameters of custom type - one value, right order - #{i}" do
210
+ let(:code) do
211
+ <<-END
212
+ #{type} test (
213
+ #{testtypes[0]} $param1,
214
+ #{testtypes[1]} $param2 = 'bar',
215
+ ) { }
216
+ END
217
+ end
218
+
219
+ it { expect(problems).to have(0).problems }
220
+ end
221
+ end
168
222
  end
169
223
  end
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'check_unsafe_interpolations' do
4
+ let(:msg) { "unsafe interpolation of variable 'foo' in exec command" }
5
+
6
+ context 'with fix disabled' do
7
+ context 'exec with unsafe interpolation in command' do
8
+ let(:code) do
9
+ <<-PUPPET
10
+ class foo {
11
+
12
+ exec { 'bar':
13
+ command => "echo ${foo}",
14
+ }
15
+
16
+ }
17
+ PUPPET
18
+ end
19
+
20
+ it 'detects an unsafe exec command argument' do
21
+ expect(problems).to have(1).problems
22
+ end
23
+
24
+ it 'creates one warning' do
25
+ expect(problems).to contain_warning(msg)
26
+ end
27
+ end
28
+
29
+ context 'exec with multiple unsafe interpolations in command' do
30
+ let(:code) do
31
+ <<-PUPPET
32
+ class foo {
33
+
34
+ exec { 'bar':
35
+ command => "echo ${foo} ${bar}",
36
+ }
37
+
38
+ }
39
+ PUPPET
40
+ end
41
+
42
+ it 'detects multiple unsafe exec command arguments' do
43
+ expect(problems).to have(2).problems
44
+ end
45
+
46
+ it 'creates two warnings' do
47
+ expect(problems).to contain_warning(msg)
48
+ expect(problems).to contain_warning(msg)
49
+ end
50
+ end
51
+
52
+ context 'code that uses title with unsafe string as command' do
53
+ let(:code) do
54
+ <<-PUPPET
55
+ class foo {
56
+
57
+ exec { "echo ${foo}": }
58
+
59
+ }
60
+ PUPPET
61
+ end
62
+
63
+ it 'detects one problem' do
64
+ expect(problems).to have(1).problems
65
+ end
66
+
67
+ it 'creates one warning' do
68
+ expect(problems).to contain_warning(msg)
69
+ end
70
+ end
71
+
72
+ context 'exec with a safe string in command' do
73
+ let(:code) do
74
+ <<-PUPPET
75
+ class foo {
76
+
77
+ exec { 'bar':
78
+ command => "echo foo",
79
+ }
80
+
81
+ }
82
+ PUPPET
83
+ end
84
+
85
+ it 'detects zero problems' do
86
+ expect(problems).to have(0).problems
87
+ end
88
+ end
89
+
90
+ context 'exec that has an array of args in command' do
91
+ let(:code) do
92
+ <<-PUPPET
93
+ class foo {
94
+
95
+ exec { 'bar':
96
+ command => ['echo', $foo],
97
+ }
98
+ }
99
+ PUPPET
100
+ end
101
+
102
+ it 'detects zero problems' do
103
+ expect(problems).to have(0).problems
104
+ end
105
+ end
106
+
107
+ context 'exec that has an array of args in command' do
108
+ let(:code) do
109
+ <<-PUPPET
110
+ class foo {
111
+
112
+ exec { ["foo", "bar", "baz"]:
113
+ command => echo qux,
114
+ }
115
+ }
116
+ PUPPET
117
+ end
118
+
119
+ it 'detects zero problems' do
120
+ expect(problems).to have(0).problems
121
+ end
122
+ end
123
+
124
+ context 'file resource' do
125
+ let(:code) do
126
+ <<-PUPPET
127
+ class foo {
128
+ file { '/etc/bar':
129
+ ensure => file,
130
+ backup => false,
131
+ content => $baz,
132
+ }
133
+ }
134
+ PUPPET
135
+ end
136
+
137
+ it 'detects zero problems' do
138
+ expect(problems).to have(0).problems
139
+ end
140
+ end
141
+
142
+ context 'file resource and an exec with unsafe interpolation in command' do
143
+ let(:code) do
144
+ <<-PUPPET
145
+ class foo {
146
+ file { '/etc/bar':
147
+ ensure => file,
148
+ backup => false,
149
+ content => $baz,
150
+ }
151
+
152
+ exec { 'qux':
153
+ command => "echo ${foo}",
154
+ }
155
+ }
156
+ PUPPET
157
+ end
158
+
159
+ it 'detects one problem' do
160
+ expect(problems).to have(1).problems
161
+ end
162
+ end
163
+
164
+ context 'case statement and an exec' do
165
+ let(:code) do
166
+ <<-PUPPET
167
+ class foo {
168
+ case bar {
169
+ baz : {
170
+ echo qux
171
+ }
172
+ }
173
+
174
+ exec { 'foo':
175
+ command => "echo bar",
176
+ }
177
+ }
178
+ PUPPET
179
+ end
180
+
181
+ it 'detects zero problems' do
182
+ expect(problems).to have(0).problems
183
+ end
184
+ end
185
+ end
186
+ end
@@ -121,6 +121,14 @@ describe 'legacy_facts' do
121
121
  expect(problems).to have(1).problem
122
122
  end
123
123
  end
124
+
125
+ context 'top scoped fact variable using unquoted legacy facts hash variable in interpolation' do
126
+ let(:code) { '$::facts[osfamily]' }
127
+
128
+ it 'detects a single problem' do
129
+ expect(problems).to have(1).problem
130
+ end
131
+ end
124
132
  end
125
133
 
126
134
  context 'with fix enabled' do
@@ -37,26 +37,10 @@ describe 'top_scope_facts' do
37
37
  end
38
38
 
39
39
  context 'fact variable using top scope' do
40
- let(:code) { '$::operatingsystem' }
40
+ let(:code) { '$::fqdn' }
41
41
 
42
- it 'onlies detect a single problem' do
43
- expect(problems).to have(1).problem
44
- end
45
-
46
- it 'creates a warning' do
47
- expect(problems).to contain_warning(msg).on_line(1).in_column(1)
48
- end
49
- end
50
-
51
- context 'fact variable using top scope with curly braces in double quote' do
52
- let(:code) { '"${::operatingsystem}"' }
53
-
54
- it 'onlies detect a single problem' do
55
- expect(problems).to have(1).problem
56
- end
57
-
58
- it 'creates a warning' do
59
- expect(problems).to contain_warning(msg).on_line(1).in_column(4)
42
+ it 'does not detect a single problem' do
43
+ expect(problems).to have(0).problem
60
44
  end
61
45
  end
62
46
 
@@ -126,34 +110,6 @@ describe 'top_scope_facts' do
126
110
  end
127
111
  end
128
112
 
129
- context 'fact variable using top scope' do
130
- let(:code) { '$::operatingsystem' }
131
-
132
- it 'onlies detect a single problem' do
133
- expect(problems).to have(1).problem
134
- end
135
-
136
- it 'fixes the problem' do
137
- expect(problems).to contain_fixed(msg).on_line(1).in_column(1)
138
- end
139
-
140
- it 'shoulds use the facts hash' do
141
- expect(manifest).to eq("$facts['operatingsystem']")
142
- end
143
- end
144
-
145
- context 'fact variable using top scope with curly braces in double quote' do
146
- let(:code) { '"${::operatingsystem}"' }
147
-
148
- it 'fixes the problem' do
149
- expect(problems).to contain_fixed(msg).on_line(1).in_column(4)
150
- end
151
-
152
- it 'shoulds use the facts hash' do
153
- expect(manifest).to eq('"${facts[\'operatingsystem\']}"')
154
- end
155
- end
156
-
157
113
  context 'with custom top scope fact variables' do
158
114
  before(:each) do
159
115
  PuppetLint.configuration.top_scope_variables = ['location', 'role']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Sharpe
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-04-21 00:00:00.000000000 Z
13
+ date: 2023-08-25 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"
@@ -66,6 +66,7 @@ files:
66
66
  - lib/puppet-lint/plugins/check_strings/quoted_booleans.rb
67
67
  - lib/puppet-lint/plugins/check_strings/single_quote_string_with_variables.rb
68
68
  - lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb
69
+ - lib/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations.rb
69
70
  - lib/puppet-lint/plugins/check_variables/variable_contains_dash.rb
70
71
  - lib/puppet-lint/plugins/check_variables/variable_is_lowercase.rb
71
72
  - lib/puppet-lint/plugins/check_whitespace/140chars.rb
@@ -139,6 +140,7 @@ files:
139
140
  - spec/unit/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb
140
141
  - spec/unit/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb
141
142
  - spec/unit/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb
143
+ - spec/unit/puppet-lint/plugins/check_unsafe_interpolations/check_unsafe_interpolations_spec.rb
142
144
  - spec/unit/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb
143
145
  - spec/unit/puppet-lint/plugins/check_variables/variable_is_lowercase_spec.rb
144
146
  - spec/unit/puppet-lint/plugins/check_whitespace/140chars_spec.rb