rubocop-neeto 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: 136ee5992041eb74e0f079c4e3617e39302e9ade42e05484f82b75992df185a9
4
+ data.tar.gz: 930fb053024e53176da3893e86ac515dda1656b39937191184077713edd8d804
5
+ SHA512:
6
+ metadata.gz: ed24a08a0fd17e77135c63341d1e31a2a17ba65c718fc2d887a67f0d74a05ad9494c9ca6ae2f61952a6cb989e913d70bec8a38eea2eff1a4d038d16397a18be9
7
+ data.tar.gz: 62d45fde06c377cb717a4b2194c1592480ad3917f4ea46f4097c71896f4f2e58fc5380f72fa649c4458c4577d5d3deb623ab34030cc73d82eb628f3cf1653829
@@ -0,0 +1,19 @@
1
+ version: v1.0
2
+
3
+ plan: standard-2
4
+
5
+ commands:
6
+ - checkout
7
+ - neetoci-version ruby 3.2.4
8
+ - bundle config path 'vendor/bundle'
9
+ - cache restore
10
+ - bundle install --jobs 1
11
+ - cache store
12
+ - bundle exec rubocop
13
+ - bundle exec rake test
14
+ - bundle exec rspec
15
+
16
+ triggers:
17
+ - event: branch
18
+ branch_name: main
19
+ - event: pull_request
data/.rbenv ADDED
@@ -0,0 +1 @@
1
+ 3.2.4
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,619 @@
1
+ # cspell:Disable
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 3.2.4
5
+ # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
6
+ # to ignore them, so only the ones explicitly set in this file are enabled.
7
+ DisabledByDefault: true
8
+ # From time to time rubocop adds new cops to say rails etc.
9
+ # So rather than disabling them it's better to enable them,
10
+ # try it out and then disable them manually one by one.
11
+ NewCops: enable
12
+ # Disable extension suggestions
13
+ SuggestExtensions: false
14
+ Exclude:
15
+ - "app/javascript/**/*"
16
+ - "test/dummy/app/javascript/**/*"
17
+ - "app/assets/**/*"
18
+ - "test/dummy/app/assets/**/*"
19
+ - "app/views/**/*.erb"
20
+ - "test/dummy/app/views/**/*.erb"
21
+ - "lib/tasks/**/*"
22
+ - "test/dummy/lib/tasks/**/*"
23
+ - ".vscode/**/*"
24
+ - ".husky/**/*"
25
+ - ".bundle/**/*"
26
+ - ".circleci/**/*"
27
+ - ".semaphore/**/*"
28
+ - "**/log/**/*"
29
+ - "**/public/**/*"
30
+ - "**/tmp/**/*"
31
+ - "**/templates/**/*"
32
+ - "**/vendor/**/*"
33
+ - "node_modules/**/*"
34
+ - "bin/**/*"
35
+ - "test/dummy/bin/**/*"
36
+ - "config/webpack/**/*"
37
+ - "db/schema.rb"
38
+ - "test/dummy/db/schema.rb"
39
+ - "db/data_schema.rb"
40
+ - "test/dummy/db/data_schema.rb"
41
+ - "*.gemspec"
42
+ - "*.yml"
43
+
44
+ # ====================================================================================================
45
+ # All access modifier related rules
46
+ # ====================================================================================================
47
+ # Add a newline before and after private keyword or other access modifiers
48
+ Layout/EmptyLinesAroundAccessModifier:
49
+ Enabled: true
50
+
51
+ # This cop checks for redundant access modifiers, including those with no code,
52
+ # those which are repeated, and leading `public` modifiers in a class or module body.
53
+ Lint/UselessAccessModifier:
54
+ Enabled: true
55
+
56
+ # Checks for debug calls
57
+ Lint/Debugger:
58
+ Enabled: true
59
+
60
+ # # bad
61
+ # class Foo
62
+ # private def bar; end
63
+ # private def baz; end
64
+ # end
65
+ # # good
66
+ # class Foo
67
+ # private
68
+ #
69
+ # def bar; end
70
+ # def baz; end
71
+ # end
72
+ Style/AccessModifierDeclarations:
73
+ Enabled: true
74
+
75
+ # # bad
76
+ # class Plumbus
77
+ # private
78
+ # def smooth; end
79
+ # end
80
+ # # good
81
+ # class Plumbus
82
+ # private
83
+ # def smooth; end
84
+ # end
85
+ Layout/AccessModifierIndentation:
86
+ Enabled: true
87
+
88
+ # ====================================================================================================
89
+ # All comment related rules
90
+ # ====================================================================================================
91
+ # Align comments with method definitions.
92
+ Layout/CommentIndentation:
93
+ Enabled: true
94
+
95
+ # Requires an empty line after frozen_string_literal: true comment
96
+ Layout/EmptyLineAfterMagicComment:
97
+ Enabled: true
98
+
99
+ # frozen_string_literal: true magic comment is required on the top of files
100
+ Style/FrozenStringLiteralComment:
101
+ Enabled: true
102
+ EnforcedStyle: always
103
+ SafeAutoCorrect: true
104
+
105
+ # ====================================================================================================
106
+ # All Class related rules
107
+ # ====================================================================================================
108
+ # Helps in brining the include statements etc to top of the class definition
109
+ Layout/ClassStructure:
110
+ Enabled: true
111
+ Description: "Enforces a canonical order of definitions within a class body."
112
+ StyleGuide: "https://github.com/rubocop/rails-style-guide#macro-style-methods"
113
+ Categories:
114
+ module_inclusions:
115
+ - include
116
+ - prepend
117
+ - extend
118
+ third_party:
119
+ - neeto_sso_track_widget_tokens
120
+ - devise
121
+ - serialize
122
+ scopes:
123
+ - default_scope
124
+ - scope
125
+ attributes:
126
+ - attribute
127
+ - attr_reader
128
+ - attr_writer
129
+ - attr_accessor
130
+ enum:
131
+ - enum
132
+ store:
133
+ # https://api.rubyonrails.org/classes/ActiveRecord/Store.html
134
+ - store
135
+ other_macros:
136
+ - delegate
137
+ - delegate_missing_to
138
+ - accepts_nested_attributes_for
139
+ validations:
140
+ - validate
141
+ - validates
142
+ - validates_acceptance_of
143
+ - validates_associated
144
+ - validates_confirmation_of
145
+ - validates_exclusion_of
146
+ - validates_format_of
147
+ - validates_inclusion_of
148
+ - validates_length_of
149
+ - validates_numericality_of
150
+ - validates_presence_of
151
+ - validates_uniqueness_of
152
+ - validates_each
153
+ - validate_with
154
+ callbacks:
155
+ - before_validation
156
+ - after_validation
157
+ - before_save
158
+ - around_save
159
+ - after_save
160
+ - before_update
161
+ - around_update
162
+ - after_update
163
+ - before_create
164
+ - after_create
165
+ - before_destroy
166
+ - around_destroy
167
+ - after_destroy
168
+ - after_commit
169
+ - after_update_commit
170
+ - after_create_commit
171
+ ExpectedOrder:
172
+ - module_inclusions
173
+ - third_party
174
+ - scopes
175
+ - constants
176
+ - attributes
177
+ - enum
178
+ - store
179
+ - associations
180
+ - validations
181
+ - callbacks
182
+ - other_macros
183
+ - initializer
184
+ - public_class_methods
185
+ - public_methods
186
+ - protected_methods
187
+ - private_methods
188
+
189
+ # In a regular class definition, no empty lines around the body.
190
+ # bad
191
+ # class Foo
192
+ #
193
+ # def bar
194
+ # # ...
195
+ # end
196
+ #
197
+ # end
198
+ #
199
+ # good
200
+ # class Foo
201
+ # def bar
202
+ # # ...
203
+ # end
204
+ # end
205
+ Layout/EmptyLinesAroundClassBody:
206
+ Enabled: true
207
+
208
+ # ====================================================================================================
209
+ # All Method related rules
210
+ # ====================================================================================================
211
+ # This cop checks whether class/module/method definitions are separated by one or more empty lines.
212
+ Layout/EmptyLineBetweenDefs:
213
+ Enabled: true
214
+
215
+ # This cop checks the . position in multi-line method calls.
216
+ # The dot should be leading rather than trailing.
217
+ Layout/DotPosition:
218
+ Enabled: true
219
+ EnforcedStyle: leading
220
+
221
+ # No space in method name and the arguments
222
+ Lint/ParenthesesAsGroupedExpression:
223
+ Enabled: true
224
+
225
+ # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg,
226
+ # when a boolean operator, && or ||, is chained along with this method/argument
227
+ Lint/RequireParentheses:
228
+ Enabled: true
229
+
230
+ # avoid redundant `return` expressions
231
+ Style/RedundantReturn:
232
+ Enabled: true
233
+ AllowMultipleReturnValues: true
234
+
235
+ # Ensures that exactly one space is used between a method name and the
236
+ # first argument for method calls without parentheses
237
+ Layout/SpaceBeforeFirstArg:
238
+ Enabled: true
239
+
240
+ # Methods that doesn't take any parameters shouldn't have paranthesis in its definition
241
+ Style/DefWithParentheses:
242
+ Enabled: true
243
+
244
+ # Defining a method with parameters needs parentheses.
245
+ Style/MethodDefParentheses:
246
+ Enabled: true
247
+
248
+ # # bad
249
+ # def some_method(arg1=:default, arg2=nil, arg3=[])
250
+ # # good
251
+ # def some_method(arg1 = :default, arg2 = nil, arg3 = [])
252
+ Layout/SpaceAroundEqualsInParameterDefault:
253
+ Enabled: true
254
+
255
+ # This cop checks for a line break before the first argument in a multi-line method call.
256
+ # # bad
257
+ # method(foo, bar,
258
+ # baz)
259
+ # # good
260
+ # method(
261
+ # foo, bar,
262
+ # baz)
263
+ Layout/FirstMethodArgumentLineBreak:
264
+ Enabled: true
265
+
266
+ # Method definitions after `private` or `protected` isolated calls need one
267
+ # extra level of indentation.
268
+ Layout/IndentationConsistency:
269
+ Enabled: true
270
+ EnforcedStyle: indented_internal_methods
271
+
272
+ # This cop checks the indentation of the method name part in method calls that span more than one line.
273
+ # # bad
274
+ # while myvariable
275
+ # .instance_method_call1
276
+ # .instance_method_call2
277
+ # # do something
278
+ # end
279
+ #
280
+ # # good
281
+ # while myvariable
282
+ # .instance_method_call1
283
+ # .instance_method_call2
284
+ #
285
+ # # do something
286
+ # end
287
+ Layout/MultilineMethodCallIndentation:
288
+ Enabled: true
289
+ EnforcedStyle: indented
290
+
291
+ # This cop ensures the indentation of the first parameter in a method definition.
292
+ Layout/FirstParameterIndentation:
293
+ Enabled: true
294
+ EnforcedStyle: consistent
295
+
296
+ # When we write method arguments in next line, indent it.
297
+ Layout/FirstArgumentIndentation:
298
+ Enabled: true
299
+ EnforcedStyle: consistent
300
+
301
+ # Alignment of args from second argument onwards should be indented
302
+ # # bad
303
+ # json.extract! comment,
304
+ # :id,
305
+ # :content,
306
+ # :created_at
307
+ # # good
308
+ # json.extract! comment,
309
+ # :id,
310
+ # :content,
311
+ # :created_at
312
+ Layout/ArgumentAlignment:
313
+ Enabled: true
314
+ EnforcedStyle: with_fixed_indentation
315
+
316
+ # In a regular method definition, no empty lines around the body.
317
+ Layout/EmptyLinesAroundMethodBody:
318
+ Enabled: true
319
+
320
+ # ====================================================================================================
321
+ # All Hash related rules
322
+ # ====================================================================================================
323
+ # EnforcedColonStyle: key
324
+ # # bad
325
+ # {
326
+ # foo: bar,
327
+ # ba: baz
328
+ # }
329
+ # {
330
+ # foo: bar,
331
+ # ba: baz
332
+ # }
333
+ # # good
334
+ # {
335
+ # foo: bar,
336
+ # ba: baz
337
+ # }
338
+ # EnforcedLastArgumentHashStyle: always_inspect
339
+ # # bad
340
+ # do_something({foo: 1,
341
+ # bar: 2})
342
+ # # good
343
+ # do_something(foo: 1,
344
+ # bar: 2)
345
+ Layout/HashAlignment:
346
+ Enabled: true
347
+ EnforcedColonStyle: key
348
+ EnforcedLastArgumentHashStyle: always_inspect
349
+
350
+ # This cop checks for a line break before the first element in a multi-line hash.
351
+ # # bad
352
+ # { a: 1,
353
+ # b: 2}
354
+ # # good
355
+ # {
356
+ # a: 1,
357
+ # b: 2 }
358
+ Layout/FirstHashElementLineBreak:
359
+ Enabled: true
360
+
361
+ # When using the `new_line` style:
362
+ # The closing brace of a multi-line hash literal must be on
363
+ # the line after the last element of the hash.
364
+ Layout/MultilineHashBraceLayout:
365
+ Enabled: true
366
+ EnforcedStyle: new_line
367
+
368
+ # # bad
369
+ # hash = {
370
+ # key: :value
371
+ # }
372
+ # but_in_a_method_call({
373
+ # its_like: :this
374
+ # })
375
+ # # good
376
+ # hash = {
377
+ # key: :value
378
+ # }
379
+ # and_in_a_method_call({
380
+ # no: :difference
381
+ # })
382
+ Layout/FirstHashElementIndentation:
383
+ Enabled: true
384
+ EnforcedStyle: consistent
385
+
386
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
387
+ Style/HashSyntax:
388
+ Enabled: true
389
+
390
+ # Use `{ a: 1 }` not `{a:1}`.
391
+ Layout/SpaceInsideHashLiteralBraces:
392
+ Enabled: true
393
+
394
+ # `no_comma`: Does not requires a comma after the last item in a hash
395
+ Style/TrailingCommaInHashLiteral:
396
+ Enabled: true
397
+
398
+ # ====================================================================================================
399
+ # All misc whitespace related rules
400
+ # ====================================================================================================
401
+ # bad
402
+ # def f(a:, b:2); {a:3}; end
403
+ # good
404
+ # def f(a:, b: 2); {a: 3}; end
405
+ Layout/SpaceAfterColon:
406
+ Enabled: true
407
+
408
+ # Ensures comma (,) is followed by some kind of space.
409
+ Layout/SpaceAfterComma:
410
+ Enabled: true
411
+
412
+ # Every ruby keyword should be surrounded by spaces
413
+ Layout/SpaceAroundKeyword:
414
+ Enabled: true
415
+
416
+ # Requires proper spacing around ruby operator symbols.
417
+ Layout/SpaceAroundOperators:
418
+ Enabled: true
419
+ ## Allows multiple spaces for keeping alignment
420
+ # {
421
+ # 1 => 2,
422
+ # 11 => 3
423
+ # }
424
+ AllowForAlignment: true
425
+
426
+ # Ensures comma symbol is not preceded by space
427
+ Layout/SpaceBeforeComma:
428
+ Enabled: true
429
+
430
+ # Use `foo {}` not `foo{}`.
431
+ Layout/SpaceBeforeBlockBraces:
432
+ Enabled: true
433
+
434
+ # Use `foo { bar }` not `foo {bar}`.
435
+ Layout/SpaceInsideBlockBraces:
436
+ Enabled: true
437
+
438
+ # enforces that parentheses do not have spaces
439
+ Layout/SpaceInsideParens:
440
+ Enabled: true
441
+
442
+ # No trailing whitespace.
443
+ Layout/TrailingWhitespace:
444
+ Enabled: true
445
+
446
+ # Require a space after comment
447
+ Layout/LeadingCommentSpace:
448
+ Enabled: true
449
+
450
+ # ====================================================================================================
451
+ # All empty lines related rules
452
+ # ====================================================================================================
453
+ # The `lf` style means that LF (Line Feed) is enforced on
454
+ # all platforms.
455
+ # # bad
456
+ # puts 'Hello' # Return character is CR+LF on all platfoms.
457
+ #
458
+ # # good
459
+ # puts 'Hello' # Return character is LF on all platfoms.
460
+ Layout/EndOfLine:
461
+ Enabled: true
462
+ EnforcedStyle: lf
463
+
464
+ # In a regular module definition, no empty lines around the body.
465
+ Layout/EmptyLinesAroundModuleBody:
466
+ Enabled: true
467
+
468
+ # # bad
469
+ # def foo
470
+ # return if need_return?
471
+ # bar
472
+ # end
473
+ #
474
+ # # good
475
+ # def foo
476
+ # return if need_return?
477
+ #
478
+ # bar
479
+ # end
480
+ Layout/EmptyLineAfterGuardClause:
481
+ Enabled: true
482
+
483
+ # Requires a single final blank line to the file.
484
+ # `final_blank_line` ensures a blank line before EOF.
485
+ # # bad
486
+ # class Foo; end # EOF
487
+ #
488
+ # # good
489
+ # class Foo; end
490
+ #
491
+ # # EOF
492
+ Layout/TrailingEmptyLines:
493
+ Enabled: true
494
+
495
+ # This cop checks for two or more consecutive blank lines.
496
+ # This rule is not same as TrailingEmptyLines, because:
497
+ # 1) It looks for empty lines throughout the file. Not just the end.
498
+ # # bad - It has two empty lines.
499
+ # some_method
500
+ # # one empty line
501
+ # # two empty lines
502
+ # some_method
503
+ #
504
+ # # good
505
+ # some_method
506
+ # # one empty line
507
+ # some_method
508
+ Layout/EmptyLines:
509
+ Enabled: true
510
+
511
+ # ====================================================================================================
512
+ # All naming convetion related rules for variables
513
+ # ====================================================================================================
514
+ # Refer: https://www.bigbinary.com/learn-rubyonrails-book/n+1-queries-and-memoization#bb-generated-p-id-44
515
+ # Sadly this cannot be auto-corrected.
516
+ Naming/MemoizedInstanceVariableName:
517
+ Enabled: true
518
+ EnforcedStyleForLeadingUnderscores: required
519
+ Severity: info
520
+
521
+ # ====================================================================================================
522
+ # All misc rules that don't fall into other categories
523
+ # ====================================================================================================
524
+ # Prefer &&/|| over and/or.
525
+ Style/AndOr:
526
+ Enabled: true
527
+
528
+ # Align `when` with `case`.
529
+ Layout/CaseIndentation:
530
+ Enabled: true
531
+
532
+ Layout/LineLength:
533
+ Enabled: true
534
+ Max: 120
535
+ AllowedPatterns: [
536
+ '^\s*#', # line that begins with comment
537
+ '^\s*"', # line that begins with double quote (long string literal)
538
+ '^\s*%{', # line that begins with percent literals (long string literal)
539
+ "^\\s*'", # line that begins with single quote (long string literal)
540
+ '"$', # line that ends with double quote (long string variable assignment)
541
+ "'$", # line that ends with single quote (long string variable assignment)
542
+ "}$", # line that ends with percent literals (long regex variable assignment)
543
+ '\/$', # line that ends with slash (long regex variable assignment)
544
+ ]
545
+
546
+ # Indent using two spaces
547
+ Layout/IndentationWidth:
548
+ Enabled: true
549
+ Width: 2
550
+
551
+ # Use spaces for indentation. Not tabs
552
+ Layout/IndentationStyle:
553
+ Enabled: true
554
+ EnforcedStyle: spaces
555
+
556
+ # Remove extra/unnecessary whitespace which's used for alignment.
557
+ # A developer shouldn't waste time indenting code with whitespaces.
558
+ Layout/ExtraSpacing:
559
+ Enabled: true
560
+ AllowForAlignment: false
561
+
562
+ # Helps in removing unwanted parentheses.
563
+ # # bad
564
+ # x += 1 while (x < 10)
565
+ # foo unless (bar || baz)
566
+ #
567
+ # if (x > 10)
568
+ # elsif (x < 3)
569
+ # end
570
+ #
571
+ # # good
572
+ # x += 1 while x < 10
573
+ # foo unless bar || baz
574
+ #
575
+ # if x > 10
576
+ # elsif x < 3
577
+ # end
578
+ Style/ParenthesesAroundCondition:
579
+ Enabled: true
580
+
581
+ # Enforce string literals to use double quotes everywhere
582
+ Style/StringLiterals:
583
+ Enabled: true
584
+ EnforcedStyle: double_quotes
585
+
586
+ # Use quotes for string literals when they are enough.
587
+ Style/RedundantPercentQ:
588
+ Enabled: true
589
+
590
+ # Align `end` with the matching keyword or starting expression except for
591
+ # assignments, where it should be aligned with the LHS.
592
+ Layout/EndAlignment:
593
+ AutoCorrect: true
594
+ Enabled: true
595
+ EnforcedStyleAlignWith: variable
596
+
597
+ # avoid lines terminated with a semicolon.
598
+ Style/Semicolon:
599
+ Enabled: true
600
+ # disallow multiple statements in a line
601
+ AllowAsExpressionSeparator: false
602
+
603
+ # Corrects usage of :true/:false to true/false
604
+ Lint/BooleanSymbol:
605
+ Enabled: true
606
+
607
+ # ====================================================================================================
608
+ # All flow(if/while/for/until) statements related
609
+ # ====================================================================================================
610
+ Lint/AssignmentInCondition:
611
+ Enabled: true
612
+ AllowSafeAssignment: true
613
+
614
+ # ====================================================================================================
615
+ # All Bundler cop rules
616
+ # ====================================================================================================
617
+ Bundler/OrderedGems:
618
+ Enabled: true
619
+ TreatCommentsAsGroupSeparators: true
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 BigBinary
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/Procfile ADDED
@@ -0,0 +1,2 @@
1
+ web: yard server
2
+ release: yard doc
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # RuboCop::Neeto
2
+
3
+ ## Cops
4
+
5
+ | Cop | Documentation | Source code |
6
+ |--------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|
7
+ | [UnsafeTableDeletion](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/UnsafeTableDeletion) | [documentation](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/UnsafeTableDeletion) | [source code](https://github.com/bigbinary/rubocop-neeto/blob/main/lib/rubocop/cop/neeto/unsafe_table_deletion.rb) |
8
+ | [UnsafeColumnDeletion](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/UnsafeColumnDeletion) | [documentation](https://rubocop-neeto.neetodeployapp.com/docs/RuboCop/Cop/Neeto/UnsafeColumnDeletion) | [source code](https://github.com/bigbinary/rubocop-neeto/blob/main/lib/rubocop/cop/neeto/unsafe_column_deletion.rb) |
9
+
10
+ ## Installation
11
+
12
+ Install the gem and add to the application's Gemfile by executing:
13
+
14
+ $ bundle add rubocop-neeto
15
+
16
+ If bundler is not being used to manage dependencies, install the gem by executing:
17
+
18
+ $ gem install rubocop-neeto
19
+
20
+ ## Usage
21
+
22
+ Add the following line to your `.rubocop.yml` file.
23
+
24
+ ```yaml
25
+ require: rubocop-neeto
26
+ ```
27
+
28
+ Alternatively, use the following array notation when specifying multiple extensions.
29
+
30
+ ```yaml
31
+ require:
32
+ - rubocop-other-extension
33
+ - rubocop-neeto
34
+ ```
35
+
36
+ Now, run the `rubocop` command ti load `rubocop-neeto` cops together with the
37
+ standard cops.
38
+
39
+ ## Development
40
+
41
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
42
+
43
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
44
+
45
+ ## Contributing
46
+
47
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bigbinary/rubocop-neeto.
48
+
49
+ ## License
50
+
51
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test rubocop]
13
+
14
+ require "rspec/core/rake_task"
15
+
16
+ RSpec::Core::RakeTask.new(:spec) do |spec|
17
+ spec.pattern = FileList["spec/**/*_spec.rb"]
18
+ end
19
+
20
+ desc "Generate a new cop with a template"
21
+ task :new_cop, [:cop] do |_task, args|
22
+ require "rubocop"
23
+
24
+ cop_name = args.fetch(:cop) do
25
+ warn "usage: bundle exec rake new_cop[Department/Name]"
26
+ exit!
27
+ end
28
+
29
+ generator = RuboCop::Cop::Generator.new(cop_name)
30
+
31
+ generator.write_source
32
+ generator.write_spec
33
+ generator.inject_require(root_file_path: "lib/rubocop/cop/neeto_cops.rb")
34
+ generator.inject_config(config_file_path: "config/default.yml")
35
+
36
+ puts generator.todo
37
+ end
@@ -0,0 +1,25 @@
1
+ Neeto/UnsafeTableDeletion:
2
+ Description: >-
3
+ `drop_table` is considered as a dangerous operation. If not used correctly,
4
+ it could cause irreversible data loss. It is advised to rename the table
5
+ to `table_name_deprecated_on_yyyy_mm_dd` instead. The renamed table can be
6
+ safely dropped in a later migration. The cop permits dropping tables
7
+ that are named in the above format.
8
+ Enabled: true
9
+ Severity: refactor
10
+ VersionAdded: '0.1'
11
+ Include:
12
+ - db/**/*.rb
13
+
14
+ Neeto/UnsafeColumnDeletion:
15
+ Description: >-
16
+ `remove_column` is considered as a dangerous operation. If not used
17
+ correctly, it could cause irreversible data loss. It is advised to rename
18
+ the column to `column_name_deprecated_on_yyyy_mm_dd` instead. The renamed
19
+ column can be safely removed in a later migration. The cop permits
20
+ removing columns that are named in the above format.
21
+ Enabled: true
22
+ Severity: refactor
23
+ VersionAdded: '0.1'
24
+ Include:
25
+ - db/**/*.rb
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Neeto
6
+ # `remove_column` is considered as a dangerous operation. If not used
7
+ # correctly, it could cause irreversible data loss. It is advised to
8
+ # rename the column to `column_name_deprecated_on_yyyy_mm_dd` instead.
9
+ # The renamed column can be safely dropped in a later migration. The cop
10
+ # permits dropping columns that are named in the above format.
11
+ #
12
+ # @example UnsafeColumnDeletion: true (default)
13
+ # # Enforces the usage of `rename_column` over `remove_column`.
14
+ #
15
+ # # bad
16
+ # remove_column :users, :email
17
+ #
18
+ # # bad
19
+ # change_table :users do |t|
20
+ # t.remove :email
21
+ # end
22
+ #
23
+ # # good
24
+ # remove_column :users, :email_deprecated_on_2024_08_09
25
+ #
26
+ # # good
27
+ # drop_table :users do |t|
28
+ # t.remove :email_deprecated_on_2024_08_09
29
+ # end
30
+ #
31
+ class UnsafeColumnDeletion < Base
32
+ SAFE_COLUMN_NAME_REGEX = /\w+_deprecated_on_\d{4}_\d{2}_\d{2}/
33
+ CURRENT_DATE = DateTime.now.strftime("%Y_%m_%d")
34
+
35
+ MSG_REMOVE_COLUMN = "'remove_column' is a dangerous operation. If " \
36
+ "not used correctly, it could cause irreversible data loss. You must perform " \
37
+ "'rename_column :%{table_name}, %{column_name}, :%{column_name}_deprecated_on_#{CURRENT_DATE}' " \
38
+ "instead. The renamed column can be safely dropped in a future migration."
39
+
40
+ MSG_CHANGE_TABLE = "'t.remove' is a dangerous operation. If not used correctly, " \
41
+ "it could cause irreversible data loss. You must perform " \
42
+ "'t.rename :%{column_name}, :%{column_name}_deprecated_on_#{CURRENT_DATE}' " \
43
+ "instead. The renamed column can be safely dropped in a future migration."
44
+
45
+ RESTRICT_ON_SEND = %i[remove_column change_table].freeze
46
+
47
+ def_node_matcher :unsafe_remove_column?, <<~PATTERN
48
+ (send nil? :remove_column
49
+ ({sym str} $_)
50
+ ({sym str} $_)
51
+ ...)
52
+ PATTERN
53
+
54
+ def_node_matcher :unsafe_remove_column_change_table?, <<~PATTERN
55
+ (block (send nil? :change_table _ ...) ...)
56
+ PATTERN
57
+
58
+ def on_send(node)
59
+ return unless unsafe_remove_column?(node)
60
+
61
+ unsafe_remove_column?(node) do |table_name, column_name|
62
+ message = format(MSG_REMOVE_COLUMN, table_name:, column_name:)
63
+ add_offense(node, message:) unless SAFE_COLUMN_NAME_REGEX.match?(column_name)
64
+ end
65
+ end
66
+
67
+ def on_block(node)
68
+ return unless unsafe_remove_column_change_table?(node)
69
+
70
+ node.each_descendant(:send) do |send_node|
71
+ next unless send_node.method_name == :remove
72
+
73
+ column_name = send_node.arguments.first.value
74
+ message = format(MSG_CHANGE_TABLE, column_name:)
75
+ add_offense(send_node, message:) unless SAFE_COLUMN_NAME_REGEX.match?(column_name)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Neeto
6
+ # `drop_table` is considered as a dangerous operation. If not used
7
+ # correctly, it could cause irreversible data loss. It is advised to
8
+ # rename the table to `table_name_deprecated_on_yyyy_mm_dd` instead. The
9
+ # renamed table can be safely dropped in a later migration. The cop
10
+ # permits dropping tables that are named in the above format.
11
+ #
12
+ # @example UnsafeTableDeletion: true (default)
13
+ # # Enforces the usage of `rename_table` over `drop_table`.
14
+ #
15
+ # # bad
16
+ # drop_table :users
17
+ #
18
+ # # bad
19
+ # drop_table :users do |t|
20
+ # t.string :email, null: false
21
+ # t.string :first_name, null: false
22
+ # end
23
+ #
24
+ # # good
25
+ # drop_table :users_deprecated_on_2024_08_09
26
+ #
27
+ # # good
28
+ # drop_table :users_deprecated_on_2024_08_09 do |t|
29
+ # t.string :email, null: false
30
+ # t.string :first_name, null: false
31
+ # end
32
+ #
33
+ class UnsafeTableDeletion < Base
34
+ SAFE_TABLE_NAME_REGEX = /\w+_deprecated_on_\d{4}_\d{2}_\d{2}/
35
+ CURRENT_DATE = DateTime.now.strftime("%Y_%m_%d")
36
+
37
+ MSG = "'drop_table' is a dangerous operation. If not used correctly, " \
38
+ "it could cause irreversible data loss. You must perform " \
39
+ "'rename_table :%{table_name}, :%{table_name}_deprecated_on_#{CURRENT_DATE}' " \
40
+ "instead. The renamed table can be safely dropped in a future migration."
41
+
42
+ RESTRICT_ON_SEND = %i[drop_table].freeze
43
+
44
+ def_node_matcher :unsafe_drop_table?, <<~PATTERN
45
+ (send nil? :drop_table ({sym str} $_) ...)
46
+ PATTERN
47
+
48
+ def on_send(node)
49
+ return unless unsafe_drop_table?(node)
50
+
51
+ unsafe_drop_table?(node) do |table_name|
52
+ message = format(MSG, table_name:)
53
+ add_offense(node, message:) unless SAFE_TABLE_NAME_REGEX.match?(table_name)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "neeto/unsafe_table_deletion"
4
+ require_relative "neeto/unsafe_column_deletion"
@@ -0,0 +1,18 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Neeto
6
+ # @!visibility private
7
+ module Inject
8
+ def self.defaults!
9
+ path = CONFIG_DEFAULT.to_s
10
+ hash = ConfigLoader.send(:load_yaml_configuration, path)
11
+ config = Config.new(hash, path).tap(&:make_excludes_absolute)
12
+ puts "configuration from #{path}" if ConfigLoader.debug?
13
+ config = ConfigLoader.merge_with_default(config, path)
14
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Neeto
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "yaml"
5
+ require_relative "neeto/version"
6
+
7
+ module RuboCop
8
+ # @!visibility private
9
+ module Neeto
10
+ class Error < StandardError; end
11
+
12
+ PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
13
+ CONFIG_DEFAULT = PROJECT_ROOT.join("config", "default.yml").freeze
14
+ CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
15
+
16
+ private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ require_relative "rubocop/neeto"
6
+ require_relative "rubocop/neeto/version"
7
+ require_relative "rubocop/neeto/inject"
8
+
9
+ RuboCop::Neeto::Inject.defaults!
10
+
11
+ require_relative "rubocop/cop/neeto_cops"
data/neeto-deploy.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "rubocop-neeto",
3
+ "scripts": {},
4
+ "stack": "heroku-20",
5
+ "formation": {},
6
+ "addons": [],
7
+ "buildpacks": [
8
+ {
9
+ "url": "heroku/ruby"
10
+ }
11
+ ]
12
+ }
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubocop-neeto
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Abhay V Ashokan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-07-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email:
29
+ - abhay.ashokan@bigbinary.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".neetoci/default.yml"
35
+ - ".rbenv"
36
+ - ".rspec"
37
+ - ".rubocop.yml"
38
+ - ".ruby-version"
39
+ - LICENSE
40
+ - Procfile
41
+ - README.md
42
+ - Rakefile
43
+ - config/default.yml
44
+ - lib/rubocop-neeto.rb
45
+ - lib/rubocop/cop/neeto/unsafe_column_deletion.rb
46
+ - lib/rubocop/cop/neeto/unsafe_table_deletion.rb
47
+ - lib/rubocop/cop/neeto_cops.rb
48
+ - lib/rubocop/neeto.rb
49
+ - lib/rubocop/neeto/inject.rb
50
+ - lib/rubocop/neeto/version.rb
51
+ - neeto-deploy.json
52
+ homepage: https://github.com/bigbinary/rubocop-neeto
53
+ licenses: []
54
+ metadata:
55
+ homepage_uri: https://github.com/bigbinary/rubocop-neeto
56
+ source_code_uri: https://github.com/bigbinary/rubocop-neeto
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 3.4.19
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: Custom RuboCop cops for Neeto
76
+ test_files: []