rubocop-gradual 0.1.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|