rubocop-neeto 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []