openvox-lint 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd99ac3fc7637de4bda009ad83ca4b89fbf861316db186f039a8b0405c062cbc
4
- data.tar.gz: 4747a1300a899ede28ddaea30a3f5488ae7ee5e294cad55ad1f4721fc55110fa
3
+ metadata.gz: 0c88e7f7c408afd3a75f203e4b9be28bc34fdbea11bba5245f5315a930cca516
4
+ data.tar.gz: 3096af92ef4d33f90c50529778930d51a979992ca62e2a96990d5e2b1a8e1936
5
5
  SHA512:
6
- metadata.gz: e260e0c5a26c9da084e03b835da830981d79fc6af3e32f5fd6644e80da03c4e01d095e4a6badeb581ff8e47467d21802efe6ad3ab1197be0c8046154c6cf37e8
7
- data.tar.gz: 6ef7e4f2244b3247012fc5e446505f1d373418e9c226c3c62e003aae26ef3d970f3a84cd63b1d66237a6176a3af85a3a41b9c8368036e2e34f8ff8d220404c9c
6
+ metadata.gz: b7d189b56162653881f90a3ff60cdbfda158e252425904e0bd4e49b7adb169a78ba13214dfdd3439498125b9892d6d7e8bdae4fc247711fb3a43d501d5cb7a88
7
+ data.tar.gz: db0220c84a03ce7f32acb448410ccd3ac61b1733c193b8f765a4eb91080bdf295c041f205e4e0841737b7a00a8c30975803115d2979e309eb090b7dfbfdf78c6
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to openvox-lint will be documented in this file.
4
4
 
5
+ ## [1.0.1] - 2026-02-09
6
+
7
+ ### Fixed
8
+
9
+ - **space_before_arrow**: No longer generates false positives on properly
10
+ aligned `=>` arrows. In a multi-parameter resource block, only the
11
+ parameter with the longest key name is expected to have a single space
12
+ before `=>`. Shorter keys may have additional padding spaces for
13
+ alignment and these are no longer flagged.
14
+
5
15
  ## [1.0.0] - 2025-02-09
6
16
 
7
17
  ### Added
data/DOCUMENTATION.md CHANGED
@@ -46,7 +46,7 @@ the lexer token types, the plugin system, and integration guidance.
46
46
 
47
47
  | Constant | Value | Description |
48
48
  |----------|-------|-------------|
49
- | `VERSION` | `'1.0.0'` | Gem version |
49
+ | `VERSION` | `'1.0.1'` | Gem version |
50
50
 
51
51
  ### Class Methods
52
52
 
@@ -312,6 +312,61 @@ report.format(problems, io: file) # to file
312
312
 
313
313
  ## Complete Check Reference
314
314
 
315
+ ### Whitespace & Alignment Checks
316
+
317
+ #### `space_before_arrow` (WARNING)
318
+
319
+ Controls spacing before `=>` (hash rocket) in resource parameter blocks.
320
+ In Puppet manifests, it is standard practice to vertically align `=>`
321
+ arrows within a resource body. This means the parameter with the
322
+ **longest key name** has exactly one space before `=>`, and all shorter
323
+ keys have additional padding spaces to bring their `=>` into alignment.
324
+
325
+ The check groups `=>` tokens by line proximity. Within each group it
326
+ identifies the longest key and only flags that key if it has more than
327
+ one space before `=>`. Shorter keys are permitted extra spaces for
328
+ alignment. A single-parameter resource with extra space before `=>`
329
+ is always flagged (nothing to align with).
330
+
331
+ **Good — properly aligned (no warnings):**
332
+ ```puppet
333
+ file { '/etc/nginx/nginx.conf':
334
+ ensure => file,
335
+ content => template('nginx/nginx.conf.erb'),
336
+ owner => 'root',
337
+ group => 'root',
338
+ mode => '0644',
339
+ }
340
+ ```
341
+
342
+ Here `content` is the longest key (7 characters). It has a single space
343
+ before `=>`. All other keys (`ensure`, `owner`, `group`, `mode`) have
344
+ padding to align their `=>` with `content =>`'s column. No warnings.
345
+
346
+ **Bad — longest key has extra space:**
347
+ ```puppet
348
+ file { '/tmp/foo':
349
+ ensure => present,
350
+ mode => '0644',
351
+ owner => 'root',
352
+ }
353
+ ```
354
+
355
+ `ensure` is the longest key (6 chars) but has 2 spaces before `=>`.
356
+ The check flags `ensure` only; `mode` and `owner` padding is fine.
357
+
358
+ **Bad — single parameter with extra space:**
359
+ ```puppet
360
+ package { 'httpd':
361
+ ensure => installed,
362
+ }
363
+ ```
364
+
365
+ Only one parameter — no alignment context — the 3 extra spaces are
366
+ flagged.
367
+
368
+ ---
369
+
315
370
  ### Puppet 8 / OpenVox 8 Migration Checks
316
371
 
317
372
  These are the most important checks for users upgrading from Puppet 7 or
data/README.md CHANGED
@@ -162,7 +162,7 @@ openvox-lint ships with **38 built-in checks** organized into categories:
162
162
  | `trailing_whitespace` | warning | No trailing whitespace at end of lines |
163
163
  | `hard_tabs` | warning | Use 2-space soft tabs, not literal tabs |
164
164
  | `line_length` | warning | Lines should not exceed 140 characters |
165
- | `space_before_arrow` | warning | At most one space before `=>` |
165
+ | `space_before_arrow` | warning | Only the longest key in an aligned block should have one space before `=>` |
166
166
  | `strict_indent` | warning | Indentation must use 2-space increments |
167
167
 
168
168
  ### Arrow Alignment (1 check)
@@ -1,20 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # There should be at most one space before a hash rocket (=>)
4
- # when there is only one parameter.
3
+ # In a block of aligned hash rockets (=>), only the parameter with the
4
+ # longest key name should have exactly one space before =>. All shorter
5
+ # keys are expected to have extra padding to keep the arrows aligned.
6
+ #
7
+ # This check fires only when:
8
+ # - A => has more than one space before it AND is the longest key in its
9
+ # alignment group (no reason for extra spaces), OR
10
+ # - A => has more than one space before it AND is the only => on its line
11
+ # group (nothing to align with).
5
12
  OpenvoxLint.new_check(:space_before_arrow) do
6
13
  def check
14
+ # Collect every FARROW token together with its preceding whitespace
15
+ # and the key token that precedes that whitespace.
16
+ farrow_entries = []
7
17
  tokens.each_with_index do |tok, i|
8
18
  next unless tok.type == :FARROW
9
- next if i == 0
10
- prev = tokens[i - 1]
11
- next unless prev.type == :WHITESPACE
12
- next if prev.value.length <= 1
13
- # Allow if this is in a multi-param aligned block
14
- # (arrow_alignment handles that)
15
- notify :warning,
16
- message: "more than one space before => (found #{prev.value.length})",
17
- line: tok.line, column: prev.column
19
+ next if i < 2
20
+
21
+ ws = tokens[i - 1]
22
+ next unless ws.type == :WHITESPACE
23
+
24
+ # The key token is whatever sits before the whitespace. It could be
25
+ # a NAME, SSTRING, STRING, VARIABLE, CLASSREF, etc.
26
+ key = tokens[i - 2]
27
+ farrow_entries << { arrow: tok, whitespace: ws, key: key }
28
+ end
29
+
30
+ return if farrow_entries.empty?
31
+
32
+ # Group arrows that belong to the same aligned block. Arrows on
33
+ # consecutive lines (gap <= 2) belong to the same group — same
34
+ # heuristic used by the arrow_alignment check.
35
+ groups = group_entries(farrow_entries)
36
+
37
+ groups.each do |group|
38
+ if group.size == 1
39
+ # Single parameter — no alignment needed, max one space.
40
+ entry = group.first
41
+ if entry[:whitespace].value.length > 1
42
+ notify :warning,
43
+ message: "more than one space before => (found #{entry[:whitespace].value.length})",
44
+ line: entry[:arrow].line,
45
+ column: entry[:whitespace].column
46
+ end
47
+ else
48
+ # Multiple parameters — find the longest key. Only the longest
49
+ # key (the one that sets the alignment column) should have a
50
+ # single space. Flag it if it has extra spaces.
51
+ max_key_len = group.map { |e| key_length(e[:key]) }.max
52
+
53
+ group.each do |entry|
54
+ ws_len = entry[:whitespace].value.length
55
+ next if ws_len <= 1 # exactly one space — always fine
56
+ klen = key_length(entry[:key])
57
+
58
+ # This is the longest key (or tied for longest). It should
59
+ # have exactly one space before =>.
60
+ if klen == max_key_len && ws_len > 1
61
+ notify :warning,
62
+ message: "more than one space before => (found #{ws_len})",
63
+ line: entry[:arrow].line,
64
+ column: entry[:whitespace].column
65
+ end
66
+
67
+ # Shorter keys: extra spaces are expected for alignment — no warning.
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ # Group entries by line proximity. Entries whose arrows appear on
76
+ # lines within 2 of each other belong to the same group.
77
+ def group_entries(entries)
78
+ groups = []
79
+ current = [entries.first]
80
+
81
+ entries[1..].each do |entry|
82
+ if entry[:arrow].line - current.last[:arrow].line <= 2
83
+ current << entry
84
+ else
85
+ groups << current
86
+ current = [entry]
87
+ end
18
88
  end
89
+ groups << current unless current.empty?
90
+ groups
91
+ end
92
+
93
+ # Calculate the display length of a key token. For quoted strings
94
+ # the length includes the quotes, matching what the developer sees.
95
+ def key_length(key_token)
96
+ key_token.value.length
19
97
  end
20
98
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenvoxLint
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openvox-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johnny Sheets