rubocop-gradual 0.1.1 → 0.3.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/CHANGELOG.md +58 -1
- data/README.md +100 -10
- data/exe/rubocop-gradual +1 -1
- data/lib/rubocop/gradual/cli.rb +9 -18
- data/lib/rubocop/gradual/commands/autocorrect.rb +47 -0
- data/lib/rubocop/gradual/commands/base.rb +56 -0
- data/lib/rubocop/gradual/configuration.rb +60 -0
- data/lib/rubocop/gradual/formatters/autocorrect.rb +35 -0
- data/lib/rubocop/gradual/formatters/base.rb +36 -0
- data/lib/rubocop/gradual/git.rb +34 -0
- data/lib/rubocop/gradual/options.rb +73 -39
- data/lib/rubocop/gradual/patch.rb +32 -0
- data/lib/rubocop/gradual/process/calculate_diff.rb +2 -15
- data/lib/rubocop/gradual/process/diff.rb +3 -10
- data/lib/rubocop/gradual/process/printer.rb +5 -5
- data/lib/rubocop/gradual/process.rb +22 -16
- data/lib/rubocop/gradual/rake_task.rb +72 -0
- data/lib/rubocop/gradual/results/issue.rb +1 -1
- data/lib/rubocop/gradual/version.rb +1 -1
- data/lib/rubocop/gradual.rb +5 -13
- metadata +11 -4
- data/lib/rubocop/gradual/formatter.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8d8cb41d6a825538a0b0411867bcef6864d16ec393f24c7d9f84e05f886caa8
|
4
|
+
data.tar.gz: e7230b837f6f39967e4c472a2a8f466d061da24af7ea9efee060175f0617bb17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 223e2e205074038f7af48b2be3d06d98136ef7d9d65b8bcf3c153d8eee937d4f6f45bada38eaf6a5f8f257e4a95230c8e9a7b19b3158abe9e599bf3ce5e53d45
|
7
|
+
data.tar.gz: 57824cdfee2b8423e88c30f50c95b8f8bba78edfcfd36fe94c73e88e4798eba62c899fb1cefc4719baf08b48422e545e59f86c78affe3a835c3aaa68f9a05c25
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,61 @@ and this project adheres to [Semantic Versioning].
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.3.0] - 2022-10-26
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Partial linting (experimental). ([@skryukov])
|
15
|
+
|
16
|
+
Partial linting is useful when you want to run RuboCop Gradual on a subset of files, for example, on changed files in a pull request:
|
17
|
+
|
18
|
+
```shell
|
19
|
+
rubocop-gradual path/to/file # run `rubocop-gradual` on a subset of files
|
20
|
+
rubocop-gradual --staged # run `rubocop-gradual` on staged files
|
21
|
+
rubocop-gradual --unstaged # run `rubocop-gradual` on unstaged files
|
22
|
+
rubocop-gradual --commit origin/main # run `rubocop-gradual` on changed files since the commit
|
23
|
+
|
24
|
+
# it's possible to combine options with autocorrect:
|
25
|
+
rubocop-gradual --staged --autocorrect # run `rubocop-gradual` with autocorrect on staged files
|
26
|
+
```
|
27
|
+
|
28
|
+
- Require mode (experimental). ([@skryukov])
|
29
|
+
|
30
|
+
RuboCop Gradual can be used in "Require mode", which is a way to replace `rubocop` with `rubocop-gradual`:
|
31
|
+
|
32
|
+
```yaml
|
33
|
+
# .rubocop.yml
|
34
|
+
|
35
|
+
require:
|
36
|
+
- rubocop-gradual
|
37
|
+
```
|
38
|
+
|
39
|
+
- Built-in Rake tasks. ([@skryukov])
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# Rakefile
|
43
|
+
require "rubocop/gradual/rake_task"
|
44
|
+
|
45
|
+
RuboCop::Gradual::RakeTask.new
|
46
|
+
```
|
47
|
+
|
48
|
+
### Fixed
|
49
|
+
|
50
|
+
- Issues with the same location ordered by the message. ([@skryukov])
|
51
|
+
|
52
|
+
## [0.2.0] - 2022-07-26
|
53
|
+
|
54
|
+
### Added
|
55
|
+
|
56
|
+
- Autocorrection options. ([@skryukov])
|
57
|
+
Run `rubocop-gradual -a` and `rubocop-gradual -A` to autocorrect new and changed files and then update the lock file.
|
58
|
+
|
59
|
+
### Changed
|
60
|
+
|
61
|
+
- Rename `--ci` to `--check` option. ([@skryukov])
|
62
|
+
|
63
|
+
- Rename `-u, --update` to `-U, --force-update` option. ([@skryukov])
|
64
|
+
|
10
65
|
## [0.1.1] - 2022-07-05
|
11
66
|
|
12
67
|
### Changed
|
@@ -25,7 +80,9 @@ and this project adheres to [Semantic Versioning].
|
|
25
80
|
|
26
81
|
[@skryukov]: https://github.com/skryukov
|
27
82
|
|
28
|
-
[Unreleased]: https://github.com/skryukov/rubocop-gradual/compare/v0.
|
83
|
+
[Unreleased]: https://github.com/skryukov/rubocop-gradual/compare/v0.3.0...HEAD
|
84
|
+
[0.3.0]: https://github.com/skryukov/rubocop-gradual/compare/v0.2.0...v0.3.0
|
85
|
+
[0.2.0]: https://github.com/skryukov/rubocop-gradual/compare/v0.1.1...v0.2.0
|
29
86
|
[0.1.1]: https://github.com/skryukov/rubocop-gradual/compare/v0.1.0...v0.1.1
|
30
87
|
[0.1.0]: https://github.com/skryukov/rubocop-gradual/commits/v0.1.0
|
31
88
|
|
data/README.md
CHANGED
@@ -5,6 +5,14 @@
|
|
5
5
|
|
6
6
|
RuboCop Gradual is a tool that helps track down and fix RuboCop offenses in your code gradually. It's a more flexible alternative to RuboCop's `--auto-gen-config` option.
|
7
7
|
|
8
|
+
RuboCop Gradual:
|
9
|
+
|
10
|
+
- generates the lock file with all RuboCop offenses and uses hashes to track each offense **line by line**
|
11
|
+
- **automatically** updates the lock file on every successful run, but returns errors on new offenses
|
12
|
+
- does not prevent your editor from **showing ignored offenses**
|
13
|
+
|
14
|
+
Gain full control of gradual improvements: just add `rubocop-gradual` and use it as proxy for `rubocop`.
|
15
|
+
|
8
16
|
<a href="https://evilmartians.com/?utm_source=rubocop-gradual&utm_campaign=project_page">
|
9
17
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
10
18
|
</a>
|
@@ -27,24 +35,106 @@ Run `rubocop-gradual` before commiting changes to update the lock file. RuboCop
|
|
27
35
|
|
28
36
|
Proposed workflow:
|
29
37
|
|
38
|
+
- Remove `rubocop_todo.yml` if it exists.
|
30
39
|
- Run `rubocop-gradual` to generate a lock file and commit it to the project repository.
|
31
|
-
|
32
|
-
-
|
33
|
-
|
40
|
+
- Add `rubocop-gradual --check` to your CI pipeline instead of `rubocop`/`standard`. It will throw an error if the lock file is out of date.
|
41
|
+
- Run `rubocop-gradual` to update the lock file, or `rubocop-gradual -a` to run autocorrection for all new and changed files and then update the lock file.
|
34
42
|
- Optionally, add `rubocop-gradual` as a pre-commit hook to your repository (using [lefthook], for example).
|
35
|
-
|
36
|
-
- RuboCop Gradual will throw an error on any new offense, but if you really want to force update the lock file, run `rubocop-gradual --update`.
|
43
|
+
- RuboCop Gradual will throw an error on any new offense, but if you really want to force update the lock file, run `rubocop-gradual --force-update`.
|
37
44
|
|
38
45
|
## Available options
|
39
46
|
|
40
47
|
```
|
41
|
-
|
42
|
-
|
48
|
+
-U, --force-update Force update Gradual lock file.
|
49
|
+
--check Check Gradual lock file is up-to-date.
|
50
|
+
-a, --autocorrect Autocorrect offenses (only when it's safe).
|
51
|
+
-A, --autocorrect-all Autocorrect offenses (safe and unsafe).
|
43
52
|
--gradual-file FILE Specify Gradual lock file.
|
44
|
-
--no-gradual Disable Gradual.
|
45
53
|
-v, --version Display version.
|
46
|
-
-
|
47
|
-
|
54
|
+
-h, --help Prints this help.
|
55
|
+
```
|
56
|
+
|
57
|
+
## Rake tasks
|
58
|
+
|
59
|
+
To use built-in Rake tasks add the following to your Rakefile:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# Rakefile
|
63
|
+
require "rubocop/gradual/rake_task"
|
64
|
+
|
65
|
+
RuboCop::Gradual::RakeTask.new
|
66
|
+
```
|
67
|
+
|
68
|
+
This will add rake tasks:
|
69
|
+
|
70
|
+
```
|
71
|
+
bundle exec rake -T
|
72
|
+
rake rubocop_gradual # Run RuboCop Gradual
|
73
|
+
rake rubocop_gradual:autocorrect # Run RuboCop Gradual with autocorrect (only when it's safe)
|
74
|
+
rake rubocop_gradual:autocorrect_all # Run RuboCop Gradual with autocorrect (safe and unsafe)
|
75
|
+
rake rubocop_gradual:check # Run RuboCop Gradual to check the lock file
|
76
|
+
rake rubocop_gradual:force_update # Run RuboCop Gradual to force update the lock file
|
77
|
+
```
|
78
|
+
|
79
|
+
It's possible to customize the Rake task name and options:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# Rakefile
|
83
|
+
|
84
|
+
require "rubocop/gradual/rake_task"
|
85
|
+
|
86
|
+
RuboCop::Gradual::RakeTask.new(:custom_task_name) do |task|
|
87
|
+
task.options = %w[--gradual-file custom_gradual_file.lock]
|
88
|
+
task.verbose = false
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
## Partial linting (experimental)
|
93
|
+
|
94
|
+
RuboCop Gradual supports partial linting. It's useful when you want to run RuboCop Gradual on a subset of files, for example, on changed files in a pull request:
|
95
|
+
|
96
|
+
```shell
|
97
|
+
rubocop-gradual path/to/file # run `rubocop-gradual` on a subset of files
|
98
|
+
rubocop-gradual --staged # run `rubocop-gradual` on staged files
|
99
|
+
rubocop-gradual --unstaged # run `rubocop-gradual` on unstaged files
|
100
|
+
rubocop-gradual --commit origin/main # run `rubocop-gradual` on changed files since the commit
|
101
|
+
|
102
|
+
# it's possible to combine options with autocorrect:
|
103
|
+
rubocop-gradual --staged --autocorrect # run `rubocop-gradual` with autocorrect on staged files
|
104
|
+
```
|
105
|
+
|
106
|
+
## Require mode (experimental)
|
107
|
+
|
108
|
+
RuboCop Gradual can be used in "Require mode", which is a way to replace `rubocop` with `rubocop-gradual`:
|
109
|
+
|
110
|
+
```yaml
|
111
|
+
# .rubocop.yml
|
112
|
+
|
113
|
+
require:
|
114
|
+
- rubocop-gradual
|
115
|
+
```
|
116
|
+
|
117
|
+
Now base `rubocop` command will run `rubocop-gradual`:
|
118
|
+
|
119
|
+
```shell
|
120
|
+
rubocop # run `rubocop-gradual`
|
121
|
+
rubocop -a # run `rubocop-gradual` with autocorrect (only when it's safe)
|
122
|
+
rubocop -A # run `rubocop-gradual` with autocorrect (safe and unsafe)
|
123
|
+
rubocop gradual check # run `rubocop-gradual` to check the lock file
|
124
|
+
rubocop gradual force_update # run `rubocop-gradual` to force update the lock file
|
125
|
+
```
|
126
|
+
|
127
|
+
To set a custom path to Gradual lock file, add `--gradual-file FILE` to a special `.rubocop-gradual` file:
|
128
|
+
|
129
|
+
```
|
130
|
+
# .rubocop-gradual
|
131
|
+
--rubocop-gradual-file path/to/my_lock_file.lock
|
132
|
+
```
|
133
|
+
|
134
|
+
To temporarily disable RuboCop Gradual, prepend command with `NO_GRADUAL=1`:
|
135
|
+
|
136
|
+
```shell
|
137
|
+
NO_GRADUAL=1 rubocop # run `rubocop`
|
48
138
|
```
|
49
139
|
|
50
140
|
## Alternatives
|
data/exe/rubocop-gradual
CHANGED
@@ -11,6 +11,6 @@ cli = RuboCop::Gradual::CLI.new
|
|
11
11
|
|
12
12
|
time = Benchmark.realtime { exit_status = cli.run }
|
13
13
|
|
14
|
-
puts "Finished in #{time} seconds" if
|
14
|
+
puts "Finished in #{time} seconds" if RuboCop::Gradual::Configuration.display_time?
|
15
15
|
|
16
16
|
exit exit_status
|
data/lib/rubocop/gradual/cli.rb
CHANGED
@@ -1,32 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "configuration"
|
3
4
|
require_relative "options"
|
4
|
-
require_relative "formatter"
|
5
5
|
|
6
6
|
module RuboCop
|
7
7
|
module Gradual
|
8
8
|
# CLI is a wrapper around RuboCop::CLI.
|
9
|
-
class CLI
|
10
|
-
def run(
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
class CLI
|
10
|
+
def run(argv = ARGV)
|
11
|
+
Configuration.apply(*Options.new.parse(argv))
|
12
|
+
puts "Gradual mode: #{Configuration.mode}" if Configuration.debug?
|
13
|
+
load_command(Configuration.command).call.to_i
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@options[:formatters] = [[Formatter, nil]]
|
23
|
-
end
|
24
|
-
|
25
|
-
def execute_runners
|
26
|
-
raise OptionArgumentError, "--auto-gen-config cannot be used in gradual mode." if @options[:auto_gen_config]
|
27
|
-
|
28
|
-
result = super
|
29
|
-
Gradual.mode == :disabled ? result : Gradual.exit_code
|
18
|
+
def load_command(command)
|
19
|
+
require_relative "commands/#{command}"
|
20
|
+
::RuboCop::Gradual::Commands.const_get(command.to_s.capitalize).new
|
30
21
|
end
|
31
22
|
end
|
32
23
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
require_relative "../formatters/autocorrect"
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
module Gradual
|
8
|
+
module Commands
|
9
|
+
# Autocorrect command runs RuboCop autocorrect before running the base command.
|
10
|
+
class Autocorrect
|
11
|
+
def call
|
12
|
+
runner = RuboCop::CLI::Command::ExecuteRunner.new(
|
13
|
+
RuboCop::CLI::Environment.new(
|
14
|
+
Configuration.rubocop_options.merge(formatters: [[Formatters::Autocorrect, nil]]),
|
15
|
+
Configuration.rubocop_config_store,
|
16
|
+
lint_paths
|
17
|
+
)
|
18
|
+
)
|
19
|
+
runner.run
|
20
|
+
Base.new.call
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def lint_paths
|
26
|
+
return Configuration.target_file_paths if Configuration.lint_paths.any?
|
27
|
+
|
28
|
+
changed_or_untracked_files.map(&:path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def changed_or_untracked_files
|
32
|
+
tracked_files = LockFile.new(Configuration.path).read_results&.files || []
|
33
|
+
|
34
|
+
target_files.reject do |file|
|
35
|
+
tracked_files.any? { |r| r.path == file.path && r.file_hash == file.file_hash }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def target_files
|
40
|
+
Parallel.map(Configuration.target_file_paths) do |path|
|
41
|
+
Results::File.new(path: path, issues: [])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "benchmark"
|
4
|
+
|
5
|
+
require_relative "../formatters/base"
|
6
|
+
require_relative "../process"
|
7
|
+
|
8
|
+
module RuboCop
|
9
|
+
module Gradual
|
10
|
+
module Commands
|
11
|
+
# Base command runs RuboCop, and processes the results with Gradual.
|
12
|
+
class Base
|
13
|
+
def call
|
14
|
+
exit_code = 0
|
15
|
+
run_rubocop
|
16
|
+
write_stats_message
|
17
|
+
time = Benchmark.realtime { exit_code = Process.new(Configuration.rubocop_results).call }
|
18
|
+
puts "Finished Gradual processing in #{time} seconds" if Configuration.display_time?
|
19
|
+
|
20
|
+
exit_code
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def run_rubocop
|
26
|
+
rubocop_runner = RuboCop::CLI::Command::ExecuteRunner.new(
|
27
|
+
RuboCop::CLI::Environment.new(
|
28
|
+
rubocop_options,
|
29
|
+
Configuration.rubocop_config_store,
|
30
|
+
lint_paths
|
31
|
+
)
|
32
|
+
)
|
33
|
+
rubocop_runner.run
|
34
|
+
end
|
35
|
+
|
36
|
+
def lint_paths
|
37
|
+
return [] if Configuration.lint_paths.empty?
|
38
|
+
|
39
|
+
Configuration.target_file_paths
|
40
|
+
end
|
41
|
+
|
42
|
+
def rubocop_options
|
43
|
+
Configuration.rubocop_options
|
44
|
+
.slice(:config, :debug, :display_time)
|
45
|
+
.merge(formatters: [[Formatters::Base, nil]])
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_stats_message
|
49
|
+
issues_count = Configuration.rubocop_results.sum { |f| f[:issues].size }
|
50
|
+
puts "\nFound #{Configuration.rubocop_results.size} files with #{issues_count} issue(s)."
|
51
|
+
puts "Processing results..."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Gradual
|
5
|
+
# Configuration class stores Gradual and Rubocop options.
|
6
|
+
module Configuration
|
7
|
+
class << self
|
8
|
+
attr_reader :options, :rubocop_options, :rubocop_results, :lint_paths, :target_file_paths
|
9
|
+
|
10
|
+
def apply(options = {}, rubocop_options = {}, lint_paths = [])
|
11
|
+
@options = options
|
12
|
+
@rubocop_options = rubocop_options
|
13
|
+
@lint_paths = lint_paths
|
14
|
+
@target_file_paths = rubocop_target_file_paths
|
15
|
+
@rubocop_results = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def command
|
19
|
+
options.fetch(:command, :base)
|
20
|
+
end
|
21
|
+
|
22
|
+
def mode
|
23
|
+
options.fetch(:mode, :update)
|
24
|
+
end
|
25
|
+
|
26
|
+
def path
|
27
|
+
options.fetch(:path, ".rubocop_gradual.lock")
|
28
|
+
end
|
29
|
+
|
30
|
+
def debug?
|
31
|
+
rubocop_options[:debug]
|
32
|
+
end
|
33
|
+
|
34
|
+
def display_time?
|
35
|
+
rubocop_options[:debug] || rubocop_options[:display_time]
|
36
|
+
end
|
37
|
+
|
38
|
+
def rubocop_config_store
|
39
|
+
RuboCop::ConfigStore.new.tap do |config_store|
|
40
|
+
config_store.options_config = rubocop_options[:config] if rubocop_options[:config]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def rubocop_target_file_paths
|
47
|
+
target_finder = RuboCop::TargetFinder.new(rubocop_config_store, rubocop_options)
|
48
|
+
mode = if rubocop_options[:only_recognized_file_types]
|
49
|
+
:only_recognized_file_types
|
50
|
+
else
|
51
|
+
:all_file_types
|
52
|
+
end
|
53
|
+
target_finder
|
54
|
+
.find(lint_paths, mode)
|
55
|
+
.map { |path| RuboCop::PathUtil.smart_path(path) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Gradual
|
7
|
+
module Formatters
|
8
|
+
# Formatter is a RuboCop formatter class that collects RuboCop results and
|
9
|
+
# calls the Gradual::Process class at the end to process them.
|
10
|
+
class Autocorrect < RuboCop::Formatter::BaseFormatter
|
11
|
+
include PathUtil
|
12
|
+
|
13
|
+
def initialize(_output, options = {})
|
14
|
+
super
|
15
|
+
@corrected_files = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def started(target_files)
|
19
|
+
puts "Inspecting #{target_files.size} file(s) for autocorrection..."
|
20
|
+
end
|
21
|
+
|
22
|
+
def file_finished(_file, offenses)
|
23
|
+
print "."
|
24
|
+
return if offenses.empty?
|
25
|
+
|
26
|
+
@corrected_files += 1 if offenses.any?(&:corrected?)
|
27
|
+
end
|
28
|
+
|
29
|
+
def finished(_inspected_files)
|
30
|
+
puts "\nFixed #{@corrected_files} file(s).\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Gradual
|
7
|
+
module Formatters
|
8
|
+
# Base is a RuboCop formatter class that collects RuboCop results and
|
9
|
+
# writes them to Configuration.rubocop_results.
|
10
|
+
class Base < RuboCop::Formatter::BaseFormatter
|
11
|
+
include PathUtil
|
12
|
+
|
13
|
+
def file_finished(file, offenses)
|
14
|
+
print "."
|
15
|
+
return if offenses.empty?
|
16
|
+
|
17
|
+
Configuration.rubocop_results << {
|
18
|
+
path: smart_path(file),
|
19
|
+
issues: offenses.reject(&:corrected?).map { |o| issue_offense(o) }
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def issue_offense(offense)
|
26
|
+
{
|
27
|
+
line: offense.line,
|
28
|
+
column: offense.real_column,
|
29
|
+
length: offense.location.length,
|
30
|
+
message: offense.message
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rbconfig"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Gradual
|
7
|
+
# Git class handles git commands.
|
8
|
+
module Git
|
9
|
+
class << self
|
10
|
+
def paths_by(commit)
|
11
|
+
git_installed!
|
12
|
+
|
13
|
+
case commit
|
14
|
+
when :unstaged
|
15
|
+
`git ls-files --others --exclude-standard -m`.split("\n")
|
16
|
+
when :staged
|
17
|
+
`git diff --cached --name-only`.split("\n")
|
18
|
+
else
|
19
|
+
`git diff --name-only #{commit}`.split("\n")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def git_installed!
|
26
|
+
void = /msdos|mswin|djgpp|mingw/.match?(RbConfig::CONFIG["host_os"]) ? "NUL" : "/dev/null"
|
27
|
+
git_found = `git --version >>#{void} 2>&1`
|
28
|
+
|
29
|
+
raise Error, "Git is not found, please install it first." unless git_found
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,73 +1,111 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "rainbow"
|
4
3
|
require "shellwords"
|
5
4
|
|
5
|
+
require_relative "git"
|
6
|
+
|
6
7
|
module RuboCop
|
7
8
|
module Gradual
|
8
9
|
# Options class defines RuboCop Gradual cli options.
|
9
|
-
# It also extracts command line RuboCop Gradual arguments
|
10
|
-
# before passing leftover arguments to RuboCop::CLI.
|
11
10
|
class Options
|
11
|
+
AUTOCORRECT_KEY =
|
12
|
+
if Gem::Version.new(RuboCop::Version::STRING) >= Gem::Version.new("1.30")
|
13
|
+
:autocorrect
|
14
|
+
else
|
15
|
+
:auto_correct
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@options = {}
|
20
|
+
end
|
21
|
+
|
12
22
|
def parse(args)
|
13
23
|
parser = define_options
|
14
|
-
|
15
|
-
|
16
|
-
|
24
|
+
gradual_args, rubocop_args = filter_args(parser, args_from_file + args)
|
25
|
+
@rubocop_options, @lint_paths = RuboCop::Options.new.parse(rubocop_args)
|
26
|
+
parser.parse(gradual_args)
|
27
|
+
|
28
|
+
[@options, @rubocop_options, @lint_paths]
|
17
29
|
end
|
18
30
|
|
19
31
|
private
|
20
32
|
|
21
33
|
def define_options
|
22
34
|
OptionParser.new do |opts|
|
23
|
-
opts
|
24
|
-
|
35
|
+
define_mode_options(opts)
|
25
36
|
define_gradual_options(opts)
|
37
|
+
define_lint_paths_options(opts)
|
26
38
|
|
27
|
-
|
39
|
+
define_info_options(opts)
|
28
40
|
end
|
29
41
|
end
|
30
42
|
|
31
|
-
def
|
32
|
-
opts.on("-
|
43
|
+
def define_mode_options(opts)
|
44
|
+
opts.on("-U", "--force-update", "Force update Gradual lock file.") { @options[:mode] = :force_update }
|
45
|
+
opts.on("-u", "--update", "Same as --force-update (deprecated).") do
|
46
|
+
warn "-u, --update is deprecated. Use -U, --force-update instead."
|
47
|
+
@options[:mode] = :force_update
|
48
|
+
end
|
33
49
|
|
34
|
-
opts.on("--
|
50
|
+
opts.on("--check", "Check Gradual lock file is up-to-date.") { @options[:mode] = :check }
|
51
|
+
opts.on("--ci", "Same as --check (deprecated).") do
|
52
|
+
warn "--ci is deprecated. Use --check instead."
|
53
|
+
@options[:mode] = :check
|
54
|
+
end
|
55
|
+
end
|
35
56
|
|
36
|
-
|
57
|
+
def define_gradual_options(opts)
|
58
|
+
opts.on("-a", "--autocorrect", "Autocorrect offenses (only when it's safe).") do
|
59
|
+
@rubocop_options[AUTOCORRECT_KEY] = true
|
60
|
+
@rubocop_options[:"safe_#{AUTOCORRECT_KEY}"] = true
|
61
|
+
@options[:command] = :autocorrect
|
62
|
+
end
|
63
|
+
opts.on("-A", "--autocorrect-all", "Autocorrect offenses (safe and unsafe).") do
|
64
|
+
@rubocop_options[AUTOCORRECT_KEY] = true
|
65
|
+
@options[:command] = :autocorrect
|
66
|
+
end
|
37
67
|
|
38
|
-
opts.on("--
|
68
|
+
opts.on("--gradual-file FILE", "Specify Gradual lock file.") { |path| @options[:path] = path }
|
39
69
|
end
|
40
70
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
71
|
+
def define_lint_paths_options(opts)
|
72
|
+
opts.on("--unstaged", "Lint unstaged files.") do
|
73
|
+
@lint_paths = git_lint_paths(:unstaged)
|
44
74
|
end
|
75
|
+
opts.on("--staged", "Lint staged files.") do
|
76
|
+
@lint_paths = git_lint_paths(:staged)
|
77
|
+
end
|
78
|
+
opts.on("--commit COMMIT", "Lint files changed since the commit.") do |commit|
|
79
|
+
@lint_paths = git_lint_paths(commit)
|
80
|
+
end
|
81
|
+
end
|
45
82
|
|
46
|
-
|
47
|
-
|
83
|
+
def define_info_options(opts)
|
84
|
+
opts.on("-v", "--version", "Display version.") do
|
85
|
+
puts "rubocop-gradual: #{VERSION}, rubocop: #{RuboCop::Version.version}"
|
86
|
+
exit
|
48
87
|
end
|
49
88
|
|
50
|
-
|
51
|
-
|
89
|
+
opts.on("-h", "--help", "Prints this help.") do
|
90
|
+
puts opts
|
91
|
+
exit
|
52
92
|
end
|
53
93
|
end
|
54
94
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
yield
|
59
|
-
end
|
95
|
+
def git_lint_paths(commit)
|
96
|
+
@rubocop_options[:only_recognized_file_types] = true
|
97
|
+
RuboCop::Gradual::Git.paths_by(commit)
|
60
98
|
end
|
61
99
|
|
62
100
|
def filter_args(parser, original_args, self_args = [])
|
63
|
-
extract_all_args(parser).each do |
|
101
|
+
extract_all_args(parser).each do |option|
|
64
102
|
loop do
|
65
|
-
break unless (i = original_args.index { |a| a.start_with?(
|
103
|
+
break unless (i = original_args.index { |a| a.start_with?(option[:name]) })
|
104
|
+
|
105
|
+
self_args << original_args.delete_at(i)
|
106
|
+
next if option[:no_args] || original_args.size <= i || original_args[i].start_with?("-")
|
66
107
|
|
67
|
-
|
68
|
-
self_args << original_args.delete_at(i)
|
69
|
-
break if original_args.size <= i || original_args[i].start_with?("-")
|
70
|
-
end
|
108
|
+
self_args << original_args.delete_at(i)
|
71
109
|
end
|
72
110
|
end
|
73
111
|
[self_args, original_args]
|
@@ -75,7 +113,9 @@ module RuboCop
|
|
75
113
|
|
76
114
|
def extract_all_args(parser)
|
77
115
|
parser.top.list.reduce([]) do |res, option|
|
78
|
-
|
116
|
+
no_args = option.is_a?(OptionParser::Switch::NoArgument)
|
117
|
+
options = (option.long + option.short).map { |o| { name: o, no_args: no_args } }
|
118
|
+
res + options
|
79
119
|
end
|
80
120
|
end
|
81
121
|
|
@@ -86,12 +126,6 @@ module RuboCop
|
|
86
126
|
[]
|
87
127
|
end
|
88
128
|
end
|
89
|
-
|
90
|
-
def rainbow
|
91
|
-
@rainbow ||= Rainbow.new.tap do |r|
|
92
|
-
r.enabled = false if ARGV.include?("--no-color")
|
93
|
-
end
|
94
|
-
end
|
95
129
|
end
|
96
130
|
end
|
97
131
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop-gradual"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Gradual
|
7
|
+
# Patching RuboCop::CLI to enable require mode.
|
8
|
+
module Patch
|
9
|
+
def run_command(name)
|
10
|
+
return super if name != :execute_runner || (ARGV & %w[--stdin -s]).any?
|
11
|
+
|
12
|
+
Configuration.apply(*parse_options)
|
13
|
+
puts "Gradual mode: #{Configuration.mode}" if Configuration.debug?
|
14
|
+
load_command(Configuration.command).call.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def load_command(command)
|
20
|
+
require_relative "commands/#{command}"
|
21
|
+
::RuboCop::Gradual::Commands.const_get(command.to_s.capitalize).new
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_options
|
25
|
+
options, rubocop_options = Options.new.parse(ARGV)
|
26
|
+
options[:mode] = :force_update if @env.paths[0..1] == %w[gradual force_update]
|
27
|
+
options[:mode] = :check if @env.paths[0..1] == %w[gradual check]
|
28
|
+
[options, rubocop_options]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
module CalculateDiff
|
11
11
|
class << self
|
12
12
|
def call(new_result, old_result)
|
13
|
-
return Diff.new.
|
13
|
+
return Diff.new.add_files(new_result.files, :new) if old_result.nil?
|
14
14
|
|
15
15
|
diff_results(new_result, old_result)
|
16
16
|
end
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
def diff_results(new_result, old_result)
|
21
21
|
new_files, fixed_files, path_files_match, moved_files_match = split_files(new_result, old_result)
|
22
22
|
|
23
|
-
diff = Diff.new.
|
23
|
+
diff = Diff.new.add_files(new_files, :new).add_files(fixed_files, :fixed)
|
24
24
|
path_files_match.chain(moved_files_match).each do |result_file, old_file|
|
25
25
|
diff_issues(diff, result_file, old_file)
|
26
26
|
end
|
@@ -73,19 +73,6 @@ module RuboCop
|
|
73
73
|
end
|
74
74
|
possibilities.min_by { |possibility| issue.distance(possibility) }
|
75
75
|
end
|
76
|
-
|
77
|
-
def map_same_files(left, right)
|
78
|
-
map_files(left.files, right.files) do |new_file, old_file|
|
79
|
-
new_file.path == old_file.path
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def map_files(key_files, value_files)
|
84
|
-
key_files.each_with_object({}) do |key_file, res|
|
85
|
-
same_file = value_files.find { |value_file| yield(key_file, value_file) }
|
86
|
-
res[key_file] = same_file if same_file
|
87
|
-
end
|
88
|
-
end
|
89
76
|
end
|
90
77
|
end
|
91
78
|
end
|
@@ -33,16 +33,9 @@ module RuboCop
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def add_files(files, key)
|
37
37
|
files.each do |file|
|
38
|
-
add_issues(file.path,
|
39
|
-
end
|
40
|
-
self
|
41
|
-
end
|
42
|
-
|
43
|
-
def add_fixed(files)
|
44
|
-
files.each do |file|
|
45
|
-
add_issues(file.path, fixed: file.issues)
|
38
|
+
add_issues(file.path, **{ key => file.issues })
|
46
39
|
end
|
47
40
|
self
|
48
41
|
end
|
@@ -54,7 +47,7 @@ module RuboCop
|
|
54
47
|
new: new,
|
55
48
|
unchanged: unchanged
|
56
49
|
}
|
57
|
-
log_file_issues(path) if
|
50
|
+
log_file_issues(path) if Configuration.debug?
|
58
51
|
self
|
59
52
|
end
|
60
53
|
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def print_results
|
13
|
-
puts diff.statistics if
|
13
|
+
puts diff.statistics if Configuration.debug?
|
14
14
|
|
15
15
|
send "print_#{diff.state}"
|
16
16
|
end
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
- Run `rubocop-gradual` locally and commit the results, or
|
24
24
|
- EVEN BETTER: before doing the above, try to fix the remaining issues in those files!
|
25
25
|
|
26
|
-
#{bold("`#{
|
26
|
+
#{bold("`#{Configuration.path}` diff:")}
|
27
27
|
|
28
28
|
#{diff.to_s(ARGV.include?("--no-color") ? :text : :color)}
|
29
29
|
MSG
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
35
35
|
|
36
36
|
def print_complete
|
37
37
|
puts bold("RuboCop Gradual is complete!")
|
38
|
-
puts "Removing `#{
|
38
|
+
puts "Removing `#{Configuration.path}` lock file..." if diff.statistics[:fixed].positive?
|
39
39
|
end
|
40
40
|
|
41
41
|
def print_updated
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
def print_new
|
50
50
|
issues_left = diff.statistics[:left]
|
51
51
|
puts bold("RuboCop Gradual got results for the first time. #{issues_left} issue(s) found.")
|
52
|
-
puts "Don't forget to commit `#{
|
52
|
+
puts "Don't forget to commit `#{Configuration.path}` log file."
|
53
53
|
end
|
54
54
|
|
55
55
|
def print_better
|
@@ -61,7 +61,7 @@ module RuboCop
|
|
61
61
|
def print_worse
|
62
62
|
puts bold("Uh oh, RuboCop Gradual got worse:")
|
63
63
|
print_new_issues
|
64
|
-
puts bold("Force updating lock file...") if
|
64
|
+
puts bold("Force updating lock file...") if Configuration.mode == :force_update
|
65
65
|
end
|
66
66
|
|
67
67
|
def print_new_issues
|
@@ -9,46 +9,52 @@ module RuboCop
|
|
9
9
|
module Gradual
|
10
10
|
# Process is a class that handles the processing of RuboCop results.
|
11
11
|
class Process
|
12
|
-
attr_reader :
|
12
|
+
attr_reader :lock_file, :old_results, :new_results
|
13
13
|
|
14
14
|
def initialize(rubocop_result)
|
15
|
-
@lock_file = LockFile.new(
|
16
|
-
@
|
15
|
+
@lock_file = LockFile.new(Configuration.path)
|
16
|
+
@old_results = lock_file.read_results
|
17
|
+
@new_results = Results.new(files: rubocop_result)
|
18
|
+
add_skipped_files_to_new_results!
|
17
19
|
end
|
18
20
|
|
19
21
|
def call
|
20
|
-
diff = CalculateDiff.call(new_results,
|
22
|
+
diff = CalculateDiff.call(new_results, old_results)
|
21
23
|
printer = Printer.new(diff)
|
22
|
-
if print_ci_warning?(diff)
|
23
|
-
printer.print_ci_warning(lock_file.diff(new_results))
|
24
|
-
else
|
25
|
-
printer.print_results
|
26
|
-
end
|
27
24
|
|
28
|
-
|
25
|
+
printer.print_results
|
26
|
+
printer.print_ci_warning(lock_file.diff(new_results)) if fail_with_outdated_lock?(diff)
|
29
27
|
|
30
|
-
|
28
|
+
exit_code = error_code(diff)
|
29
|
+
sync_lock_file(diff) if exit_code.zero?
|
30
|
+
exit_code
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
def
|
36
|
-
|
35
|
+
def fail_with_outdated_lock?(diff)
|
36
|
+
Configuration.mode == :check && diff.state != :no_changes
|
37
37
|
end
|
38
38
|
|
39
39
|
def sync_lock_file(diff)
|
40
|
-
return unless Gradual.exit_code.zero?
|
41
40
|
return lock_file.delete if diff.state == :complete
|
42
41
|
|
43
42
|
lock_file.write_results(new_results)
|
44
43
|
end
|
45
44
|
|
46
45
|
def error_code(diff)
|
47
|
-
return 1 if
|
48
|
-
return 1 if diff.state == :worse &&
|
46
|
+
return 1 if fail_with_outdated_lock?(diff)
|
47
|
+
return 1 if diff.state == :worse && Configuration.mode != :force_update
|
49
48
|
|
50
49
|
0
|
51
50
|
end
|
51
|
+
|
52
|
+
def add_skipped_files_to_new_results!
|
53
|
+
return if Configuration.lint_paths.none? || old_results.nil?
|
54
|
+
|
55
|
+
skipped_files = old_results.files.reject { |file| Configuration.target_file_paths.include?(file.path) }
|
56
|
+
new_results.files.concat(skipped_files).sort!
|
57
|
+
end
|
52
58
|
end
|
53
59
|
end
|
54
60
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rake"
|
4
|
+
require "rake/tasklib"
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
module Gradual
|
8
|
+
# Rake tasks for RuboCop::Gradual.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# require "rubocop/gradual/rake_task"
|
12
|
+
# RuboCop::Gradual::RakeTask.new
|
13
|
+
#
|
14
|
+
class RakeTask < ::Rake::TaskLib
|
15
|
+
attr_accessor :name, :verbose, :options
|
16
|
+
|
17
|
+
def initialize(name = :rubocop_gradual, *args, &task_block)
|
18
|
+
super()
|
19
|
+
@name = name
|
20
|
+
@verbose = true
|
21
|
+
@options = []
|
22
|
+
define(args, &task_block)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def define(args, &task_block)
|
28
|
+
desc "Run RuboCop Gradual" unless ::Rake.application.last_description
|
29
|
+
define_task(name, nil, args, &task_block)
|
30
|
+
setup_subtasks(args, &task_block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_subtasks(args, &task_block)
|
34
|
+
namespace(name) do
|
35
|
+
desc "Run RuboCop Gradual with autocorrect (only when it's safe)."
|
36
|
+
define_task(:autocorrect, "--autocorrect", args, &task_block)
|
37
|
+
|
38
|
+
desc "Run RuboCop Gradual with autocorrect (safe and unsafe)."
|
39
|
+
define_task(:autocorrect_all, "--autocorrect-all", args, &task_block)
|
40
|
+
|
41
|
+
desc "Run RuboCop Gradual to check the lock file."
|
42
|
+
define_task(:check, "--check", args, &task_block)
|
43
|
+
|
44
|
+
desc "Run RuboCop Gradual to force update the lock file."
|
45
|
+
define_task(:force_update, "--force-update", args, &task_block)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def define_task(name, option, args, &task_block)
|
50
|
+
task(name, *args) do |_, task_args|
|
51
|
+
RakeFileUtils.verbose(verbose) do
|
52
|
+
yield(*[self, task_args].slice(0, task_block.arity)) if task_block
|
53
|
+
run_cli(verbose, option)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_cli(verbose, option)
|
59
|
+
require "rubocop-gradual"
|
60
|
+
|
61
|
+
cli = CLI.new
|
62
|
+
puts "Running RuboCop Gradual..." if verbose
|
63
|
+
result = cli.run(full_options(option))
|
64
|
+
abort("RuboCop Gradual failed!") if result.nonzero?
|
65
|
+
end
|
66
|
+
|
67
|
+
def full_options(option)
|
68
|
+
option ? options.flatten.unshift(option) : options.flatten
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/rubocop/gradual.rb
CHANGED
@@ -9,18 +9,10 @@ module RuboCop
|
|
9
9
|
# RuboCop Gradual project namespace
|
10
10
|
module Gradual
|
11
11
|
class Error < StandardError; end
|
12
|
-
|
13
|
-
class << self
|
14
|
-
attr_accessor :debug, :exit_code, :mode, :path
|
15
|
-
|
16
|
-
def set_defaults!
|
17
|
-
self.debug = false
|
18
|
-
self.exit_code = 0
|
19
|
-
self.mode = :base
|
20
|
-
self.path = ".rubocop_gradual.lock"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
set_defaults!
|
25
12
|
end
|
26
13
|
end
|
14
|
+
|
15
|
+
if ENV["NO_GRADUAL"] != "1" && (RuboCop::ConfigLoader.loaded_features & %w[rubocop-gradual rubocop/gradual]).any?
|
16
|
+
require_relative "gradual/patch"
|
17
|
+
RuboCop::CLI.prepend(RuboCop::Gradual::Patch)
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-gradual
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Svyatoslav Kryukov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diff-lcs
|
@@ -107,14 +107,21 @@ files:
|
|
107
107
|
- lib/rubocop-gradual.rb
|
108
108
|
- lib/rubocop/gradual.rb
|
109
109
|
- lib/rubocop/gradual/cli.rb
|
110
|
-
- lib/rubocop/gradual/
|
110
|
+
- lib/rubocop/gradual/commands/autocorrect.rb
|
111
|
+
- lib/rubocop/gradual/commands/base.rb
|
112
|
+
- lib/rubocop/gradual/configuration.rb
|
113
|
+
- lib/rubocop/gradual/formatters/autocorrect.rb
|
114
|
+
- lib/rubocop/gradual/formatters/base.rb
|
115
|
+
- lib/rubocop/gradual/git.rb
|
111
116
|
- lib/rubocop/gradual/lock_file.rb
|
112
117
|
- lib/rubocop/gradual/options.rb
|
118
|
+
- lib/rubocop/gradual/patch.rb
|
113
119
|
- lib/rubocop/gradual/process.rb
|
114
120
|
- lib/rubocop/gradual/process/calculate_diff.rb
|
115
121
|
- lib/rubocop/gradual/process/diff.rb
|
116
122
|
- lib/rubocop/gradual/process/matcher.rb
|
117
123
|
- lib/rubocop/gradual/process/printer.rb
|
124
|
+
- lib/rubocop/gradual/rake_task.rb
|
118
125
|
- lib/rubocop/gradual/results.rb
|
119
126
|
- lib/rubocop/gradual/results/file.rb
|
120
127
|
- lib/rubocop/gradual/results/issue.rb
|
@@ -145,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
152
|
- !ruby/object:Gem::Version
|
146
153
|
version: '0'
|
147
154
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
155
|
+
rubygems_version: 3.3.7
|
149
156
|
signing_key:
|
150
157
|
specification_version: 4
|
151
158
|
summary: Gradual RuboCop plugin
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "benchmark"
|
4
|
-
require "pathname"
|
5
|
-
|
6
|
-
require_relative "process"
|
7
|
-
|
8
|
-
module RuboCop
|
9
|
-
module Gradual
|
10
|
-
# Formatter is a RuboCop formatter class that collects RuboCop results and
|
11
|
-
# calls the Gradual::Process class at the end to process them.
|
12
|
-
class Formatter < RuboCop::Formatter::BaseFormatter
|
13
|
-
include PathUtil
|
14
|
-
|
15
|
-
attr_reader :output_hash
|
16
|
-
|
17
|
-
def initialize(_output, options = {})
|
18
|
-
super
|
19
|
-
Gradual.debug = options[:debug]
|
20
|
-
puts "Gradual mode: #{Gradual.mode}" if Gradual.debug
|
21
|
-
@output_hash = { files: [] }
|
22
|
-
end
|
23
|
-
|
24
|
-
def file_finished(file, offenses)
|
25
|
-
print "."
|
26
|
-
return if offenses.empty?
|
27
|
-
|
28
|
-
output_hash[:files] << {
|
29
|
-
path: smart_path(file),
|
30
|
-
issues: offenses.reject(&:corrected?).map { |o| issue_offense(o) }
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
def finished(_inspected_files)
|
35
|
-
puts "\n#{stats_message}"
|
36
|
-
puts "Processing results..."
|
37
|
-
|
38
|
-
time = Benchmark.realtime { Process.new(output_hash).call }
|
39
|
-
|
40
|
-
puts "Finished Gradual processing in #{time} seconds" if options[:debug] || options[:display_time]
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def issue_offense(offense)
|
46
|
-
{
|
47
|
-
line: offense.line,
|
48
|
-
column: offense.real_column,
|
49
|
-
length: offense.location.length,
|
50
|
-
message: offense.message
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
def stats_message
|
55
|
-
issues_count = output_hash[:files].sum { |f| f[:issues].size }
|
56
|
-
"Found #{output_hash[:files].size} files with #{issues_count} issue(s)."
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|