erbcop 0.1.0 → 0.4.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 +24 -0
- data/Gemfile.lock +6 -3
- data/README.md +1 -0
- data/default.yml +6 -0
- data/erbcop.gemspec +1 -2
- data/exe/erbcop +8 -1
- data/lib/erbcop/ruby_extractor.rb +31 -23
- data/lib/erbcop/version.rb +1 -1
- metadata +3 -26
- data/lib/erbcop/cli.rb +0 -49
- data/lib/erbcop/erb_corrector.rb +0 -42
- data/lib/erbcop/erb_offense_collector.rb +0 -46
- data/lib/erbcop/offense.rb +0 -75
- data/lib/erbcop/path_finder.rb +0 -35
- data/lib/erbcop/rubo_cop_config_generator.rb +0 -65
- data/lib/erbcop/ruby_clipper.rb +0 -93
- data/lib/erbcop/ruby_offense_collector.rb +0 -50
- data/lib/erbcop/runner.rb +0 -115
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f9f5330f08da6f5c0f830990aa71a99dd28a26c298225daac38d7e093e23e9b
|
4
|
+
data.tar.gz: dc59cbbe140b340162018f7ad8201ce1dcf93723e917b18b28d2ed95e22bf737
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfe447c8f1063d4ca7a80f8d8ae27b999de085c98326185b5ba59e74ca7b8d02fef2a9ad3cf92f9d0013f2f4970befcc38ece49b328fbb47ef87c9e0b082cd48
|
7
|
+
data.tar.gz: 5bfa9369536dc698dfee9d32df8a8ce893f2fcf663ec2644f1b0f4f2fb38b8da088f95519f206031c808560339a9d4746b613c8f0122a9cffa9b30050d189bbd
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,30 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 0.4.0 - 2022-01-22
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
|
9
|
+
- Disable Style/NestedTernaryOperator by default.
|
10
|
+
|
11
|
+
## 0.3.0 - 2022-01-22
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
|
15
|
+
- Disable Style/MultilineTernaryOperator by default.
|
16
|
+
|
17
|
+
## 0.2.1 - 2022-01-22
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
|
21
|
+
- Exclude code in ERB comment.
|
22
|
+
|
23
|
+
## 0.2.0 - 2022-01-15
|
24
|
+
|
25
|
+
### Changed
|
26
|
+
|
27
|
+
- Use templatecop.
|
28
|
+
|
5
29
|
## 0.1.0 - 2022-01-15
|
6
30
|
|
7
31
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
erbcop (0.
|
4
|
+
erbcop (0.4.0)
|
5
5
|
better_html
|
6
|
-
|
7
|
-
rubocop (>= 0.87)
|
6
|
+
templatecop
|
8
7
|
|
9
8
|
GEM
|
10
9
|
remote: https://rubygems.org/
|
@@ -84,6 +83,10 @@ GEM
|
|
84
83
|
rubocop (~> 1.19)
|
85
84
|
ruby-progressbar (1.11.0)
|
86
85
|
smart_properties (1.17.0)
|
86
|
+
templatecop (0.2.0)
|
87
|
+
parallel
|
88
|
+
parser
|
89
|
+
rubocop (>= 0.87)
|
87
90
|
tzinfo (2.0.4)
|
88
91
|
concurrent-ruby (~> 1.0)
|
89
92
|
unicode-display_width (2.1.0)
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Erbcop
|
2
2
|
|
3
|
+
[](https://rubygems.org/gems/erbcop)
|
3
4
|
[](https://github.com/r7kamura/erbcop/actions/workflows/test.yml)
|
4
5
|
|
5
6
|
[RuboCop](https://github.com/rubocop/rubocop) runner for ERB template.
|
data/default.yml
CHANGED
data/erbcop.gemspec
CHANGED
data/exe/erbcop
CHANGED
@@ -3,5 +3,12 @@
|
|
3
3
|
|
4
4
|
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
5
5
|
require 'erbcop'
|
6
|
+
require 'templatecop'
|
6
7
|
|
7
|
-
|
8
|
+
Templatecop::Cli.call(
|
9
|
+
default_configuration_path: File.expand_path('../default.yml', __dir__),
|
10
|
+
default_path_patterns: %w[**/*.erb],
|
11
|
+
executable_name: 'erbcop',
|
12
|
+
implicit_configuration_paths: %w[.erbcop.yml .rubocop.yml],
|
13
|
+
ruby_extractor: Erbcop::RubyExtractor
|
14
|
+
)
|
@@ -2,10 +2,25 @@
|
|
2
2
|
|
3
3
|
require 'better_html'
|
4
4
|
require 'better_html/parser'
|
5
|
+
require 'templatecop'
|
5
6
|
|
6
7
|
module Erbcop
|
7
8
|
# Extract Ruby codes from Erb source.
|
8
9
|
class RubyExtractor
|
10
|
+
class << self
|
11
|
+
# @param [String, nil] file_path
|
12
|
+
# @param [String] source
|
13
|
+
def call(
|
14
|
+
file_path:,
|
15
|
+
source:
|
16
|
+
)
|
17
|
+
new(
|
18
|
+
file_path: file_path,
|
19
|
+
source: source
|
20
|
+
).call
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
9
24
|
# @param [String, nil] file_path
|
10
25
|
# @param [String] source
|
11
26
|
def initialize(file_path:, source:)
|
@@ -17,7 +32,7 @@ module Erbcop
|
|
17
32
|
def call
|
18
33
|
nodes.map do |node|
|
19
34
|
snippet = node.children.first
|
20
|
-
clipped = RubyClipper.new(snippet).call
|
35
|
+
clipped = ::Templatecop::RubyClipper.new(snippet).call
|
21
36
|
{
|
22
37
|
code: clipped[:code],
|
23
38
|
offset: node.location.begin_pos + clipped[:offset]
|
@@ -27,36 +42,29 @@ module Erbcop
|
|
27
42
|
|
28
43
|
private
|
29
44
|
|
45
|
+
# @return [Array<BetterHtml::AST::Node>]
|
46
|
+
def erbs
|
47
|
+
root.descendants(:erb).reject do |erb|
|
48
|
+
erb.children.first&.type == :indicator && erb.children.first&.to_a&.first == '#'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
30
52
|
# @return [Enumerator<BetterHtml::AST::Node>]
|
31
53
|
def nodes
|
54
|
+
erbs.flat_map do |erb|
|
55
|
+
erb.descendants(:code).to_a
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [BetterHtml::AST::Node]
|
60
|
+
def root
|
32
61
|
::BetterHtml::Parser.new(
|
33
62
|
::Parser::Source::Buffer.new(
|
34
63
|
@file_path,
|
35
64
|
source: @source
|
36
65
|
),
|
37
66
|
template_language: :html
|
38
|
-
).ast
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [Array<Array<Integer>>]
|
42
|
-
def ranges
|
43
|
-
result = []
|
44
|
-
traverse(ast) do |begin_, end_|
|
45
|
-
result << [begin_, end_]
|
46
|
-
end
|
47
|
-
result
|
48
|
-
end
|
49
|
-
|
50
|
-
def traverse(node, &block)
|
51
|
-
return unless node.instance_of?(::Array)
|
52
|
-
|
53
|
-
if node[0] == :erbi && node[1] == :position
|
54
|
-
block.call(node[2], node[3])
|
55
|
-
else
|
56
|
-
node.each do |element|
|
57
|
-
traverse(element, &block)
|
58
|
-
end
|
59
|
-
end
|
67
|
+
).ast
|
60
68
|
end
|
61
69
|
end
|
62
70
|
end
|
data/lib/erbcop/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erbcop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.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: 2022-01-
|
11
|
+
date: 2022-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: better_html
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: templatecop
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rubocop
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0.87'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0.87'
|
55
41
|
description:
|
56
42
|
email:
|
57
43
|
- r7kamura@gmail.com
|
@@ -73,16 +59,7 @@ files:
|
|
73
59
|
- erbcop.gemspec
|
74
60
|
- exe/erbcop
|
75
61
|
- lib/erbcop.rb
|
76
|
-
- lib/erbcop/cli.rb
|
77
|
-
- lib/erbcop/erb_corrector.rb
|
78
|
-
- lib/erbcop/erb_offense_collector.rb
|
79
|
-
- lib/erbcop/offense.rb
|
80
|
-
- lib/erbcop/path_finder.rb
|
81
|
-
- lib/erbcop/rubo_cop_config_generator.rb
|
82
|
-
- lib/erbcop/ruby_clipper.rb
|
83
62
|
- lib/erbcop/ruby_extractor.rb
|
84
|
-
- lib/erbcop/ruby_offense_collector.rb
|
85
|
-
- lib/erbcop/runner.rb
|
86
63
|
- lib/erbcop/version.rb
|
87
64
|
homepage: https://github.com/r7kamura/erbcop
|
88
65
|
licenses:
|
data/lib/erbcop/cli.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rainbow'
|
4
|
-
require 'rubocop'
|
5
|
-
|
6
|
-
module Erbcop
|
7
|
-
class Cli
|
8
|
-
def initialize(argv)
|
9
|
-
@argv = argv.dup
|
10
|
-
end
|
11
|
-
|
12
|
-
def call
|
13
|
-
options = parse!
|
14
|
-
formatter = ::RuboCop::Formatter::ProgressFormatter.new($stdout, color: options[:color])
|
15
|
-
rubocop_config = RuboCopConfigGenerator.new(additional_config_file_path: options[:additional_config_file_path]).call
|
16
|
-
file_paths = PathFinder.new(patterns: @argv).call
|
17
|
-
|
18
|
-
offenses = Runner.new(
|
19
|
-
auto_correct: options[:auto_correct],
|
20
|
-
file_paths: file_paths,
|
21
|
-
formatter: formatter,
|
22
|
-
rubocop_config: rubocop_config
|
23
|
-
).call
|
24
|
-
|
25
|
-
exit(offenses.empty? ? 0 : 1)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# @return [Hash]
|
31
|
-
def parse!
|
32
|
-
options = {}
|
33
|
-
parser = ::OptionParser.new
|
34
|
-
parser.banner = 'Usage: erbcop [options] [file1, file2, ...]'
|
35
|
-
parser.version = VERSION
|
36
|
-
parser.on('-a', '--auto-correct', 'Auto-correct offenses.') do
|
37
|
-
options[:auto_correct] = true
|
38
|
-
end
|
39
|
-
parser.on('-c', '--config=', 'Specify configuration file. (default: .erbcop.yml or .rubocop.yml)') do |file_path|
|
40
|
-
options[:additional_config_file_path] = file_path
|
41
|
-
end
|
42
|
-
parser.on('--[no-]color', 'Force color output on or off.') do |value|
|
43
|
-
options[:color] = value
|
44
|
-
end
|
45
|
-
parser.parse!(@argv)
|
46
|
-
options
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
data/lib/erbcop/erb_corrector.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'parser'
|
4
|
-
require 'rubocop/cop/legacy/corrector'
|
5
|
-
|
6
|
-
module Erbcop
|
7
|
-
# Apply auto-corrections to Erb file.
|
8
|
-
class ErbCorrector
|
9
|
-
# @param [String] file_path
|
10
|
-
# @param [Array<Erbcop::Offense>] offenses
|
11
|
-
# @param [String] source
|
12
|
-
def initialize(file_path:, offenses:, source:)
|
13
|
-
@file_path = file_path
|
14
|
-
@offenses = offenses
|
15
|
-
@source = source
|
16
|
-
end
|
17
|
-
|
18
|
-
# @return [String] Rewritten Erb code.
|
19
|
-
def call
|
20
|
-
::RuboCop::Cop::Legacy::Corrector.new(source_buffer, corrections).rewrite
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
# @return [Array<Proc>]
|
26
|
-
def corrections
|
27
|
-
@offenses.select(&:corrector).map do |offense|
|
28
|
-
lambda do |corrector|
|
29
|
-
corrector.import!(offense.corrector, offset: offense.offset)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# @return [Parser::Source::Buffer]
|
35
|
-
def source_buffer
|
36
|
-
::Parser::Source::Buffer.new(
|
37
|
-
@file_path,
|
38
|
-
source: @source
|
39
|
-
)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Erbcop
|
4
|
-
# Collect RuboCop offenses from Erb code.
|
5
|
-
class ErbOffenseCollector
|
6
|
-
# @param [Boolean] auto_correct
|
7
|
-
# @param [String] file_path Erb file path
|
8
|
-
# @param [RuboCop::Config] rubocop_config
|
9
|
-
# @param [String] source Erb code
|
10
|
-
def initialize(auto_correct:, file_path:, rubocop_config:, source:)
|
11
|
-
@auto_correct = auto_correct
|
12
|
-
@file_path = file_path
|
13
|
-
@rubocop_config = rubocop_config
|
14
|
-
@source = source
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [Array<Erbcop::Offense>]
|
18
|
-
def call
|
19
|
-
snippets.flat_map do |snippet|
|
20
|
-
RubyOffenseCollector.new(
|
21
|
-
auto_correct: @auto_correct,
|
22
|
-
file_path: @file_path,
|
23
|
-
rubocop_config: @rubocop_config,
|
24
|
-
source: snippet[:code]
|
25
|
-
).call.map do |rubocop_offense|
|
26
|
-
Offense.new(
|
27
|
-
file_path: @file_path,
|
28
|
-
offset: snippet[:offset],
|
29
|
-
rubocop_offense: rubocop_offense,
|
30
|
-
source: @source
|
31
|
-
)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
# @return [Array<Hash>]
|
39
|
-
def snippets
|
40
|
-
RubyExtractor.new(
|
41
|
-
file_path: @file_path,
|
42
|
-
source: @source
|
43
|
-
).call
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/lib/erbcop/offense.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
|
5
|
-
require 'parser'
|
6
|
-
require 'rubocop'
|
7
|
-
|
8
|
-
module Erbcop
|
9
|
-
class Offense
|
10
|
-
extend ::Forwardable
|
11
|
-
|
12
|
-
# @return [String]
|
13
|
-
attr_reader :file_path
|
14
|
-
|
15
|
-
# @return [Integer]
|
16
|
-
attr_reader :offset
|
17
|
-
|
18
|
-
delegate(
|
19
|
-
%i[
|
20
|
-
column
|
21
|
-
column_length
|
22
|
-
correctable?
|
23
|
-
corrected_with_todo?
|
24
|
-
corrected?
|
25
|
-
corrector
|
26
|
-
highlighted_area
|
27
|
-
line
|
28
|
-
message
|
29
|
-
real_column
|
30
|
-
severity
|
31
|
-
] => :rubocop_offense_with_real_location
|
32
|
-
)
|
33
|
-
|
34
|
-
# @param [Integer] offset
|
35
|
-
# @param [RuboCop::Cop::Offense] rubocop_offense
|
36
|
-
# @param [String] source Erb code.
|
37
|
-
def initialize(file_path:, offset:, rubocop_offense:, source:)
|
38
|
-
@file_path = file_path
|
39
|
-
@offset = offset
|
40
|
-
@rubocop_offense = rubocop_offense
|
41
|
-
@source = source
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [Parser::Source::Range]
|
45
|
-
def location
|
46
|
-
@location ||= ::Parser::Source::Range.new(
|
47
|
-
buffer,
|
48
|
-
@rubocop_offense.location.begin_pos + @offset,
|
49
|
-
@rubocop_offense.location.end_pos + @offset
|
50
|
-
)
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
# @return [Parser::Source::Buffer]
|
56
|
-
def buffer
|
57
|
-
::Parser::Source::Buffer.new(
|
58
|
-
file_path,
|
59
|
-
source: @source
|
60
|
-
)
|
61
|
-
end
|
62
|
-
|
63
|
-
# @return [RuboCop::Cop::Offense]
|
64
|
-
def rubocop_offense_with_real_location
|
65
|
-
::RuboCop::Cop::Offense.new(
|
66
|
-
@rubocop_offense.severity.name,
|
67
|
-
location,
|
68
|
-
@rubocop_offense.message,
|
69
|
-
@rubocop_offense.cop_name,
|
70
|
-
@rubocop_offense.status,
|
71
|
-
@rubocop_offense.corrector
|
72
|
-
)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
data/lib/erbcop/path_finder.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'pathname'
|
4
|
-
|
5
|
-
module Erbcop
|
6
|
-
# Collect file paths from given path patterns.
|
7
|
-
class PathFinder
|
8
|
-
DEFAULT_PATH_PATTERNS = %w[
|
9
|
-
**/*.erb
|
10
|
-
].freeze
|
11
|
-
|
12
|
-
# @param [Array<String>] patterns Patterns normally given as CLI arguments (e.g. `["app/views/**/*.html.erb"]`).
|
13
|
-
def initialize(patterns:)
|
14
|
-
@patterns = patterns
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [Array<String>]
|
18
|
-
def call
|
19
|
-
patterns.flat_map do |pattern|
|
20
|
-
::Pathname.glob(pattern).select(&:file?).map(&:to_s)
|
21
|
-
end.uniq.sort
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
# @return [Array<String>]
|
27
|
-
def patterns
|
28
|
-
if @patterns.empty?
|
29
|
-
DEFAULT_PATH_PATTERNS
|
30
|
-
else
|
31
|
-
@patterns
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module Erbcop
|
6
|
-
class RuboCopConfigGenerator
|
7
|
-
DEFAULT_ADDITIONAL_CONFIG_PATH1 = '.erbcop.yml'
|
8
|
-
DEFAULT_ADDITIONAL_CONFIG_PATH2 = '.rubocop.yml'
|
9
|
-
|
10
|
-
# @param [String] additional_config_file_path
|
11
|
-
def initialize(additional_config_file_path: nil)
|
12
|
-
@additional_config_file_path = additional_config_file_path
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [RuboCop::Config]
|
16
|
-
def call
|
17
|
-
::RuboCop::ConfigLoader.merge_with_default(merged_config, loaded_path)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
# @return [String]
|
23
|
-
def loaded_path
|
24
|
-
@additional_config_file_path || erbcop_default_config_file_path
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [RuboCop::Config]
|
28
|
-
def merged_config
|
29
|
-
::RuboCop::Config.create(merged_config_hash, loaded_path)
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [Hash]
|
33
|
-
def merged_config_hash
|
34
|
-
result = erbcop_default_config
|
35
|
-
result = ::RuboCop::ConfigLoader.merge(result, additional_config) if additional_config
|
36
|
-
result
|
37
|
-
end
|
38
|
-
|
39
|
-
# @return [RuboCop::Config, nil]
|
40
|
-
def additional_config
|
41
|
-
if instance_variable_defined?(:@additional_config)
|
42
|
-
@additional_config
|
43
|
-
else
|
44
|
-
@additional_config = \
|
45
|
-
if @additional_config_file_path
|
46
|
-
::RuboCop::ConfigLoader.load_file(@additional_config_file_path)
|
47
|
-
elsif ::File.exist?(DEFAULT_ADDITIONAL_CONFIG_PATH1)
|
48
|
-
::RuboCop::ConfigLoader.load_file(DEFAULT_ADDITIONAL_CONFIG_PATH1)
|
49
|
-
elsif ::File.exist?(DEFAULT_ADDITIONAL_CONFIG_PATH2)
|
50
|
-
::RuboCop::ConfigLoader.load_file(DEFAULT_ADDITIONAL_CONFIG_PATH2)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# @return [RuboCop::Config]
|
56
|
-
def erbcop_default_config
|
57
|
-
::RuboCop::ConfigLoader.load_file(erbcop_default_config_file_path)
|
58
|
-
end
|
59
|
-
|
60
|
-
# @return [String]
|
61
|
-
def erbcop_default_config_file_path
|
62
|
-
@erbcop_default_config_file_path ||= ::File.expand_path('../../default.yml', __dir__)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
data/lib/erbcop/ruby_clipper.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Erbcop
|
4
|
-
# Remove unnecessary part (e.g. `if`, `unless`, `do`, ...) from Ruby code.
|
5
|
-
class RubyClipper
|
6
|
-
# @param [String] code
|
7
|
-
def initialize(code)
|
8
|
-
@code = code
|
9
|
-
end
|
10
|
-
|
11
|
-
# @return [Hash]
|
12
|
-
def call
|
13
|
-
[
|
14
|
-
PrecedingKeywordRemover,
|
15
|
-
TrailingDoRemover
|
16
|
-
].each_with_object(
|
17
|
-
code: @code,
|
18
|
-
offset: 0
|
19
|
-
) do |klass, object|
|
20
|
-
result = klass.new(object[:code]).call
|
21
|
-
object[:code] = result[:code]
|
22
|
-
object[:offset] += result[:offset]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class PrecedingKeywordRemover
|
27
|
-
REGEXP = /
|
28
|
-
\A
|
29
|
-
(?:
|
30
|
-
begin
|
31
|
-
| case
|
32
|
-
| else
|
33
|
-
| elsif
|
34
|
-
| ensure
|
35
|
-
| if
|
36
|
-
| rescue
|
37
|
-
| unless
|
38
|
-
| until
|
39
|
-
| when
|
40
|
-
| while
|
41
|
-
| for[ \t]+\w+[ \t]+in
|
42
|
-
)
|
43
|
-
[ \t]
|
44
|
-
/x.freeze
|
45
|
-
|
46
|
-
# @param [String] code
|
47
|
-
def initialize(code)
|
48
|
-
@code = code
|
49
|
-
end
|
50
|
-
|
51
|
-
# @return [Hash]
|
52
|
-
def call
|
53
|
-
data = @code.match(REGEXP)
|
54
|
-
if data
|
55
|
-
offset = data[0].length
|
56
|
-
{
|
57
|
-
code: @code[offset..],
|
58
|
-
offset: offset
|
59
|
-
}
|
60
|
-
else
|
61
|
-
{
|
62
|
-
code: @code,
|
63
|
-
offset: 0
|
64
|
-
}
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class TrailingDoRemover
|
70
|
-
REGEXP = /
|
71
|
-
[ \t]
|
72
|
-
do
|
73
|
-
[ \t]*
|
74
|
-
(\|[^|]*\|)?
|
75
|
-
[ \t]*
|
76
|
-
\Z
|
77
|
-
/x.freeze
|
78
|
-
|
79
|
-
# @param [String] code
|
80
|
-
def initialize(code)
|
81
|
-
@code = code
|
82
|
-
end
|
83
|
-
|
84
|
-
# @return [Hash]
|
85
|
-
def call
|
86
|
-
{
|
87
|
-
code: @code.sub(REGEXP, ''),
|
88
|
-
offset: 0
|
89
|
-
}
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module Erbcop
|
6
|
-
# Collect RuboCop offenses from Ruby code.
|
7
|
-
class RubyOffenseCollector
|
8
|
-
# @param [Boolean] auto_correct
|
9
|
-
# @param [String] file_path
|
10
|
-
# @param [RuboCop::Config] rubocop_config
|
11
|
-
# @param [String] source
|
12
|
-
def initialize(auto_correct:, file_path:, rubocop_config:, source:)
|
13
|
-
@auto_correct = auto_correct
|
14
|
-
@file_path = file_path
|
15
|
-
@rubocop_config = rubocop_config
|
16
|
-
@source = source
|
17
|
-
end
|
18
|
-
|
19
|
-
# @return [Array<RuboCop::Cop::Offense>]
|
20
|
-
def call
|
21
|
-
# Skip if invalid syntax Ruby code is given. (e.g. "- if a?")
|
22
|
-
return [] unless rubocop_processed_source.valid_syntax?
|
23
|
-
|
24
|
-
rubocop_team.investigate(rubocop_processed_source).offenses.reject(&:disabled?)
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# @return [RuboCop::ProcessedSource]
|
30
|
-
def rubocop_processed_source
|
31
|
-
@rubocop_processed_source ||= ::RuboCop::ProcessedSource.new(
|
32
|
-
@source,
|
33
|
-
@rubocop_config.target_ruby_version,
|
34
|
-
@file_path
|
35
|
-
)
|
36
|
-
end
|
37
|
-
|
38
|
-
# @return [RuboCop::Cop::Team]
|
39
|
-
def rubocop_team
|
40
|
-
::RuboCop::Cop::Team.new(
|
41
|
-
::RuboCop::Cop::Registry.new(::RuboCop::Cop::Cop.all),
|
42
|
-
@rubocop_config,
|
43
|
-
auto_correct: @auto_correct,
|
44
|
-
display_cop_names: true,
|
45
|
-
extra_details: true,
|
46
|
-
stdin: ''
|
47
|
-
)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
data/lib/erbcop/runner.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Erbcop
|
4
|
-
# Run investigation and auto-correcttion.
|
5
|
-
class Runner
|
6
|
-
# @param [Boolean] auto_correct
|
7
|
-
# @param [Array<String>] file_paths
|
8
|
-
# @param [Object] formatter
|
9
|
-
# @param [RuboCop::Config] rubocop_config
|
10
|
-
def initialize(
|
11
|
-
auto_correct:,
|
12
|
-
file_paths:,
|
13
|
-
formatter:,
|
14
|
-
rubocop_config:
|
15
|
-
)
|
16
|
-
@auto_correct = auto_correct
|
17
|
-
@file_paths = file_paths
|
18
|
-
@formatter = formatter
|
19
|
-
@rubocop_config = rubocop_config
|
20
|
-
end
|
21
|
-
|
22
|
-
# @return [Array<RuboCop::Cop::Offense>]
|
23
|
-
def call
|
24
|
-
on_started
|
25
|
-
offenses = investigate_and_correct
|
26
|
-
on_finished
|
27
|
-
offenses
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
# @param [String] file_path
|
33
|
-
# @param [Array<Erbcop::Offense>] offenses
|
34
|
-
# @param [String] source
|
35
|
-
def correct(file_path:, offenses:, source:)
|
36
|
-
rewritten_source = ErbCorrector.new(
|
37
|
-
file_path: file_path,
|
38
|
-
offenses: offenses,
|
39
|
-
source: source
|
40
|
-
).call
|
41
|
-
::File.write(file_path, rewritten_source)
|
42
|
-
end
|
43
|
-
|
44
|
-
# @param [Boolean] auto_correct
|
45
|
-
# @param [String] file_path
|
46
|
-
# @param [String] rubocop_config
|
47
|
-
# @param [String] source
|
48
|
-
# @return [Array<Erbcop::Offense>]
|
49
|
-
def investigate(auto_correct:, file_path:, rubocop_config:, source:)
|
50
|
-
ErbOffenseCollector.new(
|
51
|
-
auto_correct: auto_correct,
|
52
|
-
file_path: file_path,
|
53
|
-
rubocop_config: rubocop_config,
|
54
|
-
source: source
|
55
|
-
).call
|
56
|
-
end
|
57
|
-
|
58
|
-
# @return [Array<RuboCop::Cop::Offense>]
|
59
|
-
def investigate_and_correct
|
60
|
-
@file_paths.flat_map do |file_path|
|
61
|
-
offenses_per_file = []
|
62
|
-
max_trials_count.times do
|
63
|
-
on_file_started(file_path)
|
64
|
-
source = ::File.read(file_path)
|
65
|
-
offenses = investigate(
|
66
|
-
auto_correct: @auto_correct,
|
67
|
-
file_path: file_path,
|
68
|
-
rubocop_config: @rubocop_config,
|
69
|
-
source: source
|
70
|
-
)
|
71
|
-
offenses_per_file += offenses
|
72
|
-
break if offenses.empty?
|
73
|
-
|
74
|
-
next unless @auto_correct
|
75
|
-
|
76
|
-
correct(
|
77
|
-
file_path: file_path,
|
78
|
-
offenses: offenses,
|
79
|
-
source: source
|
80
|
-
)
|
81
|
-
end
|
82
|
-
on_file_finished(file_path, offenses_per_file)
|
83
|
-
offenses_per_file
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# @return [Integer]
|
88
|
-
def max_trials_count
|
89
|
-
if @auto_correct
|
90
|
-
7 # What a heuristic number.
|
91
|
-
else
|
92
|
-
1
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def on_started
|
97
|
-
@formatter.started(@file_paths)
|
98
|
-
end
|
99
|
-
|
100
|
-
# @param [String] file_path
|
101
|
-
def on_file_started(file_path)
|
102
|
-
@formatter.file_started(file_path, {})
|
103
|
-
end
|
104
|
-
|
105
|
-
# @param [String] file_path
|
106
|
-
# @param [Array<RuboCop::Cop::Offenses]
|
107
|
-
def on_file_finished(file_path, offenses)
|
108
|
-
@formatter.file_finished(file_path, offenses)
|
109
|
-
end
|
110
|
-
|
111
|
-
def on_finished
|
112
|
-
@formatter.finished(@file_paths)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|