slimcop 0.1.0 → 0.2.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 +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
|
+
[![Gem Version](https://badge.fury.io/rb/slimcop.svg)](https://rubygems.org/gems/slimcop)
|
3
4
|
[![test](https://github.com/r7kamura/slimcop/actions/workflows/test.yml/badge.svg)](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
|