rubomop 0.1.0 → 1.0.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 +4 -4
- data/.ruby-version +1 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +20 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +88 -45
- data/README.md +45 -13
- data/exe/rubomop +1 -1
- data/lib/rubomop/cop.rb +68 -21
- data/lib/rubomop/named_mop.rb +12 -0
- data/lib/rubomop/random_mop.rb +97 -0
- data/lib/rubomop/runner.rb +106 -25
- data/lib/rubomop/todo_file.rb +12 -9
- data/lib/rubomop/version.rb +1 -1
- data/lib/rubomop.rb +9 -6
- metadata +41 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 216a8fe4da9335c5a7c12ee8e5660003658aab305804acf99bb69c8493b357d1
|
4
|
+
data.tar.gz: 86644a5f0e10bf9d744fa9e7c516b5749cc303ced54991fd6062f25c3ba87e1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3480c30528e1bf9439bb8b8c7c1de4dc7ce5f77e38c234640eacad02fbdd9365cc739b2b205f741635fbff4145ae3a2725db611d83af0365ade53efedbe8d0da
|
7
|
+
data.tar.gz: ff974af44e598fd848c50f5be23f96515c446a5e674344b2b972b026c99bf25899fb88fee67d416b3b45ae0c4ca8927934ae9f43e0372f36b306ae9bfbdbe8d7
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.8
|
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
|
-
## [
|
1
|
+
## [1.0.0] - 7/31/2025
|
2
2
|
|
3
|
-
|
3
|
+
- Allow for a second run type that removes a specific cop from the todo
|
4
|
+
- Allow for running the cleanup on a different directory
|
5
|
+
- Allow for the difference between safe and unsafe autocorrect
|
6
|
+
- Drop support for Ruby 3.1 and lower
|
7
|
+
- Handles the case where Rubocop puts criteria and not exclusions in the to-do
|
8
|
+
|
9
|
+
## [0.3.0] - 2022-08-12
|
10
|
+
|
11
|
+
- More accurately update offense count in todo file after running rubocop
|
12
|
+
|
13
|
+
## [0.2.0] - 2022-07-22
|
14
|
+
|
15
|
+
- Adds for a .rubomop.yml file with configuration options
|
16
|
+
- Command line switch to override config file name
|
17
|
+
- Allows for only/except for specific cops by name or pattern
|
18
|
+
- Allows for excluding specific file patterns from being changed
|
19
|
+
- Only runs rubocop on selected files, not on the whole repo
|
20
|
+
|
21
|
+
## [0.1.0] - 2022-07-20
|
4
22
|
|
5
23
|
- Initial release
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,72 +1,115 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubomop (
|
5
|
-
activesupport (
|
6
|
-
date_by_example (
|
4
|
+
rubomop (1.0.0)
|
5
|
+
activesupport (>= 7.0)
|
6
|
+
date_by_example (~> 0.1)
|
7
|
+
literal
|
8
|
+
zeitwerk (~> 2.7.0)
|
7
9
|
|
8
10
|
GEM
|
9
11
|
remote: https://rubygems.org/
|
10
12
|
specs:
|
11
|
-
activesupport (
|
12
|
-
|
13
|
+
activesupport (8.0.2)
|
14
|
+
base64
|
15
|
+
benchmark (>= 0.3)
|
16
|
+
bigdecimal
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
18
|
+
connection_pool (>= 2.2.5)
|
19
|
+
drb
|
13
20
|
i18n (>= 1.6, < 2)
|
21
|
+
logger (>= 1.4.2)
|
14
22
|
minitest (>= 5.1)
|
15
|
-
|
16
|
-
|
23
|
+
securerandom (>= 0.3)
|
24
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
25
|
+
uri (>= 0.13.1)
|
26
|
+
ast (2.4.3)
|
17
27
|
awesome_print (1.9.2)
|
18
|
-
|
28
|
+
base64 (0.3.0)
|
29
|
+
benchmark (0.4.1)
|
30
|
+
bigdecimal (3.2.2)
|
31
|
+
concurrent-ruby (1.3.5)
|
32
|
+
connection_pool (2.5.3)
|
19
33
|
date_by_example (0.1.1)
|
20
|
-
diff-lcs (1.
|
21
|
-
|
34
|
+
diff-lcs (1.6.2)
|
35
|
+
drb (2.2.3)
|
36
|
+
i18n (1.14.7)
|
22
37
|
concurrent-ruby (~> 1.0)
|
23
|
-
|
24
|
-
|
25
|
-
|
38
|
+
json (2.13.2)
|
39
|
+
language_server-protocol (3.17.0.5)
|
40
|
+
lint_roller (1.1.0)
|
41
|
+
literal (1.8.1)
|
42
|
+
zeitwerk
|
43
|
+
logger (1.7.0)
|
44
|
+
minitest (5.25.5)
|
45
|
+
parallel (1.27.0)
|
46
|
+
parser (3.3.9.0)
|
26
47
|
ast (~> 2.4.1)
|
48
|
+
racc
|
49
|
+
prism (1.4.0)
|
50
|
+
racc (1.8.1)
|
27
51
|
rainbow (3.1.1)
|
28
|
-
rake (13.0
|
29
|
-
regexp_parser (2.
|
30
|
-
|
31
|
-
|
32
|
-
rspec-
|
33
|
-
rspec-
|
34
|
-
|
35
|
-
rspec-collection_matchers (1.2.0)
|
52
|
+
rake (13.3.0)
|
53
|
+
regexp_parser (2.10.0)
|
54
|
+
rspec (3.13.1)
|
55
|
+
rspec-core (~> 3.13.0)
|
56
|
+
rspec-expectations (~> 3.13.0)
|
57
|
+
rspec-mocks (~> 3.13.0)
|
58
|
+
rspec-collection_matchers (1.2.1)
|
36
59
|
rspec-expectations (>= 2.99.0.beta1)
|
37
|
-
rspec-core (3.
|
38
|
-
rspec-support (~> 3.
|
39
|
-
rspec-expectations (3.
|
60
|
+
rspec-core (3.13.5)
|
61
|
+
rspec-support (~> 3.13.0)
|
62
|
+
rspec-expectations (3.13.5)
|
40
63
|
diff-lcs (>= 1.2.0, < 2.0)
|
41
|
-
rspec-support (~> 3.
|
42
|
-
rspec-mocks (3.
|
64
|
+
rspec-support (~> 3.13.0)
|
65
|
+
rspec-mocks (3.13.5)
|
43
66
|
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
-
rspec-support (~> 3.
|
45
|
-
rspec-support (3.
|
46
|
-
rubocop (1.
|
67
|
+
rspec-support (~> 3.13.0)
|
68
|
+
rspec-support (3.13.4)
|
69
|
+
rubocop (1.75.8)
|
70
|
+
json (~> 2.3)
|
71
|
+
language_server-protocol (~> 3.17.0.2)
|
72
|
+
lint_roller (~> 1.1.0)
|
47
73
|
parallel (~> 1.10)
|
48
|
-
parser (>= 3.
|
74
|
+
parser (>= 3.3.0.2)
|
49
75
|
rainbow (>= 2.2.2, < 4.0)
|
50
|
-
regexp_parser (>=
|
51
|
-
|
52
|
-
rubocop-ast (>= 1.17.0, < 2.0)
|
76
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
77
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
53
78
|
ruby-progressbar (~> 1.7)
|
54
|
-
unicode-display_width (>=
|
55
|
-
rubocop-ast (1.
|
56
|
-
parser (>= 3.
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
79
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
80
|
+
rubocop-ast (1.46.0)
|
81
|
+
parser (>= 3.3.7.2)
|
82
|
+
prism (~> 1.4)
|
83
|
+
rubocop-performance (1.25.0)
|
84
|
+
lint_roller (~> 1.1)
|
85
|
+
rubocop (>= 1.75.0, < 2.0)
|
86
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
87
|
+
ruby-progressbar (1.13.0)
|
88
|
+
securerandom (0.4.1)
|
89
|
+
standard (1.50.0)
|
90
|
+
language_server-protocol (~> 3.17.0.2)
|
91
|
+
lint_roller (~> 1.0)
|
92
|
+
rubocop (~> 1.75.5)
|
93
|
+
standard-custom (~> 1.0.0)
|
94
|
+
standard-performance (~> 1.8)
|
95
|
+
standard-custom (1.0.2)
|
96
|
+
lint_roller (~> 1.0)
|
97
|
+
rubocop (~> 1.50)
|
98
|
+
standard-performance (1.8.0)
|
99
|
+
lint_roller (~> 1.1)
|
100
|
+
rubocop-performance (~> 1.25.0)
|
101
|
+
tzinfo (2.0.6)
|
65
102
|
concurrent-ruby (~> 1.0)
|
66
|
-
unicode-display_width (
|
103
|
+
unicode-display_width (3.1.4)
|
104
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
105
|
+
unicode-emoji (4.0.4)
|
106
|
+
uri (1.0.3)
|
107
|
+
zeitwerk (2.7.3)
|
67
108
|
|
68
109
|
PLATFORMS
|
69
110
|
arm64-darwin-21
|
111
|
+
arm64-darwin-24
|
112
|
+
arm64-darwin-25
|
70
113
|
x86_64-darwin-21
|
71
114
|
x86_64-linux
|
72
115
|
|
data/README.md
CHANGED
@@ -19,6 +19,10 @@ Options include
|
|
19
19
|
* The number of items to delete (default: 10)
|
20
20
|
* Whether to limit to autocorrectable cops (default: true)
|
21
21
|
* Whether to automatically run `rubocop -a` after deletion
|
22
|
+
* A configuration file at `.rubomop.yml`
|
23
|
+
* A list of cops to only include for deletion
|
24
|
+
* A list of cops to exempt from deletion
|
25
|
+
* A list of files to exempt from change
|
22
26
|
|
23
27
|
## Installation
|
24
28
|
|
@@ -28,13 +32,6 @@ Add this line to your application's Gemfile:
|
|
28
32
|
gem "rubomop"
|
29
33
|
```
|
30
34
|
|
31
|
-
(Well, until I actually submit it, it's)
|
32
|
-
|
33
|
-
```
|
34
|
-
gem "rubocop", github: "noelrappin/rubomop"
|
35
|
-
```
|
36
|
-
|
37
|
-
|
38
35
|
And then execute:
|
39
36
|
|
40
37
|
$ bundle install
|
@@ -49,15 +46,50 @@ Or install it yourself as:
|
|
49
46
|
$ rubomop --help
|
50
47
|
Usage: rubomop [options]
|
51
48
|
-n, --number NUMBER Number of cleanups to perform (default: 10)
|
52
|
-
-a, --
|
53
|
-
--
|
54
|
-
-r, --
|
55
|
-
-f, --filename
|
56
|
-
--
|
49
|
+
-a, --autocorrect-only Only clean autocorrectable cops (default)
|
50
|
+
--no_autocorrect-only Clean all cops (not default)
|
51
|
+
-r, --run-rubocop Run rubocop -aD after (default)
|
52
|
+
-f, --filename=FILENAME Name of todo file (default: ./.rubocop_todo.yml)
|
53
|
+
--no-run-rubocop Don't run rubocop -aD after (not default)
|
54
|
+
-c, --config=CONFIG_FILE Name of optional config file (default: .rubomop.yml)
|
55
|
+
--only=ONLY String or regex of cops to limit removal do, can have multiple
|
56
|
+
--except=EXCEPT String or regex of cops to limit removal do, can have multiple
|
57
|
+
--block=BLOCK String or regex of files to not touch, can have multiple
|
57
58
|
-h, --help Prints this help
|
59
|
+
|
60
|
+
```
|
61
|
+
|
62
|
+
The `--only` option allows you to limit cops to be selected from to only
|
63
|
+
those listed, the option can be a string and will match on substrings, and you
|
64
|
+
can have more than one.
|
65
|
+
|
66
|
+
The `--except` option allows you to specify a cop that should not be
|
67
|
+
selected, again, the option can be a string and will match on substrings, and you
|
68
|
+
can have more than one. If a cop is in both the `--except` and `--include`
|
69
|
+
lists for some reasone, the except list wins and it's excluded.
|
70
|
+
|
71
|
+
The `--block` option allows you to specify files that should not be selected
|
72
|
+
for any cops. The option can be a string and will match on substrings and you can
|
73
|
+
have more than one. If a cop/file combination is in both the `--include`
|
74
|
+
cops list and the file `--block` list, the block wins and the file is not
|
75
|
+
included.
|
76
|
+
|
77
|
+
You can also put options in a `rubomop.yml` file, or you can put it in a
|
78
|
+
different location with the `-c` option from the command line.
|
79
|
+
|
80
|
+
```yaml
|
81
|
+
number: 10
|
82
|
+
autocorrect-only: true
|
83
|
+
only:
|
84
|
+
- Lint
|
85
|
+
block:
|
86
|
+
- oops
|
58
87
|
```
|
59
88
|
|
60
|
-
|
89
|
+
If an option is set via the config file and the command line, the command
|
90
|
+
line option wins. This is true even for the list options where you can have
|
91
|
+
more than one, the command line completly blocks the config file from being
|
92
|
+
used.
|
61
93
|
|
62
94
|
|
63
95
|
## Contributing
|
data/exe/rubomop
CHANGED
data/lib/rubomop/cop.rb
CHANGED
@@ -1,38 +1,41 @@
|
|
1
1
|
module Rubomop
|
2
|
-
class Cop
|
3
|
-
|
4
|
-
|
2
|
+
class Cop < Literal::Object
|
3
|
+
prop :raw_lines, _Array(String), reader: :public, default: -> { [] }
|
4
|
+
prop :files, _Array(String), reader: :public, writer: :public, default: -> { [] }
|
5
|
+
prop :comments, _Array(String), reader: :public, writer: :public, default: -> { [] }
|
6
|
+
prop :config_params, _Array(String), reader: :public, writer: :public, default: -> { [] }
|
7
|
+
prop :autocorrect, _Nilable(Symbol), reader: :public, writer: :public, default: :none
|
8
|
+
prop :offense_count, Integer, reader: :public, writer: :public, default: 0
|
9
|
+
prop :name, String, reader: :public, writer: :public, default: -> { "" }
|
10
|
+
prop :active, _Boolean, reader: :public, writer: :public, default: true
|
5
11
|
|
6
12
|
def self.create_and_parse(raw_lines)
|
7
|
-
result = new(raw_lines)
|
13
|
+
result = new(raw_lines:)
|
8
14
|
result.parse
|
9
15
|
result
|
10
16
|
end
|
11
17
|
|
12
|
-
def initialize(raw_lines)
|
13
|
-
@raw_lines = raw_lines
|
14
|
-
@files = []
|
15
|
-
@autocorrect = false
|
16
|
-
@comments = []
|
17
|
-
end
|
18
|
-
|
19
18
|
def parse
|
20
19
|
raw_lines.each { parse_one_line(_1) }
|
21
20
|
end
|
22
21
|
|
23
22
|
OFFENSE_COUNT_REGEX = /\A# Offense count: (\d*)/
|
24
|
-
COP_NAME_REGEX = /\A(.*):/
|
23
|
+
COP_NAME_REGEX = /\A(\S.*):/
|
25
24
|
FILE_NAME_REGEX = /- '(.*)'/
|
26
|
-
|
25
|
+
SAFE_AUTOCORRECT_REGEX = /\A# This cop supports safe autocorrection/
|
26
|
+
UNSAFE_AUTOCORRECT_REGEX = /\A# This cop supports unsafe autocorrection/
|
27
27
|
GENERAL_COMMENT_REGEX = /\A#/
|
28
28
|
EXCLUDE_REGEX = /Exclude:/
|
29
|
+
CONFIG_PARAM_REGEX = /\A\s\s(.*)/
|
29
30
|
|
30
31
|
def parse_one_line(line)
|
31
32
|
case line
|
32
33
|
when OFFENSE_COUNT_REGEX
|
33
34
|
self.offense_count = line.match(OFFENSE_COUNT_REGEX)[1].to_i
|
34
|
-
when
|
35
|
-
self.autocorrect =
|
35
|
+
when SAFE_AUTOCORRECT_REGEX
|
36
|
+
self.autocorrect = :safe
|
37
|
+
when UNSAFE_AUTOCORRECT_REGEX
|
38
|
+
self.autocorrect = :unsafe
|
36
39
|
when GENERAL_COMMENT_REGEX
|
37
40
|
comments << line.chomp
|
38
41
|
when EXCLUDE_REGEX
|
@@ -41,6 +44,8 @@ module Rubomop
|
|
41
44
|
self.name = line.match(COP_NAME_REGEX)[1]
|
42
45
|
when FILE_NAME_REGEX
|
43
46
|
files << line.match(FILE_NAME_REGEX)[1]
|
47
|
+
when CONFIG_PARAM_REGEX
|
48
|
+
config_params << line.match(CONFIG_PARAM_REGEX)[1]
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
@@ -50,20 +55,62 @@ module Rubomop
|
|
50
55
|
|
51
56
|
def output_lines
|
52
57
|
result = ["# Offense count: #{offense_count}"]
|
53
|
-
result << "#
|
58
|
+
result << "# This cop supports safe autocorrection (--autocorrect)." if autocorrect == :safe
|
59
|
+
result << "# This cop supports unsafe autocorrection (--autocorrect-all)." if autocorrect == :unsafe
|
54
60
|
result += comments
|
55
61
|
result << "#{name}:"
|
56
|
-
result
|
57
|
-
|
62
|
+
result += config_params.map { " #{_1}" }
|
63
|
+
unless files.empty?
|
64
|
+
result << " Exclude:"
|
65
|
+
result += files.map { " - '#{_1}'" }
|
66
|
+
end
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
def any_autocorrect?
|
71
|
+
autocorrect != :none
|
72
|
+
end
|
73
|
+
|
74
|
+
def autocorrect_inquiry
|
75
|
+
autocorrect.to_s.inquiry
|
76
|
+
end
|
77
|
+
|
78
|
+
def autocorrect_verbiage
|
79
|
+
case autocorrect
|
80
|
+
when :safe then "safe autocorrect"
|
81
|
+
when :unsafe then "unsafe autocorrect"
|
82
|
+
else
|
83
|
+
"no autocorrect"
|
84
|
+
end
|
58
85
|
end
|
59
86
|
|
60
|
-
def
|
61
|
-
|
87
|
+
def autocorrect_option
|
88
|
+
case autocorrect
|
89
|
+
when :safe then "a"
|
90
|
+
when :unsafe then "A"
|
91
|
+
else
|
92
|
+
""
|
93
|
+
end
|
62
94
|
end
|
63
95
|
|
64
96
|
def delete!(filename)
|
65
97
|
files.delete(filename)
|
66
|
-
|
98
|
+
end
|
99
|
+
|
100
|
+
def subtract!(offense_count)
|
101
|
+
self.offense_count -= offense_count
|
102
|
+
end
|
103
|
+
|
104
|
+
def activate
|
105
|
+
self.active = true
|
106
|
+
end
|
107
|
+
|
108
|
+
def deactivate
|
109
|
+
self.active = false
|
110
|
+
end
|
111
|
+
|
112
|
+
def active?
|
113
|
+
active
|
67
114
|
end
|
68
115
|
end
|
69
116
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Rubomop
|
2
|
+
class NamedMop < Literal::Object
|
3
|
+
prop :todo_file, TodoFile, reader: :public, writer: :public
|
4
|
+
prop :name, String, reader: :public, writer: :public
|
5
|
+
prop :verbose, _Boolean, reader: :public, writer: :public
|
6
|
+
prop :run_rubocop, _Boolean, reader: :public, writer: :public
|
7
|
+
|
8
|
+
def mop!
|
9
|
+
todo_file.cop_for(name).deactivate
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Rubomop
|
2
|
+
class RandomMop < Literal::Object
|
3
|
+
prop :todo_file, TodoFile, reader: :public, writer: :public
|
4
|
+
prop :number, Integer, reader: :public, writer: :public
|
5
|
+
prop :autocorrect_only, _Boolean, reader: :public, writer: :public
|
6
|
+
prop :verbose, _Boolean, reader: :public, writer: :public
|
7
|
+
prop :run_rubocop, _Boolean, reader: :public, writer: :public
|
8
|
+
prop :only, _Array(String), reader: :public, writer: :public
|
9
|
+
prop :except, _Array(String), reader: :public, writer: :public
|
10
|
+
prop :blocklist, _Array(String), reader: :public, writer: :public
|
11
|
+
|
12
|
+
def cops
|
13
|
+
todo_file.cops
|
14
|
+
end
|
15
|
+
|
16
|
+
def accept?(delete_option)
|
17
|
+
return false if autocorrect_only && !delete_option.cop.any_autocorrect?
|
18
|
+
unless except.empty?
|
19
|
+
return except.none? { delete_option.cop.name.include?(_1) }
|
20
|
+
end
|
21
|
+
unless blocklist.empty?
|
22
|
+
return blocklist.none? { delete_option.file.include?(_1) }
|
23
|
+
end
|
24
|
+
unless only.empty?
|
25
|
+
return only.any? { delete_option.cop.name.include?(_1) }
|
26
|
+
end
|
27
|
+
true
|
28
|
+
# return true unless autocorrect_only
|
29
|
+
# cop.autocorrect
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete_options
|
33
|
+
cops.flat_map { delete_options_for(_1) }
|
34
|
+
.select { accept?(_1) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_options_for(cop)
|
38
|
+
cop.files.map { DeleteOption.new(cop, _1, verbose, run_rubocop) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def log(message)
|
42
|
+
return unless verbose
|
43
|
+
print message
|
44
|
+
end
|
45
|
+
|
46
|
+
def mop!
|
47
|
+
number.times do |i|
|
48
|
+
options = delete_options
|
49
|
+
next if options.empty?
|
50
|
+
log("#{i + 1}:")
|
51
|
+
mop_once!(options.sample)
|
52
|
+
log("\n")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def mop_once!(delete_option)
|
57
|
+
delete_option.print_message if verbose
|
58
|
+
delete_option.delete!
|
59
|
+
return unless run_rubocop
|
60
|
+
todo_file.save!
|
61
|
+
offense_count = delete_option.rubocop_runner || 0
|
62
|
+
delete_option.subtract!(offense_count)
|
63
|
+
end
|
64
|
+
|
65
|
+
DeleteOption = Struct.new(:cop, :file, :verbose, :run_rubocop) do
|
66
|
+
def print_message
|
67
|
+
return unless verbose
|
68
|
+
print "Deleting #{file} from #{cop.name}" if verbose
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete!
|
72
|
+
cop.delete!(file)
|
73
|
+
end
|
74
|
+
|
75
|
+
def subtract!(offense_count)
|
76
|
+
cop.subtract!(offense_count)
|
77
|
+
end
|
78
|
+
|
79
|
+
def rubocop_runner
|
80
|
+
return unless run_rubocop
|
81
|
+
print "\nbundle exec rubocop #{file} -aD\n"
|
82
|
+
IO.popen("bundle exec rubocop #{file} -aD") do |io|
|
83
|
+
result_string = io.read
|
84
|
+
puts result_string.split("\n").last
|
85
|
+
puts "\n"
|
86
|
+
parse_io(result_string)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def parse_io(string)
|
91
|
+
match_data = string.match(/(\d*) offense(s?) corrected/)
|
92
|
+
return 0 if match_data.nil?
|
93
|
+
match_data[1].to_i
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/rubomop/runner.rb
CHANGED
@@ -1,46 +1,113 @@
|
|
1
1
|
module Rubomop
|
2
2
|
class Runner
|
3
|
-
attr_accessor :number, :autocorrect_only, :run_rubocop, :filename, :
|
3
|
+
attr_accessor :number, :autocorrect_only, :run_rubocop, :filename, :todo_file, :verbose, :config,
|
4
|
+
:options_from_command_line, :only, :except, :blocklist, :name, :directory
|
5
|
+
|
4
6
|
NUM_STRING = "Number of cleanups to perform (default: 10)"
|
5
|
-
|
7
|
+
NAME_STRING = "Name of cop to clean up. Choosing a name overrides choosing a number"
|
8
|
+
AUTOCORRECT_STRING = "Only clean auto-correctable cops (default)"
|
6
9
|
NO_AUTOCORRECT_STRING = "Clean all cops (not default)"
|
7
10
|
RUBOCOP_STRING = "Run rubocop -aD after (default)"
|
8
11
|
NO_RUBOCOP_STRING = "Don't run rubocop -aD after (not default)"
|
9
12
|
FILENAME_STRING = "Name of todo file (default: ./.rubocop_todo.yml)"
|
13
|
+
CONFIG_STRING = "Name of optional config file (default: .rubomop.yml)"
|
14
|
+
ONLY_STRING = "String or regex of cops to limit removal do, can have multiple"
|
15
|
+
EXCEPT_STRING = "String or regex of cops to not remove from, can have multiple"
|
16
|
+
BLOCK_STRING = "String or regex of files to not touch, can have multiple"
|
17
|
+
DIRECTORY_STRING = "Directory to work in (default: current directory)"
|
10
18
|
|
11
19
|
def initialize
|
12
20
|
@number = 10
|
13
21
|
@autocorrect_only = true
|
14
22
|
@run_rubocop = true
|
15
23
|
@filename = ".rubocop_todo.yml"
|
16
|
-
@
|
24
|
+
@config = ".rubomop.yml"
|
25
|
+
@directory = "."
|
26
|
+
@todo_file = TodoFile.new(filename: full_path(@filename))
|
27
|
+
@verbose = true
|
28
|
+
@options_from_command_line = []
|
29
|
+
@only = []
|
30
|
+
@except = []
|
31
|
+
@blocklist = []
|
32
|
+
@name = nil
|
17
33
|
end
|
18
34
|
|
19
35
|
def execute(args)
|
20
|
-
|
36
|
+
load_options(args)
|
21
37
|
run
|
22
38
|
end
|
23
39
|
|
40
|
+
def load_options(args)
|
41
|
+
parse(args)
|
42
|
+
load_from_file
|
43
|
+
# Recreate todo_file with the correct directory after options are loaded
|
44
|
+
@todo_file = TodoFile.new(filename: full_path(@filename))
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_from_file
|
48
|
+
config_path = full_path(config)
|
49
|
+
return unless File.exist?(config_path)
|
50
|
+
|
51
|
+
file_options = YAML.safe_load_file(config_path)
|
52
|
+
file_options.each do |key, value|
|
53
|
+
next if options_from_command_line.include?(key)
|
54
|
+
|
55
|
+
send("#{key.underscore}=", value) if respond_to?("#{key.underscore}=")
|
56
|
+
end
|
57
|
+
rescue Psych::Exception
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
24
61
|
def parse(args)
|
25
62
|
option_parser = OptionParser.new do |opts|
|
26
63
|
opts.banner = "Usage: rubomop [options]"
|
27
64
|
opts.on("-nNUMBER", "--number NUMBER", Integer, NUM_STRING) do |value|
|
28
65
|
self.number = value
|
66
|
+
@options_from_command_line << "number"
|
29
67
|
end
|
30
68
|
opts.on("-a", "--autocorrect-only", AUTOCORRECT_STRING) do
|
31
69
|
self.autocorrect_only = true
|
70
|
+
@options_from_command_line << "autocorrect-only"
|
32
71
|
end
|
33
72
|
opts.on("--no_autocorrect-only", NO_AUTOCORRECT_STRING) do
|
34
73
|
self.autocorrect_only = false
|
74
|
+
@options_from_command_line << "autocorrect-only"
|
35
75
|
end
|
36
76
|
opts.on("-r", "--run-rubocop", RUBOCOP_STRING) do
|
37
77
|
self.run_rubocop = true
|
78
|
+
@options_from_command_line << "run-rubocop"
|
38
79
|
end
|
39
|
-
opts.on("-fFILENAME", "--filename
|
80
|
+
opts.on("-fFILENAME", "--filename=FILENAME", FILENAME_STRING) do |value|
|
40
81
|
self.filename = value
|
82
|
+
@options_from_command_line << "filename"
|
41
83
|
end
|
42
84
|
opts.on("--no-run-rubocop", NO_RUBOCOP_STRING) do
|
43
85
|
self.run_rubocop = false
|
86
|
+
@options_from_command_line << "run-rubocop"
|
87
|
+
end
|
88
|
+
opts.on("-cCONFIG_FILE", "--config=CONFIG_FILE", CONFIG_STRING) do |value|
|
89
|
+
self.config = value
|
90
|
+
@options_from_command_line << "config"
|
91
|
+
end
|
92
|
+
opts.on("-dDIRECTORY", "--directory=DIRECTORY", "--dir=DIRECTORY", DIRECTORY_STRING) do |value|
|
93
|
+
self.directory = value
|
94
|
+
@options_from_command_line << "directory"
|
95
|
+
end
|
96
|
+
opts.on("--only=ONLY", ONLY_STRING) do |value|
|
97
|
+
only << value
|
98
|
+
@options_from_command_line << "only"
|
99
|
+
end
|
100
|
+
opts.on("--except=EXCEPT", ONLY_STRING) do |value|
|
101
|
+
except << value
|
102
|
+
@options_from_command_line << "except"
|
103
|
+
end
|
104
|
+
opts.on("--block=BLOCK", BLOCK_STRING) do |value|
|
105
|
+
blocklist << value
|
106
|
+
@options_from_command_line << "block"
|
107
|
+
end
|
108
|
+
opts.on("--name=NAME", NAME_STRING) do |value|
|
109
|
+
self.name = value
|
110
|
+
@options_from_command_line << "name"
|
44
111
|
end
|
45
112
|
opts.on("-h", "--help", "Prints this help") do
|
46
113
|
puts opts
|
@@ -50,34 +117,48 @@ module Rubomop
|
|
50
117
|
option_parser.parse(args)
|
51
118
|
end
|
52
119
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
120
|
+
def mop
|
121
|
+
if name
|
122
|
+
NamedMop.new(
|
123
|
+
todo_file:,
|
124
|
+
name:,
|
125
|
+
verbose:,
|
126
|
+
run_rubocop:
|
127
|
+
)
|
128
|
+
else
|
129
|
+
RandomMop.new(
|
130
|
+
todo_file:,
|
131
|
+
number:,
|
132
|
+
autocorrect_only:,
|
133
|
+
verbose:,
|
134
|
+
run_rubocop:,
|
135
|
+
only:,
|
136
|
+
except:,
|
137
|
+
blocklist:
|
138
|
+
)
|
62
139
|
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def run
|
143
|
+
self.todo_file = TodoFile.new(filename: full_path(filename))&.parse
|
144
|
+
return if todo_file.nil?
|
145
|
+
|
63
146
|
backup_existing_file
|
64
|
-
|
65
|
-
|
147
|
+
mop.mop!
|
148
|
+
todo_file&.save!
|
66
149
|
end
|
67
150
|
|
68
151
|
def backup_existing_file
|
69
|
-
|
70
|
-
|
152
|
+
filename_path = full_path(filename)
|
153
|
+
backup_path = "#{filename_path}.bak"
|
154
|
+
FileUtils.rm(backup_path) if File.exist?(backup_path)
|
155
|
+
FileUtils.mv(filename_path, backup_path)
|
71
156
|
end
|
72
157
|
|
73
|
-
|
74
|
-
File.write(filename, todo&.output || "")
|
75
|
-
end
|
158
|
+
private
|
76
159
|
|
77
|
-
def
|
78
|
-
|
79
|
-
print "Running bundle exec rubocop -aD"
|
80
|
-
system("bundle exec rubocop -aD")
|
160
|
+
def full_path(file_path)
|
161
|
+
File.join(directory, file_path)
|
81
162
|
end
|
82
163
|
end
|
83
164
|
end
|
data/lib/rubomop/todo_file.rb
CHANGED
@@ -14,10 +14,18 @@ module Rubomop
|
|
14
14
|
self
|
15
15
|
end
|
16
16
|
|
17
|
+
def cop_for(name)
|
18
|
+
cops.select { _1.name == name }.first
|
19
|
+
end
|
20
|
+
|
21
|
+
def active_cops
|
22
|
+
cops.select { _1.active? }
|
23
|
+
end
|
24
|
+
|
17
25
|
def output_lines
|
18
26
|
result = header.map(&:chomp)
|
19
27
|
result << ""
|
20
|
-
|
28
|
+
active_cops.each do |cop|
|
21
29
|
result += cop.output_lines
|
22
30
|
result << ""
|
23
31
|
end
|
@@ -28,14 +36,9 @@ module Rubomop
|
|
28
36
|
output_lines.join("\n") + "\n"
|
29
37
|
end
|
30
38
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
result
|
35
|
-
end
|
36
|
-
|
37
|
-
def delete!(delete_option)
|
38
|
-
delete_option[:cop].delete!(delete_option[:file])
|
39
|
+
def save!
|
40
|
+
FileUtils.rm_f(filename)
|
41
|
+
File.write(filename, output || "")
|
39
42
|
end
|
40
43
|
end
|
41
44
|
end
|
data/lib/rubomop/version.rb
CHANGED
data/lib/rubomop.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/array"
|
4
|
+
require "active_support/core_ext/string/inflections"
|
5
|
+
require "active_support/core_ext/string/inquiry"
|
6
|
+
require "awesome_print"
|
3
7
|
require "fileutils"
|
8
|
+
require "literal"
|
4
9
|
require "optparse"
|
5
|
-
require "
|
6
|
-
require "
|
7
|
-
|
8
|
-
|
9
|
-
require_relative "rubomop/todo_file"
|
10
|
-
require_relative "rubomop/version"
|
10
|
+
require "yaml"
|
11
|
+
require "zeitwerk"
|
12
|
+
loader = Zeitwerk::Loader.for_gem
|
13
|
+
loader.setup
|
11
14
|
|
12
15
|
module Rubomop
|
13
16
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,43 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubomop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noel Rappin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '7.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '7.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: date_by_example
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- - "
|
31
|
+
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '0.1'
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- - "
|
38
|
+
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
42
|
+
name: literal
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: zeitwerk
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- - "
|
59
|
+
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
61
|
+
version: 2.7.0
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- - "
|
66
|
+
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
68
|
+
version: 2.7.0
|
41
69
|
description: Rubomop cleans up after your Rubocop
|
42
70
|
email:
|
43
71
|
- noel.rappin@chime.com
|
@@ -59,6 +87,8 @@ files:
|
|
59
87
|
- exe/rubomop
|
60
88
|
- lib/rubomop.rb
|
61
89
|
- lib/rubomop/cop.rb
|
90
|
+
- lib/rubomop/named_mop.rb
|
91
|
+
- lib/rubomop/random_mop.rb
|
62
92
|
- lib/rubomop/runner.rb
|
63
93
|
- lib/rubomop/todo_file.rb
|
64
94
|
- lib/rubomop/version.rb
|
@@ -79,14 +109,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
109
|
requirements:
|
80
110
|
- - ">="
|
81
111
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.
|
112
|
+
version: 3.2.0
|
83
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
114
|
requirements:
|
85
115
|
- - ">="
|
86
116
|
- !ruby/object:Gem::Version
|
87
117
|
version: '0'
|
88
118
|
requirements: []
|
89
|
-
rubygems_version: 3.
|
119
|
+
rubygems_version: 3.4.19
|
90
120
|
signing_key:
|
91
121
|
specification_version: 4
|
92
122
|
summary: Rubomop cleans up after your Rubocop
|