slimcop 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 +4 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +2 -1
- data/README.md +2 -0
- data/lib/slimcop/cli.rb +56 -18
- data/lib/slimcop/configuration.rb +16 -0
- data/lib/slimcop/formatter.rb +72 -0
- data/lib/slimcop/offense.rb +71 -0
- data/lib/slimcop/ruby_offense_collector.rb +4 -2
- data/lib/slimcop/slim_corrector.rb +3 -2
- data/lib/slimcop/slim_offense_collector.rb +9 -5
- data/lib/slimcop/version.rb +1 -1
- data/lib/slimcop.rb +3 -1
- data/slimcop.gemspec +1 -0
- metadata +19 -3
- data/lib/slimcop/runner.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bace4128c4ef162ff7f9a4f1eca5af7275631b850df5a6ad48a92d8693114771
|
4
|
+
data.tar.gz: d7a04c3c5ed2930490174e41e838cd6c7e26a8eae8e6476fa188ee89ae3f103f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4cacec671cd5855ceedd2183099450f2e4abf759d71f11e77e4af5f5c25b7e52a71d6da4f4e7fbaac812bf7509311c4edc5233501b021dfbb9da6259e1b305d
|
7
|
+
data.tar.gz: 0db1c7751629572c7e8738e52fe8d44f41e20047b48f091aa00defa0dad62f2674bf5ae0fafe2b2a53ce5b3eab006fde3f0a9ae840a8cc6c779cadb9632c4845
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 0.2.0 - 2021-12-21
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- Add --color and --no-color option.
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
- Improve offenses CLI output format.
|
14
|
+
- Return exit status 1 if any offense found.
|
15
|
+
|
5
16
|
## 0.1.0 - 2021-12-21
|
6
17
|
|
7
18
|
- Initial release.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Slimcop
|
2
2
|
|
3
|
+
[](https://rubygems.org/gems/slimcop)
|
3
4
|
[](https://github.com/r7kamura/slimcop/actions/workflows/test.yml)
|
4
5
|
|
5
6
|
[RuboCop](https://github.com/rubocop/rubocop) runner for [Slim template](https://github.com/slim-template/slim).
|
@@ -32,4 +33,5 @@ Use `slimcop` executable to check offenses and auto-correct them.
|
|
32
33
|
$ slimcop --help
|
33
34
|
Usage: slimcop [options] [file1, file2, ...]
|
34
35
|
-a, --auto-correct Auto-correct offenses.
|
36
|
+
--[no-]color Force color output on or off.
|
35
37
|
```
|
data/lib/slimcop/cli.rb
CHANGED
@@ -1,36 +1,71 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'rubocop'
|
3
|
+
require 'rainbow'
|
5
4
|
|
6
5
|
module Slimcop
|
7
6
|
class Cli
|
8
7
|
def initialize(argv)
|
9
8
|
@argv = argv.dup
|
9
|
+
@configuration = Configuration.new
|
10
|
+
@formatter = Formatter.new
|
10
11
|
end
|
11
12
|
|
12
13
|
def call
|
13
14
|
options = parse!
|
14
|
-
@argv
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
else
|
24
|
-
messages = runner.offenses.map do |offense|
|
25
|
-
offense[:rubocop_offense].message
|
26
|
-
end
|
27
|
-
puts messages
|
28
|
-
end
|
29
|
-
end
|
15
|
+
slim_file_paths = @argv
|
16
|
+
|
17
|
+
Rainbow.enabled = options[:color] if options.key?(:color)
|
18
|
+
|
19
|
+
offenses_set = investigate(auto_correct: options[:auto_correct], slim_file_paths: slim_file_paths)
|
20
|
+
correct(offenses_set) if options[:auto_correct]
|
21
|
+
offenses = offenses_set.flat_map { |(_, _, array)| array }
|
22
|
+
report(offenses)
|
23
|
+
exit(offenses.empty? ? 0 : 1)
|
30
24
|
end
|
31
25
|
|
32
26
|
private
|
33
27
|
|
28
|
+
# @param [Array] offenses_set
|
29
|
+
def correct(offenses_set)
|
30
|
+
offenses_set.each do |(file_path, source, offenses)|
|
31
|
+
rewritten_source = SlimCorrector.new(
|
32
|
+
file_path: file_path,
|
33
|
+
offenses: offenses,
|
34
|
+
source: source
|
35
|
+
).call
|
36
|
+
::File.write(file_path, rewritten_source)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param [Boolean] auto_correct
|
41
|
+
# @param [Array] slim_file_paths
|
42
|
+
# @return [Array]
|
43
|
+
def investigate(auto_correct:, slim_file_paths:)
|
44
|
+
slim_file_paths.map do |file_path|
|
45
|
+
source = ::File.read(file_path)
|
46
|
+
offenses = SlimOffenseCollector.new(
|
47
|
+
auto_correct: auto_correct,
|
48
|
+
file_path: file_path,
|
49
|
+
rubocop_config: @configuration.rubocop_config,
|
50
|
+
source: source
|
51
|
+
).call
|
52
|
+
[file_path, source, offenses]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [Array<Slimcop::Offense>] offenses
|
57
|
+
def report(offenses)
|
58
|
+
result = +''
|
59
|
+
unless offenses.empty?
|
60
|
+
result << "\nOffenses:\n\n"
|
61
|
+
lines = offenses.map do |offense|
|
62
|
+
@formatter.format_offense(offense)
|
63
|
+
end
|
64
|
+
result << lines.join("\n")
|
65
|
+
end
|
66
|
+
puts(result)
|
67
|
+
end
|
68
|
+
|
34
69
|
# @return [Hash]
|
35
70
|
def parse!
|
36
71
|
options = {}
|
@@ -39,6 +74,9 @@ module Slimcop
|
|
39
74
|
parser.on('-a', '--auto-correct', 'Auto-correct offenses.') do
|
40
75
|
options[:auto_correct] = true
|
41
76
|
end
|
77
|
+
parser.on('--[no-]color', 'Force color output on or off.') do |value|
|
78
|
+
options[:color] = value
|
79
|
+
end
|
42
80
|
parser.parse!(@argv)
|
43
81
|
options
|
44
82
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop'
|
4
|
+
|
5
|
+
module Slimcop
|
6
|
+
class Configuration
|
7
|
+
# @return [RuboCop::Config]
|
8
|
+
def rubocop_config
|
9
|
+
@rubocop_config ||= begin
|
10
|
+
config_path = ::File.expand_path('../../default.yml', __dir__)
|
11
|
+
config = ::RuboCop::ConfigLoader.load_file(config_path)
|
12
|
+
::RuboCop::ConfigLoader.merge_with_default(config, config_path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'rainbow'
|
5
|
+
|
6
|
+
module Slimcop
|
7
|
+
# Format String for CLI output.
|
8
|
+
class Formatter
|
9
|
+
COLOR_FOR_SEVERITY_CODE = {
|
10
|
+
convention: :yellow,
|
11
|
+
error: :red,
|
12
|
+
fatal: :red,
|
13
|
+
info: :gray,
|
14
|
+
refactor: :yellow,
|
15
|
+
warning: :magenta
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
# @param [Slimcop::Offense] offense
|
19
|
+
# @return [String]
|
20
|
+
def format_offense(offense)
|
21
|
+
format(
|
22
|
+
'%<path>s:%<line>d:%<column>d %<severity>s: %<message>s',
|
23
|
+
column: offense.real_column,
|
24
|
+
line: offense.line,
|
25
|
+
message: message(offense),
|
26
|
+
path: file_path(offense),
|
27
|
+
severity: severity(offense)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @param [String] path e.g. "./spec/fixtures/dummy.slim"
|
34
|
+
# @return [String]
|
35
|
+
# @example "spec/fixtures/dummy.slim"
|
36
|
+
def canonicalize_path(path)
|
37
|
+
::File.expand_path(path).delete_prefix("#{::Dir.pwd}/")
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param [Slimcop::Offense] offense
|
41
|
+
# @return [String]
|
42
|
+
def file_path(offense)
|
43
|
+
Rainbow(canonicalize_path(offense.file_path)).cyan
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [Slimcop::Offense] offense
|
47
|
+
# @return [String]
|
48
|
+
def message(offense)
|
49
|
+
"#{status(offense)}#{offense.message}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param [Slimcop::Offense] offense
|
53
|
+
# @return [String]
|
54
|
+
def severity(offense)
|
55
|
+
Rainbow(offense.severity.code).color(COLOR_FOR_SEVERITY_CODE[offense.severity.name])
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param [Slimcop::Offense] offense
|
59
|
+
# @return [String]
|
60
|
+
def status(offense)
|
61
|
+
if offense.rubocop_offense.corrected_with_todo?
|
62
|
+
Rainbow('[Todo] ').green
|
63
|
+
elsif offense.rubocop_offense.corrected?
|
64
|
+
Rainbow('[Corrected] ').green
|
65
|
+
elsif offense.rubocop_offense.correctable?
|
66
|
+
Rainbow('[Correctable] ').yellow
|
67
|
+
else
|
68
|
+
''
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'parser'
|
4
|
+
|
5
|
+
module Slimcop
|
6
|
+
class Offense
|
7
|
+
# @return [Integer]
|
8
|
+
attr_reader :offset
|
9
|
+
|
10
|
+
# @return [RuboCop::Cop::Offense]
|
11
|
+
attr_reader :rubocop_offense
|
12
|
+
|
13
|
+
# @param [Integer] offset
|
14
|
+
# @param [RuboCop::Cop::Offense] rubocop_offense
|
15
|
+
# @param [String] source Slim code.
|
16
|
+
def initialize(offset:, rubocop_offense:, source:)
|
17
|
+
@offset = offset
|
18
|
+
@rubocop_offense = rubocop_offense
|
19
|
+
@source = source
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [RuboCop::Cop::Corrector]
|
23
|
+
def corrector
|
24
|
+
@rubocop_offense.corrector
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [String]
|
28
|
+
def file_path
|
29
|
+
@rubocop_offense.location.source_buffer.name
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Integer]
|
33
|
+
def line
|
34
|
+
range.line
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String]
|
38
|
+
def message
|
39
|
+
@rubocop_offense.message
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Integer]
|
43
|
+
def real_column
|
44
|
+
range.column + 1
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [RuboCop::Cop::Severity]
|
48
|
+
def severity
|
49
|
+
@rubocop_offense.severity
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# @return [Parser::Source::Buffer]
|
55
|
+
def buffer
|
56
|
+
::Parser::Source::Buffer.new(
|
57
|
+
file_path,
|
58
|
+
source: @source
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Parser::Source::Range]
|
63
|
+
def range
|
64
|
+
@range ||= ::Parser::Source::Range.new(
|
65
|
+
buffer,
|
66
|
+
@rubocop_offense.location.begin_pos + @offset,
|
67
|
+
@rubocop_offense.location.end_pos + @offset
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -5,10 +5,12 @@ require 'rubocop'
|
|
5
5
|
module Slimcop
|
6
6
|
# Collect RuboCop offenses from Ruby code.
|
7
7
|
class RubyOffenseCollector
|
8
|
+
# @param [Boolean] auto_correct
|
8
9
|
# @param [String] file_path
|
9
10
|
# @param [RuboCop::Config] rubocop_config
|
10
11
|
# @param [String] source
|
11
|
-
def initialize(file_path:, rubocop_config:, source:)
|
12
|
+
def initialize(auto_correct:, file_path:, rubocop_config:, source:)
|
13
|
+
@auto_correct = auto_correct
|
12
14
|
@file_path = file_path
|
13
15
|
@rubocop_config = rubocop_config
|
14
16
|
@source = source
|
@@ -37,7 +39,7 @@ module Slimcop
|
|
37
39
|
::RuboCop::Cop::Team.new(
|
38
40
|
::RuboCop::Cop::Registry.new(::RuboCop::Cop::Cop.all),
|
39
41
|
@rubocop_config,
|
40
|
-
auto_correct:
|
42
|
+
auto_correct: @auto_correct,
|
41
43
|
display_cop_names: true,
|
42
44
|
extra_details: true,
|
43
45
|
stdin: ''
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'parser'
|
3
4
|
require 'rubocop/cop/legacy/corrector'
|
4
5
|
|
5
6
|
module Slimcop
|
6
7
|
# Apply auto-corrections to Slim file.
|
7
8
|
class SlimCorrector
|
8
9
|
# @param [String] file_path
|
9
|
-
# @param [Array<
|
10
|
+
# @param [Array<Slimcop::Offense>] offenses
|
10
11
|
# @param [String] source
|
11
12
|
def initialize(file_path:, offenses:, source:)
|
12
13
|
@file_path = file_path
|
@@ -25,7 +26,7 @@ module Slimcop
|
|
25
26
|
def corrections
|
26
27
|
@offenses.map do |offense|
|
27
28
|
lambda do |corrector|
|
28
|
-
corrector.import!(offense
|
29
|
+
corrector.import!(offense.corrector, offset: offense.offset)
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -3,27 +3,31 @@
|
|
3
3
|
module Slimcop
|
4
4
|
# Collect RuboCop offenses from Slim code.
|
5
5
|
class SlimOffenseCollector
|
6
|
+
# @param [Boolean] auto_correct
|
6
7
|
# @param [String] file_path Slim file path
|
7
8
|
# @param [RuboCop::Config] rubocop_config
|
8
9
|
# @param [String] source Slim code
|
9
|
-
def initialize(file_path:, rubocop_config:, source:)
|
10
|
+
def initialize(auto_correct:, file_path:, rubocop_config:, source:)
|
11
|
+
@auto_correct = auto_correct
|
10
12
|
@file_path = file_path
|
11
13
|
@rubocop_config = rubocop_config
|
12
14
|
@source = source
|
13
15
|
end
|
14
16
|
|
15
|
-
# @return [Array<
|
17
|
+
# @return [Array<Slimcop::Offense>]
|
16
18
|
def call
|
17
19
|
snippets.flat_map do |snippet|
|
18
20
|
RubyOffenseCollector.new(
|
21
|
+
auto_correct: @auto_correct,
|
19
22
|
file_path: @file_path,
|
20
23
|
rubocop_config: @rubocop_config,
|
21
24
|
source: snippet[:code]
|
22
25
|
).call.map do |rubocop_offense|
|
23
|
-
|
26
|
+
Offense.new(
|
24
27
|
offset: snippet[:begin_],
|
25
|
-
rubocop_offense: rubocop_offense
|
26
|
-
|
28
|
+
rubocop_offense: rubocop_offense,
|
29
|
+
source: @source
|
30
|
+
)
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
data/lib/slimcop/version.rb
CHANGED
data/lib/slimcop.rb
CHANGED
@@ -4,9 +4,11 @@ require_relative 'slimcop/version'
|
|
4
4
|
|
5
5
|
module Slimcop
|
6
6
|
autoload :Cli, 'slimcop/cli'
|
7
|
+
autoload :Configuration, 'slimcop/configuration'
|
8
|
+
autoload :Formatter, 'slimcop/formatter'
|
9
|
+
autoload :Offense, 'slimcop/offense'
|
7
10
|
autoload :RubyExtractor, 'slimcop/ruby_extractor'
|
8
11
|
autoload :RubyOffenseCollector, 'slimcop/ruby_offense_collector'
|
9
|
-
autoload :Runner, 'slimcop/runner'
|
10
12
|
autoload :SlimCorrector, 'slimcop/slim_corrector'
|
11
13
|
autoload :SlimOffenseCollector, 'slimcop/slim_offense_collector'
|
12
14
|
end
|
data/slimcop.gemspec
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slimcop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rainbow
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rubocop
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,9 +75,11 @@ files:
|
|
61
75
|
- exe/slimcop
|
62
76
|
- lib/slimcop.rb
|
63
77
|
- lib/slimcop/cli.rb
|
78
|
+
- lib/slimcop/configuration.rb
|
79
|
+
- lib/slimcop/formatter.rb
|
80
|
+
- lib/slimcop/offense.rb
|
64
81
|
- lib/slimcop/ruby_extractor.rb
|
65
82
|
- lib/slimcop/ruby_offense_collector.rb
|
66
|
-
- lib/slimcop/runner.rb
|
67
83
|
- lib/slimcop/slim_corrector.rb
|
68
84
|
- lib/slimcop/slim_offense_collector.rb
|
69
85
|
- lib/slimcop/version.rb
|
data/lib/slimcop/runner.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module Slimcop
|
6
|
-
# Report offenses in Slim file, and apply auto-corrections if required.
|
7
|
-
class Runner
|
8
|
-
# @param [String] file_path
|
9
|
-
def initialize(file_path:)
|
10
|
-
@file_path = file_path
|
11
|
-
end
|
12
|
-
|
13
|
-
# @return [Array<Hash>]
|
14
|
-
def offenses
|
15
|
-
@offenses ||= SlimOffenseCollector.new(
|
16
|
-
file_path: @file_path,
|
17
|
-
rubocop_config: rubocop_config,
|
18
|
-
source: source
|
19
|
-
).call
|
20
|
-
end
|
21
|
-
|
22
|
-
def auto_correct
|
23
|
-
SlimCorrector.new(
|
24
|
-
file_path: @file_path,
|
25
|
-
offenses: offenses,
|
26
|
-
source: source
|
27
|
-
).call
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
# @return [RuboCop::Config]
|
33
|
-
def rubocop_config
|
34
|
-
config_path = ::File.expand_path('../../default.yml', __dir__)
|
35
|
-
config = ::RuboCop::ConfigLoader.load_file(config_path)
|
36
|
-
::RuboCop::ConfigLoader.merge_with_default(config, config_path)
|
37
|
-
end
|
38
|
-
|
39
|
-
# @return [Array<Hash>]
|
40
|
-
def snippets
|
41
|
-
RubyExtractor.new(source: source).call
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [String]
|
45
|
-
def source
|
46
|
-
::File.read(@file_path)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|