rubocop-tablecop 0.2.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 +7 -0
- data/CHANGELOG.md +63 -0
- data/LICENSE +21 -0
- data/README.md +433 -0
- data/config/default.yml +99 -0
- data/lib/rubocop/cop/tablecop/align_assignments.rb +240 -0
- data/lib/rubocop/cop/tablecop/align_methods.rb +140 -0
- data/lib/rubocop/cop/tablecop/condense_when.rb +207 -0
- data/lib/rubocop/cop/tablecop/safe_endless_method.rb +255 -0
- data/lib/rubocop/cop/tablecop_cops.rb +6 -0
- data/lib/rubocop/tablecop/plugin.rb +37 -0
- data/lib/rubocop/tablecop/version.rb +17 -0
- data/lib/rubocop/tablecop.rb +8 -0
- data/lib/rubocop-tablecop.rb +8 -0
- metadata +89 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 51eef2c0d5feffe748c3522a755b445f04c3a4b3375ae0aea80fed3abac7e3c6
|
|
4
|
+
data.tar.gz: d970c3c03b7cf9e4dc01c3184e276e79aaf7e88651d651f5f7d0b444ba7bad21
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 19bed6636d3be68d97d506d660dab28f2470eb2e6f3dc94312809a32ee7909a66d914e3a1995e65278f38e4c8b21c4365cde21839528be48748dad27661bde65
|
|
7
|
+
data.tar.gz: e0c333e488389fee8c0cace9506b429e3eff5fed20b503ec2972ecbe5030c2b4791ba91cd5f8518e90338d48c93064a4c28b83e0f1507bf57bd7877d8be60b4d
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2025-12-13
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **BREAKING**: Renamed gem from `tablecop` to `rubocop-tablecop` for RuboCop plugin auto-discovery
|
|
13
|
+
- **BREAKING**: Minimum RuboCop version increased from 1.50 to 1.72 (required for plugin system)
|
|
14
|
+
- Migrated to RuboCop's plugin system using `lint_roller`
|
|
15
|
+
- Version module relocated to `RuboCop::Tablecop::Version::STRING` (backwards-compatible `VERSION` constant retained)
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `RuboCop::Tablecop::Plugin` class for native plugin integration
|
|
20
|
+
- Can now use `plugins: [rubocop-tablecop]` in `.rubocop.yml` instead of `require:`
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Removed unused variable warning in `AlignAssignments` cop
|
|
25
|
+
|
|
26
|
+
### Migration
|
|
27
|
+
|
|
28
|
+
Update your configuration:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
# Before (.rubocop.yml)
|
|
32
|
+
require:
|
|
33
|
+
- tablecop
|
|
34
|
+
|
|
35
|
+
# After (.rubocop.yml)
|
|
36
|
+
plugins:
|
|
37
|
+
- rubocop-tablecop
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Update your Gemfile:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
# Before
|
|
44
|
+
gem "tablecop"
|
|
45
|
+
|
|
46
|
+
# After
|
|
47
|
+
gem "rubocop-tablecop", "~> 0.2"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## [0.1.0] - 2025-12-10
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- `Tablecop/CondenseWhen` - Condenses multi-line `when` clauses to single lines and aligns `then` keywords
|
|
55
|
+
- `Tablecop/AlignMethods` - Aligns contiguous single-line method definitions on the `=` operator
|
|
56
|
+
- `Tablecop/AlignAssignments` - Aligns consecutive assignment statements on the `=` operator
|
|
57
|
+
- `Tablecop/SafeEndlessMethod` - Converts multi-line methods to endless or traditional one-liner form, avoiding RuboCop's known bugs
|
|
58
|
+
- Safe default configuration that disables known-buggy RuboCop cops:
|
|
59
|
+
- `Style/EndlessMethod` (heredoc destruction, rescue orphaning, module_eval failures)
|
|
60
|
+
- `Style/DoubleNegation` (semantically wrong: `!!false` ≠ `!false.nil?`)
|
|
61
|
+
- `Style/HashExcept` (breaks mixed symbol/string key handling)
|
|
62
|
+
- `Layout/ExtraSpacing` with `ForceEqualSignAlignment` (infinite loops with heredocs)
|
|
63
|
+
- Documentation of known RuboCop autocorrect bugs in `docs/known-issues.md`
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Joseph Wecker
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
# rubocop-tablecop
|
|
2
|
+
|
|
3
|
+
A RuboCop plugin for table-like, condensed Ruby formatting. Enforces vertical alignment and single-line expressions where they improve readability, while avoiding RuboCop's known autocorrect bugs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add to your Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem "rubocop-tablecop"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
Add to your `.rubocop.yml`:
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
# RuboCop 1.72+ (plugin system - recommended)
|
|
25
|
+
plugins:
|
|
26
|
+
- rubocop-tablecop
|
|
27
|
+
|
|
28
|
+
# Or for older RuboCop versions
|
|
29
|
+
require:
|
|
30
|
+
- rubocop-tablecop
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The plugin requires **RuboCop >= 1.72**.
|
|
34
|
+
|
|
35
|
+
## Cops
|
|
36
|
+
|
|
37
|
+
### Tablecop/AlignAssignments
|
|
38
|
+
|
|
39
|
+
Aligns consecutive assignment statements on the `=` operator for improved readability.
|
|
40
|
+
|
|
41
|
+
**Enabled by default:** Yes
|
|
42
|
+
|
|
43
|
+
**Supports autocorrect:** Yes
|
|
44
|
+
|
|
45
|
+
**What it does:**
|
|
46
|
+
- Aligns consecutive assignments at the same indentation level
|
|
47
|
+
- Handles simple assignments (`=`), compound assignments (`||=`, `&&=`, `+=`, etc.), and constant assignments
|
|
48
|
+
- Skips lines containing heredocs to avoid infinite loops with other cops
|
|
49
|
+
- Respects `Layout/LineLength` configuration
|
|
50
|
+
|
|
51
|
+
**Examples:**
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
# bad
|
|
55
|
+
x = 1
|
|
56
|
+
foo = 2
|
|
57
|
+
barbaz = 3
|
|
58
|
+
|
|
59
|
+
# good
|
|
60
|
+
x = 1
|
|
61
|
+
foo = 2
|
|
62
|
+
barbaz = 3
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
# bad (compound operators)
|
|
67
|
+
data ||= attrs
|
|
68
|
+
options = default
|
|
69
|
+
config &&= fallback
|
|
70
|
+
|
|
71
|
+
# good
|
|
72
|
+
data ||= attrs
|
|
73
|
+
options = default
|
|
74
|
+
config &&= fallback
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Limitations:**
|
|
78
|
+
- Skips assignments inside blocks
|
|
79
|
+
- Skips multi-assignment (`a, b = ...`)
|
|
80
|
+
- Skips assignments containing heredocs
|
|
81
|
+
- Only aligns assignments on consecutive lines at the same indentation level
|
|
82
|
+
|
|
83
|
+
### Tablecop/AlignMethods
|
|
84
|
+
|
|
85
|
+
Aligns contiguous single-line method definitions so their bodies start at the same column.
|
|
86
|
+
|
|
87
|
+
**Enabled by default:** Yes
|
|
88
|
+
|
|
89
|
+
**Supports autocorrect:** Yes
|
|
90
|
+
|
|
91
|
+
**What it does:**
|
|
92
|
+
- Aligns on `=` for endless methods
|
|
93
|
+
- Aligns traditional one-liners as if they had an invisible `=`
|
|
94
|
+
- Works with both instance and singleton methods
|
|
95
|
+
- Respects `Layout/LineLength` configuration
|
|
96
|
+
|
|
97
|
+
**Examples:**
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
# bad
|
|
101
|
+
def foo = 1
|
|
102
|
+
def barbaz = 2
|
|
103
|
+
|
|
104
|
+
# good
|
|
105
|
+
def foo = 1
|
|
106
|
+
def barbaz = 2
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
# bad (mixed endless and traditional)
|
|
111
|
+
def foo = 1
|
|
112
|
+
def bar() 2 end
|
|
113
|
+
|
|
114
|
+
# good
|
|
115
|
+
def foo = 1
|
|
116
|
+
def bar() 2 end
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
# bad (singleton methods)
|
|
121
|
+
def self.x = 1
|
|
122
|
+
def self.longer_name = 2
|
|
123
|
+
|
|
124
|
+
# good
|
|
125
|
+
def self.x = 1
|
|
126
|
+
def self.longer_name = 2
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Limitations:**
|
|
130
|
+
- Only aligns methods on consecutive lines at the same indentation level
|
|
131
|
+
- Only processes single-line methods
|
|
132
|
+
|
|
133
|
+
### Tablecop/CondenseWhen
|
|
134
|
+
|
|
135
|
+
Condenses multi-line `when` clauses to single lines using the `then` keyword and aligns them vertically.
|
|
136
|
+
|
|
137
|
+
**Enabled by default:** Yes
|
|
138
|
+
|
|
139
|
+
**Supports autocorrect:** Yes
|
|
140
|
+
|
|
141
|
+
**What it does:**
|
|
142
|
+
- Converts multi-line `when` clauses to single-line format with `then`
|
|
143
|
+
- Aligns `then` keywords across sibling `when` clauses for table-like appearance
|
|
144
|
+
- Only condenses when the result fits within `Layout/LineLength`
|
|
145
|
+
- Preserves complex bodies that shouldn't be condensed
|
|
146
|
+
|
|
147
|
+
**Examples:**
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
# bad
|
|
151
|
+
case foo
|
|
152
|
+
when 1
|
|
153
|
+
"one"
|
|
154
|
+
when 200
|
|
155
|
+
"two hundred"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# good
|
|
159
|
+
case foo
|
|
160
|
+
when 1 then "one"
|
|
161
|
+
when 200 then "two hundred"
|
|
162
|
+
end
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
# bad
|
|
167
|
+
case status
|
|
168
|
+
when :pending
|
|
169
|
+
handle_pending
|
|
170
|
+
when :approved
|
|
171
|
+
handle_approved
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# good
|
|
175
|
+
case status
|
|
176
|
+
when :pending then handle_pending
|
|
177
|
+
when :approved then handle_approved
|
|
178
|
+
end
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**What it skips:**
|
|
182
|
+
- Multi-statement bodies
|
|
183
|
+
- Bodies with heredocs
|
|
184
|
+
- Bodies with multi-line strings
|
|
185
|
+
- Bodies with comments between `when` and body
|
|
186
|
+
- Complex control flow (multi-line `if`/`case`)
|
|
187
|
+
- Multi-statement blocks
|
|
188
|
+
- Cases where condensing would exceed line length
|
|
189
|
+
|
|
190
|
+
**Example of what's left alone:**
|
|
191
|
+
|
|
192
|
+
```ruby
|
|
193
|
+
# left alone (multiple statements)
|
|
194
|
+
case foo
|
|
195
|
+
when 1
|
|
196
|
+
do_something
|
|
197
|
+
do_something_else
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# left alone (heredoc)
|
|
201
|
+
case foo
|
|
202
|
+
when 1
|
|
203
|
+
<<~MSG
|
|
204
|
+
Hello
|
|
205
|
+
MSG
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Tablecop/SafeEndlessMethod
|
|
210
|
+
|
|
211
|
+
Converts multi-line single-expression methods to single-line form, avoiding all the known bugs in RuboCop's `Style/EndlessMethod`.
|
|
212
|
+
|
|
213
|
+
**Enabled by default:** Yes
|
|
214
|
+
|
|
215
|
+
**Supports autocorrect:** Yes
|
|
216
|
+
|
|
217
|
+
**What it does:**
|
|
218
|
+
- Converts simple multi-line methods to endless method syntax (`def foo = expr`)
|
|
219
|
+
- Falls back to traditional one-liner (`def foo() expr end`) for methods with modifier-if/unless that call other methods
|
|
220
|
+
- Avoids RuboCop's `Style/EndlessMethod` bugs:
|
|
221
|
+
- Heredoc destruction
|
|
222
|
+
- Rescue clause orphaning
|
|
223
|
+
- module_eval context failures
|
|
224
|
+
- Modifier-if with dynamic method failures
|
|
225
|
+
|
|
226
|
+
**Examples:**
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
# bad
|
|
230
|
+
def foo
|
|
231
|
+
42
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# good
|
|
235
|
+
def foo = 42
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
# bad
|
|
240
|
+
def calculate(x, y)
|
|
241
|
+
x + y
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# good
|
|
245
|
+
def calculate(x, y) = x + y
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```ruby
|
|
249
|
+
# bad (modifier-if with method call)
|
|
250
|
+
def clear!
|
|
251
|
+
data_layer.clear! if data_layer.respond_to?(:clear!)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# good (uses traditional one-liner to avoid bugs)
|
|
255
|
+
def clear!() data_layer.clear! if data_layer.respond_to?(:clear!) end
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**What it skips:**
|
|
259
|
+
- Methods already on a single line
|
|
260
|
+
- Methods with multiple statements
|
|
261
|
+
- Methods with heredocs
|
|
262
|
+
- Methods with rescue/ensure clauses
|
|
263
|
+
- Setter methods (ending with `=`)
|
|
264
|
+
- Methods with multi-statement blocks
|
|
265
|
+
- Methods with complex control flow (multi-line `if`/`case`)
|
|
266
|
+
- Methods where condensing would exceed line length
|
|
267
|
+
|
|
268
|
+
## Built-in Cop Configuration
|
|
269
|
+
|
|
270
|
+
Tablecop sets opinionated defaults for RuboCop's built-in cops to achieve a table-like, condensed style. These are configured in `config/default.yml` and automatically applied when you use the plugin.
|
|
271
|
+
|
|
272
|
+
### Disabled Cops (Conflicts)
|
|
273
|
+
|
|
274
|
+
These cops are disabled because they conflict with Tablecop's alignment features:
|
|
275
|
+
|
|
276
|
+
```yaml
|
|
277
|
+
# Conflicts with Tablecop/AlignAssignments
|
|
278
|
+
Layout/SpaceAroundOperators:
|
|
279
|
+
Enabled: false # Enforces exactly one space, undoes alignment
|
|
280
|
+
|
|
281
|
+
# Conflicts with Tablecop/SafeEndlessMethod
|
|
282
|
+
Style/SingleLineDoEndBlock:
|
|
283
|
+
Enabled: false # Would reformat SafeEndlessMethod output
|
|
284
|
+
|
|
285
|
+
Style/SingleLineMethods:
|
|
286
|
+
Enabled: false # Would reformat SafeEndlessMethod output
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Disabled Cops (Known Bugs)
|
|
290
|
+
|
|
291
|
+
These cops have critical autocorrect bugs and are replaced by safer Tablecop equivalents:
|
|
292
|
+
|
|
293
|
+
```yaml
|
|
294
|
+
# REPLACED by Tablecop/SafeEndlessMethod
|
|
295
|
+
Style/EndlessMethod:
|
|
296
|
+
Enabled: false # Destroys heredocs, orphans rescue clauses
|
|
297
|
+
|
|
298
|
+
Style/AmbiguousEndlessMethodDefinition:
|
|
299
|
+
Enabled: false # Related to EndlessMethod issues
|
|
300
|
+
|
|
301
|
+
# BUGS: Creates syntax errors and silent logic bugs
|
|
302
|
+
Style/DoubleNegation:
|
|
303
|
+
Enabled: false # !!false ≠ !false.nil?
|
|
304
|
+
|
|
305
|
+
Style/HashExcept:
|
|
306
|
+
Enabled: false # Breaks mixed symbol/string key handling
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Layout Configuration
|
|
310
|
+
|
|
311
|
+
```yaml
|
|
312
|
+
Layout/HashAlignment:
|
|
313
|
+
EnforcedHashRocketStyle: table
|
|
314
|
+
EnforcedColonStyle: table
|
|
315
|
+
EnforcedLastArgumentHashStyle: always_inspect
|
|
316
|
+
|
|
317
|
+
Layout/ExtraSpacing:
|
|
318
|
+
AllowForAlignment: true
|
|
319
|
+
AllowBeforeTrailingComments: true
|
|
320
|
+
ForceEqualSignAlignment: false # Would cause infinite loops with heredocs
|
|
321
|
+
|
|
322
|
+
Layout/FirstArrayElementIndentation:
|
|
323
|
+
EnforcedStyle: consistent # Not aligned to brackets
|
|
324
|
+
|
|
325
|
+
Layout/FirstArgumentIndentation:
|
|
326
|
+
EnforcedStyle: consistent # Not aligned to parens
|
|
327
|
+
|
|
328
|
+
Layout/SpaceInsideHashLiteralBraces:
|
|
329
|
+
EnforcedStyle: space # { foo: 1 } not {foo: 1}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
See `config/default.yml` for the complete configuration.
|
|
333
|
+
|
|
334
|
+
## Known Issues
|
|
335
|
+
|
|
336
|
+
RuboCop has several autocorrect bugs that can destroy code. Tablecop's default configuration disables or works around these where possible. See [docs/known-issues.md](docs/known-issues.md) for detailed documentation of:
|
|
337
|
+
|
|
338
|
+
| Bug | Cop | Impact | Tablecop Mitigation |
|
|
339
|
+
|-----|-----|--------|---------------------|
|
|
340
|
+
| Heredoc destruction | `Style/EndlessMethod` | Data loss | Disabled; use `Tablecop/SafeEndlessMethod` |
|
|
341
|
+
| Rescue orphaning | `Style/EndlessMethod` | Scope/syntax errors | Disabled; use `Tablecop/SafeEndlessMethod` |
|
|
342
|
+
| module_eval failures | `Style/EndlessMethod` | Runtime NameError | Disabled; use `Tablecop/SafeEndlessMethod` |
|
|
343
|
+
| Modifier-if parse failures | `Style/EndlessMethod` | Parse-time NameError | Disabled; use `Tablecop/SafeEndlessMethod` |
|
|
344
|
+
| Heredoc alignment loop | `Layout/ExtraSpacing` | Process hangs | `ForceEqualSignAlignment: false` |
|
|
345
|
+
| `!!false` → `!false.nil?` | `Style/DoubleNegation` | Silent logic bug | Disabled |
|
|
346
|
+
| Mixed key types | `Style/HashExcept` | Data corruption | Disabled |
|
|
347
|
+
|
|
348
|
+
## Example Output
|
|
349
|
+
|
|
350
|
+
Here's what code looks like with Tablecop's formatting:
|
|
351
|
+
|
|
352
|
+
```ruby
|
|
353
|
+
# Method alignment
|
|
354
|
+
class Calculator
|
|
355
|
+
def add(x, y) = x + y
|
|
356
|
+
def subtract(x, y) = x - y
|
|
357
|
+
def multiply(x, y) = x * y
|
|
358
|
+
def divide(x, y) = x / y
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# Assignment alignment
|
|
362
|
+
class Config
|
|
363
|
+
BASE_URL = "https://example.com"
|
|
364
|
+
API_VERSION = "v1"
|
|
365
|
+
TIMEOUT = 30
|
|
366
|
+
|
|
367
|
+
def initialize
|
|
368
|
+
@cache = {}
|
|
369
|
+
@enabled = true
|
|
370
|
+
@retries = 3
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# Case statement condensing
|
|
375
|
+
def status_message(status)
|
|
376
|
+
case status
|
|
377
|
+
when :pending then "Waiting for approval"
|
|
378
|
+
when :approved then "Ready to proceed"
|
|
379
|
+
when :rejected then "Cannot continue"
|
|
380
|
+
when :completed then "All done"
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# Hash alignment
|
|
385
|
+
config = {
|
|
386
|
+
host: "localhost",
|
|
387
|
+
port: 3000,
|
|
388
|
+
ssl: true,
|
|
389
|
+
timeout: 30,
|
|
390
|
+
retries: 3,
|
|
391
|
+
pool: 10
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Philosophy
|
|
396
|
+
|
|
397
|
+
Tablecop prioritizes:
|
|
398
|
+
|
|
399
|
+
1. **Vertical alignment** - Code aligned in columns is easier to scan
|
|
400
|
+
2. **Density** - Single-line expressions where appropriate reduce scrolling
|
|
401
|
+
3. **Safety** - Avoid RuboCop's known autocorrect bugs
|
|
402
|
+
4. **Readability** - Only condense when it improves clarity
|
|
403
|
+
|
|
404
|
+
This style works best for:
|
|
405
|
+
- Configuration files with many similar assignments
|
|
406
|
+
- Simple data transformations and mappings
|
|
407
|
+
- API clients with many similar methods
|
|
408
|
+
- DSLs with repetitive structures
|
|
409
|
+
|
|
410
|
+
This style may not work well for:
|
|
411
|
+
- Complex business logic with deep nesting
|
|
412
|
+
- Long method chains
|
|
413
|
+
- Files with highly variable line lengths
|
|
414
|
+
|
|
415
|
+
## Development
|
|
416
|
+
|
|
417
|
+
After checking out the repo, run `bundle install` to install dependencies. Then:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
# Run RuboCop on the project
|
|
421
|
+
bundle exec rubocop
|
|
422
|
+
|
|
423
|
+
# Run autocorrect
|
|
424
|
+
bundle exec rubocop -a
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Contributing
|
|
428
|
+
|
|
429
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/v2-io/tablecop.
|
|
430
|
+
|
|
431
|
+
## License
|
|
432
|
+
|
|
433
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE).
|
data/config/default.yml
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Tablecop Default Configuration
|
|
2
|
+
#
|
|
3
|
+
# Table-like, condensed Ruby formatting.
|
|
4
|
+
# These defaults prioritize vertical alignment and single-line expressions
|
|
5
|
+
# where they improve readability.
|
|
6
|
+
#
|
|
7
|
+
# CAUTION: Some alignment cops have known bugs with autocorrect.
|
|
8
|
+
# See docs/known-issues.md for details.
|
|
9
|
+
|
|
10
|
+
# =============================================================================
|
|
11
|
+
# Tablecop Custom Cops
|
|
12
|
+
# =============================================================================
|
|
13
|
+
|
|
14
|
+
Tablecop/AlignAssignments:
|
|
15
|
+
Description: "Align consecutive assignments on the = operator."
|
|
16
|
+
Enabled: true
|
|
17
|
+
VersionAdded: "0.1.0"
|
|
18
|
+
|
|
19
|
+
Tablecop/AlignMethods:
|
|
20
|
+
Description: "Align contiguous single-line method definitions."
|
|
21
|
+
Enabled: true
|
|
22
|
+
VersionAdded: "0.1.0"
|
|
23
|
+
|
|
24
|
+
Tablecop/CondenseWhen:
|
|
25
|
+
Description: "Condense multi-line `when` clauses to single lines when possible."
|
|
26
|
+
Enabled: true
|
|
27
|
+
VersionAdded: "0.1.0"
|
|
28
|
+
|
|
29
|
+
Tablecop/SafeEndlessMethod:
|
|
30
|
+
Description: "Convert multi-line methods to single-line, avoiding RuboCop bugs."
|
|
31
|
+
Enabled: true
|
|
32
|
+
VersionAdded: "0.1.0"
|
|
33
|
+
|
|
34
|
+
# =============================================================================
|
|
35
|
+
# Disabled Cops (conflict with Tablecop alignment)
|
|
36
|
+
# =============================================================================
|
|
37
|
+
|
|
38
|
+
# DISABLED: Conflicts with Tablecop/AlignAssignments.
|
|
39
|
+
# SpaceAroundOperators enforces exactly one space, which undoes alignment padding.
|
|
40
|
+
Layout/SpaceAroundOperators:
|
|
41
|
+
Enabled: false
|
|
42
|
+
|
|
43
|
+
# DISABLED: Conflicts with Tablecop/SafeEndlessMethod.
|
|
44
|
+
# These cops try to reformat blocks/methods that SafeEndlessMethod creates,
|
|
45
|
+
# causing infinite autocorrect loops.
|
|
46
|
+
Style/SingleLineDoEndBlock:
|
|
47
|
+
Enabled: false
|
|
48
|
+
|
|
49
|
+
Style/SingleLineMethods:
|
|
50
|
+
Enabled: false
|
|
51
|
+
|
|
52
|
+
# =============================================================================
|
|
53
|
+
# Disabled Cops (replaced by Tablecop equivalents)
|
|
54
|
+
# =============================================================================
|
|
55
|
+
|
|
56
|
+
# DISABLED: Style/EndlessMethod has critical autocorrect bugs:
|
|
57
|
+
# - Destroys heredoc content entirely
|
|
58
|
+
# - Breaks rescue clauses (orphans them outside the class)
|
|
59
|
+
# - Fails in module_eval contexts (Toys, DSLs)
|
|
60
|
+
# - Fails with modifier-if calling dynamic methods
|
|
61
|
+
# See docs/known-issues.md for details.
|
|
62
|
+
# Use Tablecop/SafeEndlessMethod instead.
|
|
63
|
+
Style/EndlessMethod:
|
|
64
|
+
Enabled: false
|
|
65
|
+
|
|
66
|
+
# Related to EndlessMethod - can cause issues in the same contexts
|
|
67
|
+
Style/AmbiguousEndlessMethodDefinition:
|
|
68
|
+
Enabled: false
|
|
69
|
+
|
|
70
|
+
# =============================================================================
|
|
71
|
+
# Layout - Alignment
|
|
72
|
+
# =============================================================================
|
|
73
|
+
|
|
74
|
+
# Require spaces inside hash braces: { foo: 1 }
|
|
75
|
+
Layout/SpaceInsideHashLiteralBraces:
|
|
76
|
+
EnforcedStyle: space
|
|
77
|
+
|
|
78
|
+
# Allow extra spacing for alignment
|
|
79
|
+
# NOTE: ForceEqualSignAlignment has a bug with compound operators (||=, &&=)
|
|
80
|
+
# that can create syntax errors. Use with caution.
|
|
81
|
+
Layout/ExtraSpacing:
|
|
82
|
+
AllowForAlignment: true
|
|
83
|
+
AllowBeforeTrailingComments: true
|
|
84
|
+
ForceEqualSignAlignment: false # Disabled due to ||= bug
|
|
85
|
+
|
|
86
|
+
# Table-style hash alignment
|
|
87
|
+
# NOTE: Can cause infinite loops when combined with other alignment cops.
|
|
88
|
+
# If you experience hangs, try switching to 'key' style.
|
|
89
|
+
Layout/HashAlignment:
|
|
90
|
+
EnforcedHashRocketStyle: table
|
|
91
|
+
EnforcedColonStyle: table
|
|
92
|
+
EnforcedLastArgumentHashStyle: always_inspect
|
|
93
|
+
|
|
94
|
+
# Consistent indentation (not aligned to brackets/parens)
|
|
95
|
+
Layout/FirstArrayElementIndentation:
|
|
96
|
+
EnforcedStyle: consistent
|
|
97
|
+
|
|
98
|
+
Layout/FirstArgumentIndentation:
|
|
99
|
+
EnforcedStyle: consistent
|