puppet-lint-class_alignment-check 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2a840e9e2d88d40af098ce22a8a2ca7d8dde090b727f85af6e05f72c84b79c95
4
+ data.tar.gz: be0f893935808ba8c07682dd5bd7457ca686ba8adc973a85a04d40d2785b656d
5
+ SHA512:
6
+ metadata.gz: 4c312626c1d7b3b23584963c138b324ee11b5c1931c6f2bcf1f34a85a9aa95d99850c1fd31fb6ef96659d2646fa3bc4dfa40b516e102bc82944612bb0c5fcf39
7
+ data.tar.gz: 8cd001ccd8620fd4fd4f57ba946d36a23a2115d1ce2c2c0835e30c533f42cc064e426edcbaf87a42ce2d88c2d18ed8efc443bd8f91768fda2c7389329ba29696
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Tim Sharpe
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # puppet-lint-class_alignment-check
2
+
3
+ [![License](https://img.shields.io/github/license/anhpt379/puppet-lint-class_alignment-check.svg)](https://github.com/anhpt379/puppet-lint-class_alignment-check/blob/master/LICENSE)
4
+ [![Test](https://github.com/anhpt379/puppet-lint-class_alignment-check/actions/workflows/test.yml/badge.svg)](https://github.com/anhpt379/puppet-lint-class_alignment-check/actions/workflows/test.yml)
5
+
6
+ A puppet-lint plugin to check and fix class params/equals alignment.
7
+
8
+ ## Usage
9
+
10
+ This plugin provides 2 checks for puppet-lint:
11
+
12
+ - `class_params_alignment`
13
+ - `class_equals_alignment`
14
+
15
+ It supports `--fix` flag.
16
+
17
+ > Parameters to classes or defined types must be uniformly indented in two
18
+ > spaces from the title. The equals sign should be aligned.
19
+ >
20
+ > <https://puppet.com/docs/puppet/7/style_guide.html#style_guide_classes-param-indentation-alignment>
21
+
22
+ ```puppet
23
+ class name (
24
+ $var1 = 'default',
25
+ $var2 = 'something else',
26
+ $another = 'another default value',
27
+ ) {
28
+
29
+ }
30
+ ```
31
+
32
+ ```puppet
33
+ class name (
34
+ Boolean $broadcastclient = false,
35
+ Optional[Stdlib::Absolutepath] $config_dir = undef,
36
+ Enum['running', 'stopped'] $service_ensure = 'running',
37
+ String $package_ensure = 'present',
38
+ ) {
39
+
40
+ }
41
+ ```
@@ -0,0 +1,213 @@
1
+ # Parameters to classes or defined types must be uniformly indented in two
2
+ # spaces from the title. The equals sign should be aligned.
3
+ #
4
+ # https://puppet.com/docs/puppet/7/style_guide.html#style_guide_classes-param-indentation-alignment
5
+
6
+ require 'debug'
7
+
8
+ def a_param?(token)
9
+ if token.prev_code_token.type == :EQUALS
10
+ false
11
+ elsif token.prev_code_token.type == :FARROW
12
+ false
13
+ elsif token.type == :VARIABLE && !%i[DQPRE DQMID].include?(token.prev_code_token.type)
14
+ true
15
+ end
16
+ end
17
+
18
+ def first_param_on_the_line?(token)
19
+ origin = token
20
+ while token&.prev_token
21
+ token = token.prev_token
22
+
23
+ break if token.type == :NEWLINE
24
+ end
25
+
26
+ while token&.next_token
27
+ token = token.next_token
28
+
29
+ break if token.type == :VARIABLE
30
+ end
31
+
32
+ origin == token
33
+ end
34
+
35
+ def the_one?(token, character)
36
+ case character
37
+ when '='
38
+ true if token.type == :EQUALS
39
+ when '$'
40
+ true if token.type == :VARIABLE && a_param?(token) && first_param_on_the_line?(token)
41
+ end
42
+ end
43
+
44
+ def get_the_first_param(token)
45
+ while token&.prev_code_token
46
+ token = token.prev_code_token
47
+ break if token.type == :CLASS
48
+ end
49
+
50
+ while token&.next_code_token
51
+ token = token.next_code_token
52
+ return token if token.type == :VARIABLE
53
+ end
54
+ end
55
+
56
+ def get_prev_code_token(token, character)
57
+ case character
58
+ when '='
59
+ token.prev_code_token
60
+ when '$'
61
+ if token.prev_code_token
62
+ if %i[CLASSREF RBRACK].include?(token.prev_code_token.type)
63
+ token.prev_code_token
64
+ elsif token.prev_code_token.type == :LPAREN
65
+ token
66
+ elsif token.prev_code_token.type == :COMMA
67
+ get_the_first_param(token)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ # This function is copied & modified from puppet-lint arrow_alignment check
74
+ # https://github.com/puppetlabs/puppet-lint/blob/020143b705b023946739eb44e7c7d99fcd087527/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb#L8
75
+ def check_for(character)
76
+ # I intentionally didn't rename `arrow` to another name, to keep the code as
77
+ # similar as the original one, to easier to update in the future.
78
+ (class_indexes + defined_type_indexes).each do |res_idx|
79
+ arrow_column = [0]
80
+ level_idx = 0
81
+ level_tokens = []
82
+ param_column = [nil]
83
+ resource_tokens = res_idx[:param_tokens]
84
+ next if resource_tokens.nil?
85
+
86
+ resource_tokens.reject! do |token|
87
+ COMMENT_TYPES.include?(token.type)
88
+ end
89
+
90
+ # If this is a single line resource, skip it
91
+ first_arrow = resource_tokens.index { |r| the_one?(r, character) }
92
+ last_arrow = resource_tokens.rindex { |r| the_one?(r, character) }
93
+ next if first_arrow.nil?
94
+ next if last_arrow.nil?
95
+ next if resource_tokens[first_arrow].line == resource_tokens[last_arrow].line
96
+
97
+ resource_tokens.each do |token|
98
+ if the_one?(token, character)
99
+ param_token = get_prev_code_token(token, character)
100
+ param_token = token if param_token.nil?
101
+
102
+ param_length = param_token.to_manifest.length
103
+
104
+ param_column[level_idx] = param_token.column if param_column[level_idx].nil?
105
+
106
+ if (level_tokens[level_idx] ||= []).any? { |t| t.line == token.line }
107
+ this_arrow_column = param_column[level_idx] + param_length + 1
108
+ elsif character == '$' && param_token.type == :VARIABLE
109
+ this_arrow_column = param_token.column
110
+ else
111
+ this_arrow_column = param_token.column + param_token.to_manifest.length
112
+ this_arrow_column += 1 if param_token.type != :INDENT
113
+ end
114
+
115
+ arrow_column[level_idx] = this_arrow_column if arrow_column[level_idx] < this_arrow_column
116
+
117
+ (level_tokens[level_idx] ||= []) << token
118
+ elsif token.prev_token.type == :LPAREN
119
+ level_idx += 1
120
+ arrow_column << 0
121
+ level_tokens[level_idx] ||= []
122
+ param_column << nil
123
+ elsif token.next_token.type == :RPAREN
124
+ if (level_tokens[level_idx] ||= []).map(&:line).uniq.length > 1
125
+ level_tokens[level_idx].each do |arrow_tok|
126
+ next if arrow_tok.column == arrow_column[level_idx] || level_tokens[level_idx].size == 1
127
+
128
+ arrows_on_line = level_tokens[level_idx].select { |t| t.line == arrow_tok.line }
129
+ notify(
130
+ :warning,
131
+ message: "indentation of #{character} is not properly aligned (expected in column #{arrow_column[level_idx]}, but found it in column #{arrow_tok.column})",
132
+ line: arrow_tok.line,
133
+ column: arrow_tok.column,
134
+ token: arrow_tok,
135
+ arrow_column: arrow_column[level_idx],
136
+ newline: arrows_on_line.index(arrow_tok) != 0,
137
+ newline_indent: param_column[level_idx] - 1
138
+ )
139
+ end
140
+ end
141
+ arrow_column[level_idx] = 0
142
+ level_tokens[level_idx].clear
143
+ param_column[level_idx] = nil
144
+ level_idx -= 1
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ # This function is copied & modified from puppet-lint arrow_alignment fix
151
+ # https://github.com/puppetlabs/puppet-lint/blob/020143b705b023946739eb44e7c7d99fcd087527/lib/puppet-lint/plugins/check_whitespace/arrow_alignment.rb#L94
152
+ def fix_for(problem)
153
+ if problem[:newline]
154
+ index = tokens.index(problem[:token].prev_code_token.prev_token)
155
+
156
+ # insert newline
157
+ tokens.insert(index, PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0))
158
+
159
+ # indent the parameter to the correct depth
160
+ problem[:token].prev_code_token.prev_token.type = :INDENT
161
+ problem[:token].prev_code_token.prev_token.value = ' ' * problem[:newline_indent]
162
+
163
+ end_param_idx = tokens.index(problem[:token].prev_code_token)
164
+ start_param_idx = tokens.index(problem[:token].prev_token_of(%i[INDENT NEWLINE]))
165
+ param_length = tokens[start_param_idx..end_param_idx].map do |r|
166
+ r.to_manifest.length
167
+ end.reduce(0) { |sum, x| sum + x } + 1
168
+ new_ws_len = problem[:arrow_column] - param_length
169
+ else
170
+ new_ws_len = if problem[:token].prev_token.type == :WHITESPACE
171
+ problem[:token].prev_token.to_manifest.length
172
+ else
173
+ 0
174
+ end
175
+ new_ws_len += (problem[:arrow_column] - problem[:token].column)
176
+ end
177
+
178
+ if new_ws_len.negative?
179
+ raise PuppetLint::NoFix if problem[:token].prev_token.type != :INDENT
180
+
181
+ new_ws = problem[:token].prev_token.to_manifest[0...new_ws_len]
182
+ problem[:token].prev_token.value = new_ws
183
+ else
184
+ new_ws = ' ' * new_ws_len
185
+
186
+ if problem[:token].prev_token.type == :WHITESPACE
187
+ problem[:token].prev_token.value = new_ws
188
+ else
189
+ index = tokens.index(problem[:token].prev_token)
190
+ tokens.insert(index + 1, PuppetLint::Lexer::Token.new(:WHITESPACE, new_ws, 0, 0))
191
+ end
192
+ end
193
+ end
194
+
195
+ PuppetLint.new_check(:class_params_alignment) do
196
+ def check
197
+ check_for('$')
198
+ end
199
+
200
+ def fix(problem)
201
+ fix_for(problem)
202
+ end
203
+ end
204
+
205
+ PuppetLint.new_check(:class_equals_alignment) do
206
+ def check
207
+ check_for('=')
208
+ end
209
+
210
+ def fix(problem)
211
+ fix_for(problem)
212
+ end
213
+ end
@@ -0,0 +1,483 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'class_equals_alignment' do
4
+ let(:msg) { 'indentation of = is not properly aligned (expected in column %d, but found it in column %d)' }
5
+
6
+ context 'with fix disabled' do
7
+ context 'selectors inside a resource' do
8
+ let(:code) do
9
+ <<-END
10
+ class foo (
11
+ $ensure = $ensure,
12
+ $require = $ensure ? {
13
+ present => Class['tomcat::install'],
14
+ absent => undef;
15
+ },
16
+ $foo = bar,
17
+ ) {}
18
+ END
19
+ end
20
+
21
+ it 'should not detect any problems' do
22
+ expect(problems).to have(0).problems
23
+ end
24
+ end
25
+
26
+ context 'selectors in the middle of a resource' do
27
+ let(:code) do
28
+ <<-END
29
+ class foo (
30
+ $ensure = $ensure ? {
31
+ present => directory,
32
+ absent => undef,
33
+ },
34
+ $owner = 'tomcat6',
35
+ ) {}
36
+ END
37
+ end
38
+
39
+ it 'should not detect any problems' do
40
+ expect(problems).to have(0).problems
41
+ end
42
+ end
43
+
44
+ context 'selector inside a resource' do
45
+ let(:code) do
46
+ <<-END
47
+ $ensure = $ensure ? {
48
+ present => directory,
49
+ absent => undef,
50
+ },
51
+ $owner = 'foo4',
52
+ $group = 'foo4',
53
+ $mode = '0755',
54
+ END
55
+ end
56
+
57
+ it 'should not detect any problems' do
58
+ expect(problems).to have(0).problems
59
+ end
60
+ end
61
+
62
+ context 'selector inside a hash inside a resource' do
63
+ let(:code) do
64
+ <<-END
65
+ $server = {
66
+ ensure => ensure => $ensure ? {
67
+ present => directory,
68
+ absent => undef,
69
+ },
70
+ ip => '192.168.1.1'
71
+ },
72
+ $owner = 'foo4',
73
+ $group = 'foo4',
74
+ $mode = '0755',
75
+ END
76
+ end
77
+
78
+ it 'should not detect any problems' do
79
+ expect(problems).to have(0).problems
80
+ end
81
+ end
82
+
83
+ context 'nested hashes with correct indentation' do
84
+ let(:code) do
85
+ <<-END
86
+ class lvs::base (
87
+ $virtualeservers = {
88
+ '192.168.2.13' => {
89
+ vport => '11025',
90
+ service => 'smtp',
91
+ scheduler => 'wlc',
92
+ protocol => 'tcp',
93
+ checktype => 'external',
94
+ checkcommand => '/path/to/checkscript',
95
+ real_servers => {
96
+ 'server01' => {
97
+ real_server => '192.168.2.14',
98
+ real_port => '25',
99
+ forwarding => 'masq',
100
+ },
101
+ 'server02' => {
102
+ real_server => '192.168.2.15',
103
+ real_port => '25',
104
+ forwarding => 'masq',
105
+ }
106
+ }
107
+ }
108
+ }
109
+ ) {}
110
+ END
111
+ end
112
+
113
+ it 'should not detect any problems' do
114
+ expect(problems).to have(0).problems
115
+ end
116
+ end
117
+
118
+ context 'single resource with a misaligned =' do
119
+ let(:code) do
120
+ <<-END
121
+ class foo (
122
+ $foo = 1,
123
+ $bar = 2,
124
+ $gronk = 3,
125
+ $baz = 4,
126
+ $meh = 5,
127
+ ) {}
128
+ END
129
+ end
130
+
131
+ it 'should detect four problems' do
132
+ expect(problems).to have(4).problems
133
+ end
134
+
135
+ it 'should create four warnings' do
136
+ expect(problems).to contain_warning(format(msg, 20, 18)).on_line(2).in_column(18)
137
+ expect(problems).to contain_warning(format(msg, 20, 18)).on_line(3).in_column(18)
138
+ expect(problems).to contain_warning(format(msg, 20, 19)).on_line(5).in_column(19)
139
+ expect(problems).to contain_warning(format(msg, 20, 18)).on_line(6).in_column(18)
140
+ end
141
+ end
142
+
143
+ context 'complex resource with a misaligned =' do
144
+ let(:code) do
145
+ <<-END
146
+ class foo (
147
+ $foo = 1,
148
+ $bar = $baz ? {
149
+ gronk => 2,
150
+ meh => 3,
151
+ },
152
+ $meep = 4,
153
+ $bah= 5,
154
+ ) {}
155
+ END
156
+ end
157
+
158
+ it 'should detect three problems' do
159
+ expect(problems).to have(3).problems
160
+ end
161
+
162
+ it 'should create three warnings' do
163
+ expect(problems).to contain_warning(format(msg, 19, 18)).on_line(2).in_column(18)
164
+ expect(problems).to contain_warning(format(msg, 19, 20)).on_line(3).in_column(20)
165
+ expect(problems).to contain_warning(format(msg, 19, 17)).on_line(8).in_column(17)
166
+ end
167
+ end
168
+
169
+ context 'resource with unaligned = in commented line' do
170
+ let(:code) do
171
+ <<-END
172
+ class foo (
173
+ $ensure = directory,
174
+ # $purge = true,
175
+ ) {}
176
+ END
177
+ end
178
+
179
+ it 'should not detect any problems' do
180
+ expect(problems).to have(0).problems
181
+ end
182
+ end
183
+
184
+ context 'multiline resource with a single line of params' do
185
+ let(:code) do
186
+ <<-END
187
+ class mymodule::do_thing (
188
+ $whatever = 'bar', $one = 'two',
189
+ ) {}
190
+ END
191
+ end
192
+
193
+ it 'should not detect any problems' do
194
+ expect(problems).to have(0).problems
195
+ end
196
+ end
197
+
198
+ context 'resource with aligned = too far out' do
199
+ let(:code) do
200
+ <<-END
201
+ class foo (
202
+ $ensure = file,
203
+ $mode = '0444',
204
+ ) {}
205
+ END
206
+ end
207
+
208
+ it 'should detect 2 problems' do
209
+ expect(problems).to have(2).problems
210
+ end
211
+
212
+ it 'should create 2 warnings' do
213
+ expect(problems).to contain_warning(format(msg, 21, 22)).on_line(2).in_column(22)
214
+ expect(problems).to contain_warning(format(msg, 21, 22)).on_line(3).in_column(22)
215
+ end
216
+ end
217
+
218
+ context 'resource with multiple params where one is an empty hash' do
219
+ let(:code) do
220
+ <<-END
221
+ class foo (
222
+ $a = true,
223
+ $b = {
224
+ }
225
+ ) {}
226
+ END
227
+ end
228
+
229
+ it 'should not detect any problems' do
230
+ expect(problems).to have(0).problems
231
+ end
232
+ end
233
+
234
+ context 'multiline resource with multiple params on a line' do
235
+ let(:code) do
236
+ <<-END
237
+ class test (
238
+ $a = 'foo', $bb = 'bar',
239
+ $ccc = 'baz',
240
+ ) {}
241
+ END
242
+ end
243
+
244
+ it 'should detect 2 problems' do
245
+ expect(problems).to have(2).problems
246
+ end
247
+
248
+ it 'should create 2 warnings' do
249
+ expect(problems).to contain_warning(format(msg, 18, 16)).on_line(2).in_column(16)
250
+ expect(problems).to contain_warning(format(msg, 18, 29)).on_line(2).in_column(29)
251
+ end
252
+ end
253
+ end
254
+
255
+ context 'with fix enabled' do
256
+ before do
257
+ PuppetLint.configuration.fix = true
258
+ end
259
+
260
+ after do
261
+ PuppetLint.configuration.fix = false
262
+ end
263
+
264
+ context 'single resource with a misaligned =' do
265
+ let(:code) do
266
+ <<-END
267
+ class foo (
268
+ $foo = 1,
269
+ $bar = 2,
270
+ $gronk = 3,
271
+ $baz = 4,
272
+ $meh = 5,
273
+ ) {}
274
+ END
275
+ end
276
+
277
+ let(:fixed) do
278
+ <<-END
279
+ class foo (
280
+ $foo = 1,
281
+ $bar = 2,
282
+ $gronk = 3,
283
+ $baz = 4,
284
+ $meh = 5,
285
+ ) {}
286
+ END
287
+ end
288
+
289
+ it 'should detect four problems' do
290
+ expect(problems).to have(4).problems
291
+ end
292
+
293
+ it 'should fix the manifest' do
294
+ expect(problems).to contain_fixed(format(msg, 20, 18)).on_line(2).in_column(18)
295
+ expect(problems).to contain_fixed(format(msg, 20, 18)).on_line(3).in_column(18)
296
+ expect(problems).to contain_fixed(format(msg, 20, 19)).on_line(5).in_column(19)
297
+ expect(problems).to contain_fixed(format(msg, 20, 18)).on_line(6).in_column(18)
298
+ end
299
+
300
+ it 'should align the class_paramss' do
301
+ expect(manifest).to eq(fixed)
302
+ end
303
+ end
304
+
305
+ context 'complex resource with a misaligned =' do
306
+ let(:code) do
307
+ <<-END
308
+ class foo (
309
+ $foo = 1,
310
+ $bar = $baz ? {
311
+ gronk => 2,
312
+ meh => 3,
313
+ },
314
+ $meep= 4,
315
+ $bah = 5,
316
+ ) {}
317
+ END
318
+ end
319
+
320
+ let(:fixed) do
321
+ <<-END
322
+ class foo (
323
+ $foo = 1,
324
+ $bar = $baz ? {
325
+ gronk => 2,
326
+ meh => 3,
327
+ },
328
+ $meep = 4,
329
+ $bah = 5,
330
+ ) {}
331
+ END
332
+ end
333
+
334
+ it 'should detect three problems' do
335
+ expect(problems).to have(3).problems
336
+ end
337
+
338
+ it 'should fix the manifest' do
339
+ expect(problems).to contain_fixed(format(msg, 19, 18)).on_line(2).in_column(18)
340
+ expect(problems).to contain_fixed(format(msg, 19, 18)).on_line(7).in_column(18)
341
+ expect(problems).to contain_fixed(format(msg, 19, 18)).on_line(8).in_column(18)
342
+ end
343
+
344
+ it 'should align the class_paramss' do
345
+ expect(manifest).to eq(fixed)
346
+ end
347
+ end
348
+
349
+ context 'resource with aligned = too far out' do
350
+ let(:code) do
351
+ <<-END
352
+ class foo (
353
+ $ensure = file,
354
+ $mode = '0444',
355
+ ) {}
356
+ END
357
+ end
358
+
359
+ let(:fixed) do
360
+ <<-END
361
+ class foo (
362
+ $ensure = file,
363
+ $mode = '0444',
364
+ ) {}
365
+ END
366
+ end
367
+
368
+ it 'should detect 2 problems' do
369
+ expect(problems).to have(2).problems
370
+ end
371
+
372
+ it 'should create 2 warnings' do
373
+ expect(problems).to contain_fixed(format(msg, 21, 22)).on_line(2).in_column(22)
374
+ expect(problems).to contain_fixed(format(msg, 21, 22)).on_line(3).in_column(22)
375
+ end
376
+
377
+ it 'should realign the class_paramss with the minimum whitespace' do
378
+ expect(manifest).to eq(fixed)
379
+ end
380
+ end
381
+
382
+ context 'resource with unaligned = and no whitespace between param and =' do
383
+ let(:code) do
384
+ <<-END
385
+ class test (
386
+ $param1 = 'foo',
387
+ $param2= 'bar',
388
+ ) {}
389
+ END
390
+ end
391
+
392
+ let(:fixed) do
393
+ <<-END
394
+ class test (
395
+ $param1 = 'foo',
396
+ $param2 = 'bar',
397
+ ) {}
398
+ END
399
+ end
400
+
401
+ it 'should detect 1 problem' do
402
+ expect(problems).to have(1).problem
403
+ end
404
+
405
+ it 'should fix the problem' do
406
+ expect(problems).to contain_fixed(format(msg, 21, 20)).on_line(3).in_column(20)
407
+ end
408
+
409
+ it 'should add whitespace between the param and the class_params' do
410
+ expect(manifest).to eq(fixed)
411
+ end
412
+ end
413
+
414
+ context 'multiline resource with multiple params on a line' do
415
+ let(:code) do
416
+ <<-END
417
+ class test (
418
+ $a = 'foo', $bb = 'bar',
419
+ $ccc = 'baz',
420
+ ) {}
421
+ END
422
+ end
423
+
424
+ let(:fixed) do
425
+ <<-END
426
+ class test (
427
+ $a = 'foo',
428
+ $bb = 'bar',
429
+ $ccc = 'baz',
430
+ ) {}
431
+ END
432
+ end
433
+
434
+ it 'should detect 2 problems' do
435
+ expect(problems).to have(2).problems
436
+ end
437
+
438
+ it 'should fix 2 problems' do
439
+ expect(problems).to contain_fixed(format(msg, 18, 16)).on_line(2).in_column(16)
440
+ expect(problems).to contain_fixed(format(msg, 18, 29)).on_line(2).in_column(29)
441
+ end
442
+
443
+ it 'should move the extra param onto its own line and realign' do
444
+ expect(manifest).to eq(fixed)
445
+ end
446
+ end
447
+
448
+ context 'multiline resource with multiple params on a line, extra one longer' do
449
+ let(:code) do
450
+ <<-END
451
+ class test (
452
+ $a = 'foo', $bbccc = 'bar',
453
+ $ccc = 'baz',
454
+ ) {}
455
+ END
456
+ end
457
+
458
+ let(:fixed) do
459
+ <<-END
460
+ class test (
461
+ $a = 'foo',
462
+ $bbccc = 'bar',
463
+ $ccc = 'baz',
464
+ ) {}
465
+ END
466
+ end
467
+
468
+ it 'should detect 2 problems' do
469
+ expect(problems).to have(3).problems
470
+ end
471
+
472
+ it 'should fix 2 problems' do
473
+ expect(problems).to contain_fixed(format(msg, 20, 16)).on_line(2).in_column(16)
474
+ expect(problems).to contain_fixed(format(msg, 20, 32)).on_line(2).in_column(32)
475
+ expect(problems).to contain_fixed(format(msg, 20, 18)).on_line(3).in_column(18)
476
+ end
477
+
478
+ it 'should move the extra param onto its own line and realign' do
479
+ expect(manifest).to eq(fixed)
480
+ end
481
+ end
482
+ end
483
+ end
@@ -0,0 +1,321 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'class_params_alignment' do
4
+ let(:msg) { 'indentation of $ is not properly aligned (expected in column %d, but found it in column %d)' }
5
+
6
+ context 'with fix disabled' do
7
+ context 'with correct indentation' do
8
+ let(:code) do
9
+ <<-END
10
+ class foo (
11
+ $foo = 1,
12
+ $bar = 2,
13
+ $gronk = 3,
14
+ $baz = 4,
15
+ $meh = 5,
16
+ ) {}
17
+ END
18
+ end
19
+
20
+ it 'should not detect any problems' do
21
+ expect(problems).to have(0).problems
22
+ end
23
+ end
24
+
25
+ context 'single resource with a misaligned $' do
26
+ let(:code) do
27
+ <<-END
28
+ class foo (
29
+ $foo = 1,
30
+ $bar = 2,
31
+ $gronk = 3,
32
+ $baz = 4,
33
+ $meh = 5,
34
+ ) {}
35
+ END
36
+ end
37
+
38
+ it 'should detect four problems' do
39
+ expect(problems).to have(4).problems
40
+ end
41
+
42
+ it 'should create four warnings' do
43
+ expect(problems).to contain_warning(format(msg, 13, 11)).on_line(3).in_column(11)
44
+ expect(problems).to contain_warning(format(msg, 13, 11)).on_line(4).in_column(11)
45
+ expect(problems).to contain_warning(format(msg, 13, 11)).on_line(5).in_column(11)
46
+ expect(problems).to contain_warning(format(msg, 13, 12)).on_line(6).in_column(12)
47
+ end
48
+ end
49
+
50
+ context 'complex resource with a misaligned $' do
51
+ let(:code) do
52
+ <<-END
53
+ class foo (
54
+ $foo = 1,
55
+ $bar = $baz ? {
56
+ gronk => 2,
57
+ meh => 3,
58
+ },
59
+ $meep = 4,
60
+ $bah= 5,
61
+ ) {}
62
+ END
63
+ end
64
+
65
+ it 'should detect three problems' do
66
+ expect(problems).to have(3).problems
67
+ end
68
+
69
+ it 'should create three warnings' do
70
+ expect(problems).to contain_warning(format(msg, 13, 11)).on_line(3).in_column(11)
71
+ expect(problems).to contain_warning(format(msg, 13, 15)).on_line(7).in_column(15)
72
+ expect(problems).to contain_warning(format(msg, 13, 17)).on_line(8).in_column(17)
73
+ end
74
+ end
75
+
76
+ context 'resource with unaligned $ in commented line' do
77
+ let(:code) do
78
+ <<-END
79
+ class foo (
80
+ $ensure = directory,
81
+ # $purge = true,
82
+ ) {}
83
+ END
84
+ end
85
+
86
+ it 'should not detect any problems' do
87
+ expect(problems).to have(0).problems
88
+ end
89
+ end
90
+
91
+ context 'multiline resource with a single line of params' do
92
+ let(:code) do
93
+ <<-END
94
+ class mymodule::do_thing (
95
+ $whatever = 'bar', $one = 'two',
96
+ ) {}
97
+ END
98
+ end
99
+
100
+ it 'should not detect any problems' do
101
+ expect(problems).to have(0).problems
102
+ end
103
+ end
104
+
105
+ context 'resource with aligned $ too far out' do
106
+ let(:code) do
107
+ <<-END
108
+ class foo (
109
+ $ensure = file,
110
+ $mode = '0444',
111
+ ) {}
112
+ END
113
+ end
114
+
115
+ it 'should detect 0 problems' do
116
+ expect(problems).to have(0).problems
117
+ end
118
+ end
119
+
120
+ context 'resource with multiple params where one is an empty hash' do
121
+ let(:code) do
122
+ <<-END
123
+ class foo (
124
+ $a = true,
125
+ $b = {
126
+ }
127
+ ) {}
128
+ END
129
+ end
130
+
131
+ it 'should not detect any problems' do
132
+ expect(problems).to have(0).problems
133
+ end
134
+ end
135
+
136
+ context 'multiline resource with multiple params on a line' do
137
+ let(:code) do
138
+ <<-END
139
+ class test (
140
+ $a = 'foo', $bb = 'bar',
141
+ $ccc = 'baz',
142
+ ) {}
143
+ END
144
+ end
145
+
146
+ it 'should detect 0 problems' do
147
+ expect(problems).to have(0).problems
148
+ end
149
+ end
150
+ end
151
+
152
+ context 'with fix enabled' do
153
+ before do
154
+ PuppetLint.configuration.fix = true
155
+ end
156
+
157
+ after do
158
+ PuppetLint.configuration.fix = false
159
+ end
160
+
161
+ context 'single resource with a misaligned $' do
162
+ let(:code) do
163
+ <<-END
164
+ class foo (
165
+ $foo = 1,
166
+ $bar = 2,
167
+ $gronk = 3,
168
+ $baz = 4,
169
+ $meh = 5,
170
+ ) {}
171
+ END
172
+ end
173
+
174
+ let(:fixed) do
175
+ <<-END
176
+ class foo (
177
+ $foo = 1,
178
+ $bar = 2,
179
+ $gronk = 3,
180
+ $baz = 4,
181
+ $meh = 5,
182
+ ) {}
183
+ END
184
+ end
185
+
186
+ it 'should detect four problems' do
187
+ expect(problems).to have(4).problems
188
+ end
189
+
190
+ it 'should fix the manifest' do
191
+ expect(problems).to contain_fixed(format(msg, 13, 15)).on_line(3).in_column(15)
192
+ expect(problems).to contain_fixed(format(msg, 13, 15)).on_line(4).in_column(15)
193
+ expect(problems).to contain_fixed(format(msg, 13, 17)).on_line(5).in_column(17)
194
+ expect(problems).to contain_fixed(format(msg, 13, 11)).on_line(6).in_column(11)
195
+ end
196
+
197
+ it 'should align the class_paramss' do
198
+ expect(manifest).to eq(fixed)
199
+ end
200
+ end
201
+
202
+ context 'complex resource with a misaligned =' do
203
+ let(:code) do
204
+ <<-END
205
+ class foo (
206
+ $foo = 1,
207
+ $bar = $baz ? {
208
+ gronk => $a,
209
+ meh => $b,
210
+ },
211
+ $meep= 4,
212
+ $bah = 5,
213
+ ) {}
214
+ END
215
+ end
216
+
217
+ let(:fixed) do
218
+ <<-END
219
+ class foo (
220
+ $foo = 1,
221
+ $bar = $baz ? {
222
+ gronk => $a,
223
+ meh => $b,
224
+ },
225
+ $meep= 4,
226
+ $bah = 5,
227
+ ) {}
228
+ END
229
+ end
230
+
231
+ it 'should detect three problems' do
232
+ expect(problems).to have(3).problems
233
+ end
234
+
235
+ it 'should fix the manifest' do
236
+ expect(problems).to contain_fixed(format(msg, 13, 11)).on_line(3).in_column(11)
237
+ expect(problems).to contain_fixed(format(msg, 13, 11)).on_line(7).in_column(11)
238
+ expect(problems).to contain_fixed(format(msg, 13, 11)).on_line(8).in_column(11)
239
+ end
240
+
241
+ it 'should align the class_paramss' do
242
+ expect(manifest).to eq(fixed)
243
+ end
244
+ end
245
+
246
+ context 'multiline resource with multiple params on a line' do
247
+ let(:code) do
248
+ <<-END
249
+ class test (
250
+ $a = 'foo', $bb = 'bar',
251
+ $ccc = 'baz',
252
+ ) {}
253
+ END
254
+ end
255
+
256
+ let(:fixed) do
257
+ <<-END
258
+ class test (
259
+ $a = 'foo', $bb = 'bar',
260
+ $ccc = 'baz',
261
+ ) {}
262
+ END
263
+ end
264
+
265
+ it 'should detect 1 problem' do
266
+ expect(problems).to have(1).problems
267
+ end
268
+
269
+ it 'should fix 1 problem' do
270
+ expect(problems).to contain_fixed(format(msg, 13, 11)).on_line(3).in_column(11)
271
+ end
272
+
273
+ it 'should move the extra param onto its own line and realign' do
274
+ expect(manifest).to eq(fixed)
275
+ end
276
+ end
277
+
278
+ context 'multiline resource with inline variables' do
279
+ let(:code) do
280
+ <<-END
281
+ class name (
282
+ $aaa = function('foo', 'bar'),
283
+ $bbb = function('foo', 'bar'),
284
+ Boolean $key1 = false,
285
+ Enum['never', 'allow', 'try', 'demand'] $key2,
286
+ $materializer_version = $foo ? {
287
+ default => "foo ${bar} baz ${gronk} qux 0.4.1-1.el${::facts['operatingsystemmajrelease']}"
288
+ }) { }
289
+ END
290
+ end
291
+
292
+ let(:fixed) do
293
+ <<-END
294
+ class name (
295
+ $aaa = function('foo', 'bar'),
296
+ $bbb = function('foo', 'bar'),
297
+ Boolean $key1 = false,
298
+ Enum['never', 'allow', 'try', 'demand'] $key2,
299
+ $materializer_version = $foo ? {
300
+ default => "foo ${bar} baz ${gronk} qux 0.4.1-1.el${::facts['operatingsystemmajrelease']}"
301
+ }) { }
302
+ END
303
+ end
304
+
305
+ it 'should detect 4 problems' do
306
+ expect(problems).to have(4).problems
307
+ end
308
+
309
+ it 'should fix 4 problems' do
310
+ expect(problems).to contain_fixed(format(msg, 53, 13)).on_line(2).in_column(13)
311
+ expect(problems).to contain_fixed(format(msg, 53, 13)).on_line(3).in_column(13)
312
+ expect(problems).to contain_fixed(format(msg, 53, 21)).on_line(4).in_column(21)
313
+ expect(problems).to contain_fixed(format(msg, 53, 11)).on_line(6).in_column(11)
314
+ end
315
+
316
+ it 'should move the extra param onto its own line and realign' do
317
+ expect(manifest).to eq(fixed)
318
+ end
319
+ end
320
+ end
321
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'puppet-lint'
4
+
5
+ PuppetLint::Plugins.load_spec_helper
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppet-lint-class_alignment-check
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anh Pham
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: puppet-lint
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec-collection_matchers
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec-its
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: " A puppet-lint plugin to check & fix class params/equals alignment.\n"
104
+ email: anhpt379@gmail.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - LICENSE
110
+ - README.md
111
+ - lib/puppet-lint/plugins/check_class_params_alignment.rb
112
+ - spec/puppet-lint/plugins/check_class_equals_alignment_spec.rb
113
+ - spec/puppet-lint/plugins/check_class_params_alignment_spec.rb
114
+ - spec/spec_helper.rb
115
+ homepage: https://github.com/anhpt379/puppet-lint-class_alignment-check
116
+ licenses:
117
+ - MIT
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubygems_version: 3.2.22
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: A puppet-lint plugin to check & fix class params/equals alignment.
138
+ test_files:
139
+ - spec/puppet-lint/plugins/check_class_equals_alignment_spec.rb
140
+ - spec/puppet-lint/plugins/check_class_params_alignment_spec.rb
141
+ - spec/spec_helper.rb