rubomop 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e23279657fd3a3f2172cbbcdd14d3f7c6067c8721a1e18b50eaf45ed7602149
4
- data.tar.gz: 85f85b5809d827705ee7c0e77978c6efb24be669f3d50c013394373b82f7fe45
3
+ metadata.gz: 35a52f9290f40da21229725a1eff7e999552f468f5018dc8789ba335de86eace
4
+ data.tar.gz: 38d3d0e3b4c7f0dbf5fa12a6815cd4a03e1740436262bc6d86e95a1cefc98491
5
5
  SHA512:
6
- metadata.gz: 64d68023ebb7185bd24096b7377ec04f2968047c2dcee244873f56bcaa3cd569c917979d32db8a4cd95ce32ca342652f2569a9feac2f10b1dde2f1617f75b5f4
7
- data.tar.gz: 5c1c1bb6adfe50f915dc1d2607ea2039bf0b6f8070ce89885dcdba72900f723b78b869c5b9221638ccc5b8c53e937c67c9ed0b84736fee9f14def7ae964780ed
6
+ metadata.gz: 1db04192c3ee364bc31da684196e825ca1a0468ea39fe78e30cdeae95ff032561911c1ae913e0067147d116d8e2acc303b6c49b2f6e2a09ed1ba32d0597f3d4b
7
+ data.tar.gz: 1e9e4c3b1306d8b90cdeaaaaa0ea1ed0c7ef9d747a8e296489acd5d7a4f20b4dc8a2ed0fc01bb0276fee36d455f798bebe0730bbd2a3e222cb3f24fcbaff4960
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2022-07-19
3
+ ## [0.2.0] - 2022-07-22
4
+
5
+ - Adds for a .rubomop.yml file with configuration options
6
+ - Command line switch to override config file name
7
+ - Allows for only/except for specific cops by name or pattern
8
+ - Allows for excluding specific file patterns from being changed
9
+ - Only runs rubocop on selected files, not on the whole repo
10
+
11
+ ## [0.1.0] - 2022-07-20
4
12
 
5
13
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubomop (0.1.0)
4
+ rubomop (0.2.0)
5
5
  activesupport (> 5.0)
6
- date_by_example (> 0.1)
6
+ date_by_example (~> 0.1)
7
+ zeitwerk (~> 2.6.0)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -64,6 +65,7 @@ GEM
64
65
  tzinfo (2.0.4)
65
66
  concurrent-ruby (~> 1.0)
66
67
  unicode-display_width (2.2.0)
68
+ zeitwerk (2.6.0)
67
69
 
68
70
  PLATFORMS
69
71
  arm64-darwin-21
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, --autocorrect_only Only clean autocorrectable cops (default)
53
- --no_autocorrect_only Clean all cops (not default)
54
- -r, --run_rubocop Run rubocop -aD after (default)
55
- -f, --filename FILENAME Name of todo file (default: ./.rubocop_todo.yml)
56
- --no_run_rubocop Don't run rubocop -aD after (not default)
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
- ## Development
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
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "rubomop"
4
+ # require_relative "../lib/rubomop" # when running locally
4
5
 
5
6
  Rubomop::Runner.new.execute(ARGV)
data/lib/rubomop/cop.rb CHANGED
@@ -57,10 +57,6 @@ module Rubomop
57
57
  result + files.map { " - '#{_1}'"}
58
58
  end
59
59
 
60
- def delete_options
61
- files.map { {cop: self, file: _1} }
62
- end
63
-
64
60
  def delete!(filename)
65
61
  files.delete(filename)
66
62
  self.offense_count -= 1
@@ -0,0 +1,86 @@
1
+ module Rubomop
2
+ class Mop
3
+ attr_accessor :todo_file, :number, :autocorrect_only, :run_rubocop
4
+ attr_accessor :verbose, :only, :except, :block
5
+
6
+ def initialize(todo_file, number, autocorrect_only, verbose, run_rubocop, only, except, blocklist)
7
+ @todo_file = todo_file
8
+ @number = number
9
+ @autocorrect_only = autocorrect_only
10
+ @verbose = verbose
11
+ @run_rubocop = run_rubocop
12
+ @only = only
13
+ @except = except
14
+ @block = blocklist
15
+ end
16
+
17
+ def cops
18
+ todo_file.cops
19
+ end
20
+
21
+ def accept?(delete_option)
22
+ return false if autocorrect_only && !delete_option.cop.autocorrect
23
+ unless except.empty?
24
+ return except.none? { delete_option.cop.name.include?(_1) }
25
+ end
26
+ unless block.empty?
27
+ return block.none? { delete_option.file.include?(_1) }
28
+ end
29
+ unless only.empty?
30
+ return only.any? { delete_option.cop.name.include?(_1) }
31
+ end
32
+ true
33
+ # return true unless autocorrect_only
34
+ # cop.autocorrect
35
+ end
36
+
37
+ def delete_options
38
+ cops.flat_map { delete_options_for(_1) }
39
+ .select { accept?(_1) }
40
+ end
41
+
42
+ def delete_options_for(cop)
43
+ cop.files.map { DeleteOption.new(cop, _1, verbose, run_rubocop) }
44
+ end
45
+
46
+ def log(message)
47
+ return unless verbose
48
+ print message
49
+ end
50
+
51
+ def mop!
52
+ number.times do |i|
53
+ options = delete_options
54
+ next if options.empty?
55
+ log("#{i + 1}:")
56
+ mop_once!(options.sample)
57
+ log("\n")
58
+ end
59
+ end
60
+
61
+ def mop_once!(delete_option)
62
+ delete_option.print_message if verbose
63
+ delete_option.delete!
64
+ return unless run_rubocop
65
+ todo_file.save!
66
+ delete_option.rubocop_runner
67
+ end
68
+
69
+ DeleteOption = Struct.new(:cop, :file, :verbose, :run_rubocop) do
70
+ def print_message
71
+ return unless verbose
72
+ print "Deleting #{file} from #{cop.name}" if verbose
73
+ end
74
+
75
+ def delete!
76
+ cop.delete!(file)
77
+ end
78
+
79
+ def rubocop_runner
80
+ return unless run_rubocop
81
+ print "\nbundle exec rubocop #{file} -aD\n"
82
+ system("bundle exec rubocop #{file} -aD")
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,46 +1,97 @@
1
1
  module Rubomop
2
2
  class Runner
3
- attr_accessor :number, :autocorrect_only, :run_rubocop, :filename, :todo
3
+ attr_accessor :number, :autocorrect_only, :run_rubocop
4
+ attr_accessor :filename, :todo, :verbose, :config, :options_from_command_line
5
+ attr_accessor :only, :except, :block
6
+
4
7
  NUM_STRING = "Number of cleanups to perform (default: 10)"
5
8
  AUTOCORRECT_STRING = "Only clean autocorrectable 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"
10
17
 
11
18
  def initialize
12
19
  @number = 10
13
20
  @autocorrect_only = true
14
21
  @run_rubocop = true
15
22
  @filename = ".rubocop_todo.yml"
23
+ @config = ".rubomop.yml"
16
24
  @todo = nil
25
+ @verbose = true
26
+ @options_from_command_line = []
27
+ @only = []
28
+ @except = []
29
+ @block = []
17
30
  end
18
31
 
19
32
  def execute(args)
20
- parse(args)
33
+ load_options(args)
21
34
  run
22
35
  end
23
36
 
37
+ def load_options(args)
38
+ parse(args)
39
+ load_from_file
40
+ end
41
+
42
+ def load_from_file
43
+ return unless File.exist?(config)
44
+ file_options = YAML.safe_load(File.read(config))
45
+ file_options.each do |key, value|
46
+ next if options_from_command_line.include?(key)
47
+ send("#{key.underscore}=", value) if respond_to?("#{key.underscore}=")
48
+ end
49
+ rescue Psych::Exception
50
+ nil
51
+ end
52
+
24
53
  def parse(args)
25
54
  option_parser = OptionParser.new do |opts|
26
55
  opts.banner = "Usage: rubomop [options]"
27
56
  opts.on("-nNUMBER", "--number NUMBER", Integer, NUM_STRING) do |value|
28
57
  self.number = value
58
+ @options_from_command_line << "number"
29
59
  end
30
60
  opts.on("-a", "--autocorrect-only", AUTOCORRECT_STRING) do
31
61
  self.autocorrect_only = true
62
+ @options_from_command_line << "autocorrect-only"
32
63
  end
33
64
  opts.on("--no_autocorrect-only", NO_AUTOCORRECT_STRING) do
34
65
  self.autocorrect_only = false
66
+ @options_from_command_line << "autocorrect-only"
35
67
  end
36
68
  opts.on("-r", "--run-rubocop", RUBOCOP_STRING) do
37
69
  self.run_rubocop = true
70
+ @options_from_command_line << "run-rubocop"
38
71
  end
39
- opts.on("-fFILENAME", "--filename FILENAME", FILENAME_STRING) do |value|
72
+ opts.on("-fFILENAME", "--filename=FILENAME", FILENAME_STRING) do |value|
40
73
  self.filename = value
74
+ @options_from_command_line << "filename"
41
75
  end
42
76
  opts.on("--no-run-rubocop", NO_RUBOCOP_STRING) do
43
77
  self.run_rubocop = false
78
+ @options_from_command_line << "run-rubocop"
79
+ end
80
+ opts.on("-cCONFIG_FILE", "--config=CONFIG_FILE", CONFIG_STRING) do |value|
81
+ self.config = value
82
+ @options_from_command_line << "config"
83
+ end
84
+ opts.on("--only=ONLY", ONLY_STRING) do |value|
85
+ only << value
86
+ @options_from_command_line << "only"
87
+ end
88
+ opts.on("--except=EXCEPT", ONLY_STRING) do |value|
89
+ except << value
90
+ @options_from_command_line << "except"
91
+ end
92
+ opts.on("--block=BLOCK", BLOCK_STRING) do |value|
93
+ block << value
94
+ @options_from_command_line << "block"
44
95
  end
45
96
  opts.on("-h", "--help", "Prints this help") do
46
97
  puts opts
@@ -50,34 +101,21 @@ module Rubomop
50
101
  option_parser.parse(args)
51
102
  end
52
103
 
104
+ def mop
105
+ Mop.new(todo, number, autocorrect_only, verbose, run_rubocop, only, except, block)
106
+ end
107
+
53
108
  def run
54
109
  self.todo = TodoFile.new(filename: filename)&.parse
55
110
  return if todo.nil?
56
- number.times do |i|
57
- delete_options = todo&.delete_options(autocorrect_only: autocorrect_only)
58
- next if delete_options.empty?
59
- object_to_delete = delete_options.sample
60
- print "#{i + 1}: Deleting #{object_to_delete[:file]} from #{object_to_delete[:cop].name}\n"
61
- todo&.delete!(object_to_delete)
62
- end
63
111
  backup_existing_file
64
- save_new_file
65
- rubocop_runner
112
+ mop.mop!
113
+ todo&.save!
66
114
  end
67
115
 
68
116
  def backup_existing_file
69
117
  FileUtils.rm("#{filename}.bak") if File.exist?("#{filename}.bak")
70
118
  FileUtils.mv(filename, "#{filename}.bak")
71
119
  end
72
-
73
- def save_new_file
74
- File.write(filename, todo&.output || "")
75
- end
76
-
77
- def rubocop_runner
78
- return unless run_rubocop
79
- print "Running bundle exec rubocop -aD"
80
- system("bundle exec rubocop -aD")
81
- end
82
120
  end
83
121
  end
@@ -28,14 +28,9 @@ module Rubomop
28
28
  output_lines.join("\n") + "\n"
29
29
  end
30
30
 
31
- def delete_options(autocorrect_only: true)
32
- result = cops.flat_map(&:delete_options)
33
- result = result.select { _1[:cop].autocorrect } if autocorrect_only
34
- result
35
- end
36
-
37
- def delete!(delete_option)
38
- delete_option[:cop].delete!(delete_option[:file])
31
+ def save!
32
+ FileUtils.rm_f(filename)
33
+ File.write(filename, output || "")
39
34
  end
40
35
  end
41
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubomop
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/rubomop.rb CHANGED
@@ -1,13 +1,14 @@
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 "awesome_print"
3
6
  require "fileutils"
4
7
  require "optparse"
5
- require "awesome_print"
6
- require "active_support/core_ext/array"
7
- require_relative "rubomop/cop"
8
- require_relative "rubomop/runner"
9
- require_relative "rubomop/todo_file"
10
- require_relative "rubomop/version"
8
+ require "yaml"
9
+ require "zeitwerk"
10
+ loader = Zeitwerk::Loader.for_gem
11
+ loader.setup
11
12
 
12
13
  module Rubomop
13
14
  class Error < StandardError; end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubomop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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: 2022-07-21 00:00:00.000000000 Z
11
+ date: 2022-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: date_by_example
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">"
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">"
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.1'
27
27
  - !ruby/object:Gem::Dependency
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: zeitwerk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.6.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.6.0
41
55
  description: Rubomop cleans up after your Rubocop
42
56
  email:
43
57
  - noel.rappin@chime.com
@@ -59,6 +73,7 @@ files:
59
73
  - exe/rubomop
60
74
  - lib/rubomop.rb
61
75
  - lib/rubomop/cop.rb
76
+ - lib/rubomop/mop.rb
62
77
  - lib/rubomop/runner.rb
63
78
  - lib/rubomop/todo_file.rb
64
79
  - lib/rubomop/version.rb