slimembedcop 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codespellignore +0 -0
- data/.rubocop.yml +0 -2
- data/CHANGELOG.md +10 -0
- data/README.md +96 -2
- data/Rakefile +5 -3
- data/exe/slimembedcop +3 -3
- data/lib/default.yml +10 -4
- data/lib/slimembedcop/cli.rb +11 -34
- data/lib/slimembedcop/config_generator.rb +41 -40
- data/lib/slimembedcop/extractor.rb +37 -40
- data/lib/slimembedcop/offense.rb +3 -3
- data/lib/slimembedcop/offense_collector.rb +16 -10
- data/lib/slimembedcop/option.rb +28 -0
- data/lib/slimembedcop/path_finder.rb +32 -33
- data/lib/slimembedcop/ruby_offense_collector.rb +38 -31
- data/lib/slimembedcop/runner.rb +61 -57
- data/lib/slimembedcop/template_corrector.rb +6 -6
- data/lib/slimembedcop/version.rb +1 -1
- data/lib/slimembedcop.rb +11 -10
- data/slimembedcop.gemspec +15 -15
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 819399a1940beed5d69493debeb14cc9ca337274d4c94a015aa4fa7cb4a61576
|
4
|
+
data.tar.gz: a9513d7bcc2b2df861fa0b9509542ef83f2b7caa4757d9a986d626d2305ce5d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b193c4391dadc3d800d2a9b6ae62dad2d0ce3e52450e3c292a7f30971bc82b622ce268d7b5a15e59d36c9ab627d7b476971d5cf4158e7e4ede005e4458b50fbb
|
7
|
+
data.tar.gz: 38dec3b0af1d1d4702297a6f0cdb01732ff9075fa2aa48258c5588b8e0caffc4f1b493956a3c8d4efc71d70dae502fb9808aa7c1dcacea47cdf7c002fcc29521
|
data/.codespellignore
ADDED
File without changes
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 1.0.0 - 2024-11-29
|
4
|
+
|
5
|
+
- Fix warnings for use of `Team.new`.
|
6
|
+
|
7
|
+
## 0.2.0 - 2023-09-16
|
8
|
+
|
9
|
+
- Disable unnecessary cop for slimembedcop.
|
10
|
+
- Add `--debug` option.
|
11
|
+
- Remove .rubocop.yml for default implicit config path.
|
12
|
+
|
3
13
|
## 0.1.0 - 2023-09-07
|
4
14
|
|
5
15
|
- Initial release
|
data/README.md
CHANGED
@@ -1,6 +1,100 @@
|
|
1
|
-
#
|
1
|
+
# SlimEmbedCop
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/slimembedcop.svg)](https://badge.fury.io/rb/slimembedcop)
|
4
|
+
[![CI](https://github.com/ydah/slimembedcop/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/slimembedcop/actions/workflows/ci.yml)
|
5
|
+
[![RubyDoc](https://img.shields.io/badge/%F0%9F%93%9ARubyDoc-documentation-informational.svg)](https://www.rubydoc.info/gems/slimembedcop)
|
6
|
+
|
7
|
+
|
8
|
+
[RuboCop](https://github.com/rubocop/rubocop) runner for [Ruby code embedded in Slim](https://github.com/slim-template/slim#embedded-engines-markdown-).
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
**SlimEmbedCop**'s installation is pretty standard:
|
13
|
+
|
14
|
+
```sh
|
15
|
+
% gem install slimembedcop
|
16
|
+
```
|
17
|
+
|
18
|
+
If you'd rather install SlimEmbedCop using `bundler`, add a line for it in your `Gemfile` (but set the `require` option to `false`, as it is a standalone tool):
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'slimembedcop', require: false
|
22
|
+
```
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
Use `slimembedcop` executable to check offenses and autocorrect them.
|
27
|
+
[RuboCop's cop](https://docs.rubocop.org/rubocop/1.56/cops.html) or any [custom cop](https://docs.rubocop.org/rubocop/extensions.html#custom-cops) you create can also be used with `slimembedcop`.
|
28
|
+
|
29
|
+
```sh
|
30
|
+
% exe/slimembedcop --help
|
31
|
+
Usage: slimembedcop [options] [file1, file2, ...]
|
32
|
+
-v, --version Display version.
|
33
|
+
-a, --autocorrect Autocorrect offenses.
|
34
|
+
-c, --config= Specify configuration file.
|
35
|
+
--[no-]color Force color output on or off.
|
36
|
+
-d, --debug Display debug info.
|
37
|
+
```
|
38
|
+
|
39
|
+
### Example
|
40
|
+
|
41
|
+
You have a Slim file like this:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
ruby:
|
45
|
+
message = "world"
|
46
|
+
html
|
47
|
+
head
|
48
|
+
title Slim Samples
|
49
|
+
body
|
50
|
+
ruby:
|
51
|
+
if some_var = true
|
52
|
+
do_something
|
53
|
+
end
|
54
|
+
h1 Hello, #{message}
|
55
|
+
ruby:
|
56
|
+
do_something /pattern/i
|
57
|
+
```
|
58
|
+
|
59
|
+
When executed, it outputs the following offenses:
|
60
|
+
|
61
|
+
```sh
|
62
|
+
% slimembedcop dummy.slim
|
63
|
+
Inspecting 1 file
|
64
|
+
W
|
65
|
+
|
66
|
+
Offenses:
|
67
|
+
|
68
|
+
dummy.slim:2:13: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
|
69
|
+
message = "world"
|
70
|
+
^^^^^^^
|
71
|
+
dummy.slim:8:19: W: [Correctable] Lint/AssignmentInCondition: Use == if you meant to do a comparison or wrap the expression in parentheses to indicate you meant to assign in a condition.
|
72
|
+
if some_var = true
|
73
|
+
^
|
74
|
+
dummy.slim:13:16: W: [Correctable] Lint/AmbiguousRegexpLiteral: Ambiguous regexp literal. Parenthesize the method arguments if it's surely a regexp literal, or add a whitespace to the right of the / if it should be a division.
|
75
|
+
do_something /pattern/i
|
76
|
+
^
|
77
|
+
|
78
|
+
1 file inspected, 3 offenses detected, 3 offenses autocorrectable
|
79
|
+
```
|
80
|
+
|
81
|
+
## Configuration
|
82
|
+
|
83
|
+
The behavior of [RuboCop](https://github.com/rubocop/rubocop) can be controlled via the [.rubocop.yml](https://github.com/rubocop/rubocop/blob/master/.rubocop.yml) configuration file. The behavior of `SlimEmbedCop` can be controlled by the `.slimembedcop.yml` configuration file. It makes it possible to enable/disable certain cops (checks) and to alter their behavior if they accept any parameters. The file can be placed in your home directory, XDG config directory, or in some project directory.
|
84
|
+
|
85
|
+
The file has the following format:
|
86
|
+
|
87
|
+
```yaml
|
88
|
+
inherit_from: ../.rubocop.yml
|
89
|
+
|
90
|
+
Style/Encoding:
|
91
|
+
Enabled: false
|
92
|
+
|
93
|
+
Layout/LineLength:
|
94
|
+
Max: 99
|
95
|
+
```
|
96
|
+
|
97
|
+
NOTE: It is basically the same as RuboCop's. Please check [Configuration](https://docs.rubocop.org/rubocop/configuration.html) for details.
|
4
98
|
|
5
99
|
## License
|
6
100
|
|
data/Rakefile
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
5
6
|
|
6
7
|
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
RuboCop::RakeTask.new
|
7
9
|
|
8
|
-
task default: %i[spec]
|
10
|
+
task default: %i[spec rubocop]
|
data/exe/slimembedcop
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
$LOAD_PATH.unshift File.expand_path(
|
5
|
-
require
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
5
|
+
require 'slimembedcop'
|
6
6
|
|
7
|
-
exit Slimembedcop::Cli.
|
7
|
+
exit Slimembedcop::Cli.new(ARGV).run
|
data/lib/default.yml
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
Style/FrozenStringLiteralComment:
|
2
|
-
Enabled: false
|
3
1
|
Layout/TrailingEmptyLines:
|
4
2
|
Enabled: false
|
3
|
+
|
5
4
|
Layout/InitialIndentation:
|
6
5
|
Enabled: false
|
7
|
-
|
8
|
-
|
6
|
+
|
7
|
+
Lint/UselessAssignment:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Naming/FileName:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/FrozenStringLiteralComment:
|
14
|
+
Enabled: false
|
data/lib/slimembedcop/cli.rb
CHANGED
@@ -1,44 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require "rubocop"
|
3
|
+
require 'rubocop'
|
5
4
|
|
6
5
|
module Slimembedcop
|
7
6
|
# Command line interface for Slimembedcop.
|
8
7
|
class Cli
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def run(argv)
|
14
|
-
options = parse_options!(argv)
|
15
|
-
formatter = ::RuboCop::Formatter::ProgressFormatter.new($stdout, color: options[:color])
|
16
|
-
config = ConfigGenerator.run(DEFAULT_CONFIG_PATH, options[:forced_config_path])
|
17
|
-
paths = PathFinder.run(DEFAULT_PATH_PATTERNS, config.for_all_cops["Exclude"], argv)
|
18
|
-
offenses = Runner.run(paths, formatter, config, options[:autocorrect])
|
19
|
-
exit(offenses.empty? ? 0 : 1)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
8
|
+
def initialize(argv)
|
9
|
+
@argv = argv
|
10
|
+
end
|
23
11
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
options[:autocorrect] = true
|
32
|
-
end
|
33
|
-
parser.on("-c", "--config=", "Specify configuration file. (default: #{DEFAULT_CONFIG_PATH} or .rubocop.yml)") do |file_path|
|
34
|
-
options[:forced_config_path] = file_path
|
35
|
-
end
|
36
|
-
parser.on("--[no-]color", "Force color output on or off.") do |value|
|
37
|
-
options[:color] = value
|
38
|
-
end
|
39
|
-
parser.parse!(argv)
|
40
|
-
options
|
41
|
-
end
|
12
|
+
def run
|
13
|
+
options = Option.new(@argv)
|
14
|
+
formatter = ::RuboCop::Formatter::ProgressFormatter.new($stdout, color: options.color)
|
15
|
+
config = ConfigGenerator.new(options).run
|
16
|
+
paths = PathFinder.new(options, config).run
|
17
|
+
offenses = Runner.new(paths, formatter, options, config).run
|
18
|
+
exit(offenses.empty? ? 0 : 1)
|
42
19
|
end
|
43
20
|
end
|
44
21
|
end
|
@@ -1,57 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'rubocop'
|
4
4
|
|
5
5
|
module Slimembedcop
|
6
6
|
# Generates a configuration for RuboCop.
|
7
7
|
class ConfigGenerator
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
::RuboCop::ConfigLoader.merge_with_default(merged_config, loaded_path)
|
13
|
-
end
|
8
|
+
def initialize(option)
|
9
|
+
@default_config_path = option.default_config_path
|
10
|
+
@forced_config_path = option.forced_config_path
|
11
|
+
end
|
14
12
|
|
15
|
-
|
13
|
+
def run
|
14
|
+
::RuboCop::ConfigLoader.merge_with_default(merged_config, loaded_path)
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
@forced_config_path || implicit_config_path || @default_config_path
|
19
|
-
end
|
17
|
+
private
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def loaded_path
|
20
|
+
@forced_config_path || implicit_config_path || @default_config_path
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
result
|
29
|
-
end
|
23
|
+
def merged_config
|
24
|
+
::RuboCop::Config.create(merged_config_hash, loaded_path)
|
25
|
+
end
|
30
26
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
if @forced_config_path
|
37
|
-
::RuboCop::ConfigLoader.load_file(@forced_config_path)
|
38
|
-
elsif (path = implicit_config_path)
|
39
|
-
::RuboCop::ConfigLoader.load_file(path)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
27
|
+
def merged_config_hash
|
28
|
+
result = default_config
|
29
|
+
result = ::RuboCop::ConfigLoader.merge(result, user_config) if user_config
|
30
|
+
result
|
31
|
+
end
|
43
32
|
|
44
|
-
|
45
|
-
|
33
|
+
def user_config
|
34
|
+
if instance_variable_defined?(:@user_config)
|
35
|
+
@user_config
|
36
|
+
else
|
37
|
+
@user_config =
|
38
|
+
if @forced_config_path
|
39
|
+
::RuboCop::ConfigLoader.load_file(@forced_config_path)
|
40
|
+
elsif (path = implicit_config_path)
|
41
|
+
::RuboCop::ConfigLoader.load_file(path)
|
42
|
+
end
|
46
43
|
end
|
44
|
+
end
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
def default_config
|
47
|
+
::RuboCop::ConfigLoader.load_file(@default_config_path)
|
48
|
+
end
|
49
|
+
|
50
|
+
def implicit_config_path
|
51
|
+
if instance_variable_defined?(:@implicit_config_path)
|
52
|
+
@implicit_config_path
|
53
|
+
else
|
54
|
+
@implicit_config_path = %w[.slimembedcop.yml].find do |path|
|
55
|
+
::File.exist?(path)
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
@@ -1,57 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "slimi"
|
4
|
-
|
5
3
|
module Slimembedcop
|
6
4
|
# Extract Ruby codes from Slim embedded code.
|
7
5
|
class Extractor
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@source = source
|
6
|
+
def initialize(source)
|
7
|
+
@source = source
|
8
|
+
end
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def run
|
11
|
+
ranges.map do |(begin_, end_)|
|
12
|
+
{ code: @source[begin_...end_], offset: begin_ }
|
16
13
|
end
|
14
|
+
end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
if inside_ruby && block_end?(line, leading_spaces)
|
35
|
-
result << [begin_pos, index - 1]
|
36
|
-
inside_ruby = false
|
37
|
-
end
|
38
|
-
|
39
|
-
index += line.length
|
16
|
+
private
|
17
|
+
|
18
|
+
def ranges
|
19
|
+
result = []
|
20
|
+
index = 0
|
21
|
+
begin_pos = 0
|
22
|
+
leading_spaces = 0
|
23
|
+
inside_ruby = false
|
24
|
+
@source.each_line do |line|
|
25
|
+
if block_start?(line)
|
26
|
+
leading_spaces = line.match(/^\s*/)[0].length
|
27
|
+
inside_ruby = true
|
28
|
+
begin_pos = index += line.length
|
29
|
+
next
|
40
30
|
end
|
41
31
|
|
42
|
-
|
32
|
+
if inside_ruby && block_end?(line, leading_spaces)
|
33
|
+
result << [begin_pos, index - 1]
|
34
|
+
inside_ruby = false
|
35
|
+
end
|
43
36
|
|
44
|
-
|
37
|
+
index += line.length
|
45
38
|
end
|
46
39
|
|
47
|
-
|
48
|
-
line.strip.start_with?("ruby:")
|
49
|
-
end
|
40
|
+
result << [begin_pos, index - 1] if inside_ruby
|
50
41
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def block_start?(line)
|
46
|
+
line.strip.start_with?('ruby:')
|
47
|
+
end
|
48
|
+
|
49
|
+
def block_end?(line, leading_spaces)
|
50
|
+
line.match(/^\s{#{leading_spaces}}\S/) ||
|
51
|
+
(leading_spaces.zero? && line.match(/^\S/))
|
55
52
|
end
|
56
53
|
end
|
57
54
|
end
|
data/lib/slimembedcop/offense.rb
CHANGED
@@ -3,20 +3,26 @@
|
|
3
3
|
module Slimembedcop
|
4
4
|
# Collect RuboCop offenses from Template code.
|
5
5
|
class OffenseCollector
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
def initialize(path, config, source, autocorrect, debug)
|
7
|
+
@path = path
|
8
|
+
@config = config
|
9
|
+
@source = source
|
10
|
+
@autocorrect = autocorrect
|
11
|
+
@debug = debug
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
snippets.flat_map do |snippet|
|
16
|
+
RubyOffenseCollector.new(@path, @config, snippet[:code], @autocorrect, @debug).run.map do |offense|
|
17
|
+
Offense.new(@path, snippet[:offset], offense, @source)
|
12
18
|
end
|
13
19
|
end
|
20
|
+
end
|
14
21
|
|
15
|
-
|
22
|
+
private
|
16
23
|
|
17
|
-
|
18
|
-
|
19
|
-
end
|
24
|
+
def snippets
|
25
|
+
Extractor.new(@source).run
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slimembedcop
|
4
|
+
# Command line options.
|
5
|
+
class Option
|
6
|
+
attr_reader :version, :autocorrect, :forced_config_path, :color, :debug,
|
7
|
+
:args, :default_config_path, :default_path_patterns
|
8
|
+
|
9
|
+
def initialize(argv)
|
10
|
+
opt = OptionParser.new
|
11
|
+
@version = false
|
12
|
+
@autocorrect = false
|
13
|
+
@forced_config_path = nil
|
14
|
+
@color = nil
|
15
|
+
@debug = false
|
16
|
+
@default_config_path = File.expand_path('../default.yml', __dir__)
|
17
|
+
@default_path_patterns = %w[**/*.slim].freeze
|
18
|
+
|
19
|
+
opt.banner = 'Usage: slimembedcop [options] [file1, file2, ...]'
|
20
|
+
opt.on('-v', '--version', 'Display version.') { @version = true }
|
21
|
+
opt.on('-a', '--autocorrect', 'Autocorrect offenses.') { @autocorrect = true }
|
22
|
+
opt.on('-c', '--config=', 'Specify configuration file.') { |path| @forced_config_path = path }
|
23
|
+
opt.on('--[no-]color', 'Force color output on or off.') { |value| @color = value }
|
24
|
+
opt.on('-d', '--debug', 'Display debug info.') { |value| @debug = value }
|
25
|
+
@args = opt.parse(argv)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,52 +1,51 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'pathname'
|
4
|
+
require 'set'
|
5
5
|
|
6
6
|
module Slimembedcop
|
7
7
|
# Collect file paths from given path patterns.
|
8
8
|
class PathFinder
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
matching_paths(patterns) do |path|
|
15
|
-
!excluded?(path)
|
16
|
-
end.sort
|
17
|
-
end
|
9
|
+
def initialize(options, config)
|
10
|
+
@default_patterns = options.default_path_patterns
|
11
|
+
@exclude_patterns = config.for_all_cops['Exclude'] || []
|
12
|
+
@path_patterns = options.args
|
13
|
+
end
|
18
14
|
|
19
|
-
|
15
|
+
def run
|
16
|
+
matching_paths(patterns) { |path| !excluded?(path) }.sort
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
patterns.each_with_object(Set.new) do |pattern, set|
|
23
|
-
::Pathname.glob(pattern) do |pathname|
|
24
|
-
next unless pathname.file?
|
19
|
+
private
|
25
20
|
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
def matching_paths(patterns, &block)
|
22
|
+
patterns.each_with_object(Set.new) do |pattern, set|
|
23
|
+
::Pathname.glob(pattern) do |pathname|
|
24
|
+
next unless pathname.file?
|
25
|
+
|
26
|
+
path = pathname.expand_path.to_s
|
27
|
+
set.add(path) if block.nil? || yield(path)
|
29
28
|
end
|
30
29
|
end
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def excluded?(path)
|
33
|
+
excluded.include?(path)
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def excluded
|
37
|
+
@excluded ||= matching_paths(@exclude_patterns)
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
def patterns
|
41
|
+
return @default_patterns if @path_patterns.empty?
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
@path_patterns.map do |pattern|
|
44
|
+
next pattern unless File.directory?(pattern)
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
46
|
+
@default_patterns.map do |default|
|
47
|
+
File.join(pattern, default)
|
48
|
+
end.flatten
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
@@ -1,47 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'rubocop'
|
4
4
|
|
5
5
|
module Slimembedcop
|
6
6
|
# Collect RuboCop offenses from Ruby code.
|
7
7
|
class RubyOffenseCollector
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(path, config, source, autocorrect, debug)
|
9
|
+
@path = path
|
10
|
+
@config = config
|
11
|
+
@source = source
|
12
|
+
@autocorrect = autocorrect
|
13
|
+
@debug = debug
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
16
|
+
def run
|
17
|
+
return [] unless processed_source.valid_syntax?
|
14
18
|
|
15
|
-
|
19
|
+
team.investigate(processed_source).offenses.reject(&:disabled?)
|
20
|
+
end
|
16
21
|
|
17
|
-
|
18
|
-
@registry ||= begin
|
19
|
-
all_cops = if ::RuboCop::Cop::Registry.respond_to?(:all)
|
20
|
-
::RuboCop::Cop::Registry.all
|
21
|
-
else
|
22
|
-
::RuboCop::Cop::Cop.all
|
23
|
-
end
|
22
|
+
private
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
def processed_source
|
25
|
+
::RuboCop::ProcessedSource.new(@source, @config.target_ruby_version, @path).tap do |processed_source|
|
26
|
+
processed_source.config = @config if processed_source.respond_to?(:config)
|
27
|
+
processed_source.registry = registry if processed_source.respond_to?(:registry)
|
27
28
|
end
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
def team
|
32
|
+
::RuboCop::Cop::Team.mobilize(
|
33
|
+
registry,
|
34
|
+
@config,
|
35
|
+
autocorrect: @autocorrect,
|
36
|
+
debug: @debug,
|
37
|
+
display_cop_names: true,
|
38
|
+
extra_details: true,
|
39
|
+
stdin: ''
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def registry
|
44
|
+
@registry ||= begin
|
45
|
+
all_cops = if ::RuboCop::Cop::Registry.respond_to?(:all)
|
46
|
+
::RuboCop::Cop::Registry.all
|
47
|
+
else
|
48
|
+
::RuboCop::Cop::Cop.all
|
49
|
+
end
|
35
50
|
|
36
|
-
|
37
|
-
::RuboCop::Cop::Team.new(
|
38
|
-
registry,
|
39
|
-
config,
|
40
|
-
autocorrect: autocorrect,
|
41
|
-
display_cop_names: true,
|
42
|
-
extra_details: true,
|
43
|
-
stdin: ""
|
44
|
-
)
|
51
|
+
::RuboCop::Cop::Registry.new(all_cops)
|
45
52
|
end
|
46
53
|
end
|
47
54
|
end
|
data/lib/slimembedcop/runner.rb
CHANGED
@@ -1,83 +1,87 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'parallel'
|
4
|
+
require 'stringio'
|
5
5
|
|
6
6
|
module Slimembedcop
|
7
7
|
# Run investigation and auto-correction.
|
8
8
|
class Runner
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
result.flat_map { |(_, offenses)| offenses }
|
17
|
-
end
|
9
|
+
def initialize(paths, formatter, options, config)
|
10
|
+
@paths = paths
|
11
|
+
@formatter = formatter
|
12
|
+
@autocorrect = options.autocorrect
|
13
|
+
@debug = options.debug
|
14
|
+
@config = config
|
15
|
+
end
|
18
16
|
|
19
|
-
|
17
|
+
def run
|
18
|
+
on_started
|
19
|
+
result = run_in_parallel
|
20
|
+
on_finished(result)
|
21
|
+
result.flat_map { |(_, offenses)| offenses }
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
formatter.started(paths)
|
23
|
-
end
|
24
|
+
private
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
max_trials_count.times do
|
29
|
-
on_file_started(formatter, path)
|
30
|
-
source = ::File.read(path)
|
31
|
-
offenses = investigate(path, config, source)
|
32
|
-
offenses_per_file |= offenses
|
33
|
-
break if offenses.none?(&:correctable?)
|
26
|
+
def on_started
|
27
|
+
@formatter.started(@paths)
|
28
|
+
end
|
34
29
|
|
35
|
-
|
30
|
+
def run_in_parallel
|
31
|
+
::Parallel.map(@paths) do |path|
|
32
|
+
offenses_per_file = []
|
33
|
+
max_trials_count.times do
|
34
|
+
on_file_started(path)
|
35
|
+
source = ::File.read(path)
|
36
|
+
offenses = investigate(path, source)
|
37
|
+
offenses_per_file |= offenses
|
38
|
+
break if offenses.none?(&:correctable?)
|
36
39
|
|
37
|
-
|
38
|
-
end
|
40
|
+
next unless @autocorrect
|
39
41
|
|
40
|
-
|
41
|
-
[path, offenses_per_file]
|
42
|
+
correct(path, offenses, source)
|
42
43
|
end
|
43
|
-
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
7
|
48
|
-
else
|
49
|
-
1
|
50
|
-
end
|
45
|
+
on_file_finished(path, offenses_per_file)
|
46
|
+
[path, offenses_per_file]
|
51
47
|
end
|
48
|
+
end
|
52
49
|
|
53
|
-
|
54
|
-
|
50
|
+
def max_trials_count
|
51
|
+
if @autocorrect
|
52
|
+
7
|
53
|
+
else
|
54
|
+
1
|
55
55
|
end
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
58
|
+
def investigate(path, source)
|
59
|
+
OffenseCollector.new(path, @config, source, @autocorrect, @debug).run
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
def correct(path, offenses, source)
|
63
|
+
rewritten_source = TemplateCorrector.new(path, offenses, source).run
|
64
|
+
::File.write(path, rewritten_source)
|
65
|
+
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
def on_file_started(path)
|
68
|
+
@formatter.file_started(path, {})
|
69
|
+
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
result.each do |(path, offenses)|
|
74
|
-
on_file_started(formatter, path)
|
75
|
-
on_file_finished(path, formatter, offenses)
|
76
|
-
end
|
77
|
-
formatter.instance_variable_set(:@output, original)
|
71
|
+
def on_file_finished(path, offenses)
|
72
|
+
@formatter.file_finished(path, offenses)
|
73
|
+
end
|
78
74
|
|
79
|
-
|
75
|
+
def on_finished(result)
|
76
|
+
original = @formatter.output
|
77
|
+
@formatter.instance_variable_set(:@output, ::StringIO.new)
|
78
|
+
result.each do |(path, offenses)|
|
79
|
+
on_file_started(path)
|
80
|
+
on_file_finished(path, offenses)
|
80
81
|
end
|
82
|
+
@formatter.instance_variable_set(:@output, original)
|
83
|
+
|
84
|
+
@formatter.finished(@paths)
|
81
85
|
end
|
82
86
|
end
|
83
87
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'parser'
|
4
|
+
require 'rubocop/cop/legacy/corrector'
|
5
5
|
|
6
6
|
module Slimembedcop
|
7
7
|
# Apply auto-corrections to Template file.
|
@@ -18,6 +18,10 @@ module Slimembedcop
|
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
+
def source_buffer
|
22
|
+
::Parser::Source::Buffer.new(@path, source: @source)
|
23
|
+
end
|
24
|
+
|
21
25
|
def corrections
|
22
26
|
@offenses.select(&:corrector).map do |offense|
|
23
27
|
lambda do |corrector|
|
@@ -25,9 +29,5 @@ module Slimembedcop
|
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
28
|
-
|
29
|
-
def source_buffer
|
30
|
-
::Parser::Source::Buffer.new(@path, source: @source)
|
31
|
-
end
|
32
32
|
end
|
33
33
|
end
|
data/lib/slimembedcop/version.rb
CHANGED
data/lib/slimembedcop.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'slimembedcop/version'
|
4
4
|
|
5
5
|
module Slimembedcop
|
6
|
-
autoload :Cli,
|
7
|
-
autoload :ConfigGenerator,
|
8
|
-
autoload :Extractor,
|
9
|
-
autoload :Offense,
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
6
|
+
autoload :Cli, 'slimembedcop/cli'
|
7
|
+
autoload :ConfigGenerator, 'slimembedcop/config_generator'
|
8
|
+
autoload :Extractor, 'slimembedcop/extractor'
|
9
|
+
autoload :Offense, 'slimembedcop/offense'
|
10
|
+
autoload :Option, 'slimembedcop/option'
|
11
|
+
autoload :OffenseCollector, 'slimembedcop/offense_collector'
|
12
|
+
autoload :PathFinder, 'slimembedcop/path_finder'
|
13
|
+
autoload :RubyOffenseCollector, 'slimembedcop/ruby_offense_collector'
|
14
|
+
autoload :Runner, 'slimembedcop/runner'
|
15
|
+
autoload :TemplateCorrector, 'slimembedcop/template_corrector'
|
15
16
|
end
|
data/slimembedcop.gemspec
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'lib/slimembedcop/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
6
|
+
spec.name = 'slimembedcop'
|
7
7
|
spec.version = Slimembedcop::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.authors = ['Yudai Takada']
|
9
|
+
spec.email = ['t.yudai92@gmail.com']
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
14
|
-
spec.required_ruby_version =
|
11
|
+
spec.summary = 'RuboCop runner for Ruby code embedded in Slim.'
|
12
|
+
spec.homepage = 'https://github.com/ydah/slimembedcop'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
spec.required_ruby_version = '>= 2.7.0'
|
15
15
|
|
16
|
-
spec.metadata[
|
17
|
-
spec.metadata[
|
18
|
-
spec.metadata[
|
19
|
-
spec.metadata[
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
18
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
|
19
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
20
20
|
|
21
21
|
spec.files = Dir.chdir(__dir__) do
|
22
22
|
`git ls-files -z`.split("\x0").reject do |f|
|
@@ -24,9 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
25
25
|
end
|
26
26
|
end
|
27
|
-
spec.bindir =
|
27
|
+
spec.bindir = 'exe'
|
28
28
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
|
-
spec.require_paths = [
|
29
|
+
spec.require_paths = ['lib']
|
30
30
|
|
31
|
-
spec.add_dependency
|
31
|
+
spec.add_dependency 'rubocop', '~> 1.0'
|
32
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slimembedcop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
|
+
original_platform: ''
|
6
7
|
authors:
|
7
8
|
- Yudai Takada
|
8
|
-
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -24,7 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
-
description:
|
28
27
|
email:
|
29
28
|
- t.yudai92@gmail.com
|
30
29
|
executables:
|
@@ -32,6 +31,7 @@ executables:
|
|
32
31
|
extensions: []
|
33
32
|
extra_rdoc_files: []
|
34
33
|
files:
|
34
|
+
- ".codespellignore"
|
35
35
|
- ".rspec"
|
36
36
|
- ".rubocop.yml"
|
37
37
|
- CHANGELOG.md
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- lib/slimembedcop/extractor.rb
|
47
47
|
- lib/slimembedcop/offense.rb
|
48
48
|
- lib/slimembedcop/offense_collector.rb
|
49
|
+
- lib/slimembedcop/option.rb
|
49
50
|
- lib/slimembedcop/path_finder.rb
|
50
51
|
- lib/slimembedcop/ruby_offense_collector.rb
|
51
52
|
- lib/slimembedcop/runner.rb
|
@@ -60,7 +61,6 @@ metadata:
|
|
60
61
|
source_code_uri: https://github.com/ydah/slimembedcop
|
61
62
|
changelog_uri: https://github.com/ydah/slimembedcop/releases
|
62
63
|
rubygems_mfa_required: 'true'
|
63
|
-
post_install_message:
|
64
64
|
rdoc_options: []
|
65
65
|
require_paths:
|
66
66
|
- lib
|
@@ -75,8 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
79
|
-
signing_key:
|
78
|
+
rubygems_version: 3.6.0.dev
|
80
79
|
specification_version: 4
|
81
80
|
summary: RuboCop runner for Ruby code embedded in Slim.
|
82
81
|
test_files: []
|