slimcop 0.3.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e43c25d5b3588ae90dd33cff028ef9c42ada8905782d8ac97049324948e0e8f6
4
- data.tar.gz: b487022dc36d88c433ff0cf5b2666fe97e27a0e88b3def78fcbc51a2f33d753c
3
+ metadata.gz: 03e13f6191b529e4c4b0ca6bc1fbbd6d1144eb029e62158ae04f43111f4dd96e
4
+ data.tar.gz: 4eb2dccd29708a5de535d9fb4971eb56084e3d45644fd9ad9f0731416ad22ec7
5
5
  SHA512:
6
- metadata.gz: fba92c121be30436567f9cc30cb22570a8bc3f6316d8564681d9d124a2400296590fed6f0c11b7b3cb3ea16d3e48ebd3f53ba9719bc085bf76b731f1c7115e29
7
- data.tar.gz: df506c25b9b513589bf05391555b83228e976b000c4117e55d85b8e209ef613c25beef1b8e981a871e8c17382048d472a59dce3386cd1f034164ec81e528b547
6
+ metadata.gz: '09705a482591105427cf3bc97f6ba86ab317d78e845fb0ca91d677730fa7081b5466c54112449127d83dc350431aea1de288bfc67034e10045e47dfcda57a7b3'
7
+ data.tar.gz: '09384443d865bb4cd1edf7d44e0ee1eb84dcf6729910220b4cad9970eba1dd16b0cb00b26b40f5845223a61488097a5fd9b8c48f25c8e69349ba47d1739cea2c'
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ require:
2
+ - rubocop-rspec
3
+
1
4
  AllCops:
2
5
  NewCops: enable
3
6
  SuggestExtensions: false
@@ -9,5 +12,20 @@ Layout/LineLength:
9
12
  Metrics:
10
13
  Enabled: false
11
14
 
15
+ RSpec/AnyInstance:
16
+ Enabled: false
17
+
18
+ RSpec/ExampleLength:
19
+ Enabled: false
20
+
21
+ RSpec/ImplicitSubject:
22
+ Enabled: false
23
+
24
+ RSpec/MultipleExpectations:
25
+ Enabled: false
26
+
27
+ RSpec/NamedSubject:
28
+ Enabled: false
29
+
12
30
  Style/Documentation:
13
31
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -2,6 +2,46 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ### 0.7.0 - 2021-12-28
6
+
7
+ ### Changed
8
+
9
+ - Re-use RuboCop's progress formatter as our default formatter.
10
+
11
+ ## 0.6.0 - 2021-12-28
12
+
13
+ ### Added
14
+
15
+ - Add -c, --config CLI option to customize RuboCop config.
16
+
17
+ ### Changed
18
+
19
+ - Not investigate all files then auto-correct them, but do it for each file.
20
+ - Sort processed files in alphabetical order.
21
+ - Disable Lint/UselessAssignment by default.
22
+
23
+ ## 0.5.0 - 2021-12-27
24
+
25
+ ### Changed
26
+
27
+ - Disable Lint/EmptyFile by default.
28
+ - Disable Style/RescueModifier by default.
29
+
30
+ ### Fixed
31
+
32
+ - Fix NoMethodError on some RuboCop offenses.
33
+ - Fix bug when uncorrectable RuboCop offense exists.
34
+
35
+ ## 0.4.0 - 2021-12-26
36
+
37
+ ### Added
38
+
39
+ - Support glob pattern on arguments of executable.
40
+
41
+ ### Fixed
42
+
43
+ - Fix bug on parsing invalid syntax Ruby code.
44
+
5
45
  ## 0.3.0 - 2021-12-25
6
46
 
7
47
  ### Added
data/Gemfile CHANGED
@@ -2,11 +2,9 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- # Specify your gem's dependencies in slimcop.gemspec
6
5
  gemspec
7
6
 
8
7
  gem 'rake', '~> 13.0'
9
-
10
- gem 'rspec', '~> 3.0'
11
-
12
- gem 'rubocop', '~> 1.21'
8
+ gem 'rspec'
9
+ gem 'rubocop'
10
+ gem 'rubocop-rspec'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slimcop (0.3.0)
4
+ slimcop (0.7.0)
5
5
  rainbow
6
6
  rubocop (>= 0.87)
7
7
  slimi (>= 0.4)
@@ -42,8 +42,10 @@ GEM
42
42
  unicode-display_width (>= 1.4.0, < 3.0)
43
43
  rubocop-ast (1.15.0)
44
44
  parser (>= 3.0.1.1)
45
+ rubocop-rspec (2.6.0)
46
+ rubocop (~> 1.19)
45
47
  ruby-progressbar (1.11.0)
46
- slimi (0.4.0)
48
+ slimi (0.4.2)
47
49
  temple
48
50
  temple (0.8.2)
49
51
  unicode-display_width (2.1.0)
@@ -53,8 +55,9 @@ PLATFORMS
53
55
 
54
56
  DEPENDENCIES
55
57
  rake (~> 13.0)
56
- rspec (~> 3.0)
57
- rubocop (~> 1.21)
58
+ rspec
59
+ rubocop
60
+ rubocop-rspec
58
61
  slimcop!
59
62
 
60
63
  BUNDLED WITH
data/README.md CHANGED
@@ -33,5 +33,25 @@ Use `slimcop` executable to check offenses and auto-correct them.
33
33
  $ slimcop --help
34
34
  Usage: slimcop [options] [file1, file2, ...]
35
35
  -a, --auto-correct Auto-correct offenses.
36
+ -c, --config= Specify configuration file.
36
37
  --[no-]color Force color output on or off.
37
38
  ```
39
+
40
+ ### Example
41
+
42
+ ```console
43
+ $ slimcop "**/*.slim"
44
+ Inspecting 1 file
45
+ C
46
+
47
+ Offenses:
48
+
49
+ spec/fixtures/dummy.slim:1:3: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
50
+ - "a"
51
+ ^^^
52
+ spec/fixtures/dummy.slim:3:5: C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
53
+ | #{"c"}
54
+ ^^^
55
+
56
+ 1 file inspected, 2 offenses detected, 2 offenses auto-correctable
57
+ ```
data/default.yml CHANGED
@@ -10,6 +10,9 @@ Layout/BlockAlignment:
10
10
  Layout/ClosingParenthesisIndentation:
11
11
  Enabled: false
12
12
 
13
+ Lint/EmptyFile:
14
+ Enabled: false
15
+
13
16
  Layout/EmptyLineAfterGuardClause:
14
17
  Enabled: false
15
18
 
@@ -76,6 +79,9 @@ Layout/TrailingEmptyLines:
76
79
  Layout/TrailingWhitespace:
77
80
  Enabled: false
78
81
 
82
+ Lint/UselessAssignment:
83
+ Enabled: false
84
+
79
85
  Lint/Void:
80
86
  Enabled: false
81
87
 
@@ -100,6 +106,9 @@ Style/IfUnlessModifier:
100
106
  Style/Next:
101
107
  Enabled: false
102
108
 
109
+ Style/RescueModifier:
110
+ Enabled: false
111
+
103
112
  Style/WhileUntilDo:
104
113
  Enabled: false
105
114
 
data/lib/slimcop/cli.rb CHANGED
@@ -1,69 +1,71 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rainbow'
4
+ require 'rubocop'
4
5
 
5
6
  module Slimcop
6
7
  class Cli
7
8
  def initialize(argv)
8
9
  @argv = argv.dup
9
- @configuration = Configuration.new
10
- @formatter = Formatter.new
10
+ @formatter = ::RuboCop::Formatter::ProgressFormatter.new($stdout)
11
11
  end
12
12
 
13
13
  def call
14
14
  options = parse!
15
- slim_file_paths = @argv
16
-
17
15
  Rainbow.enabled = options[:color] if options.key?(:color)
16
+ rubocop_config = RuboCopConfigGenerator.new(additional_config_file_path: options[:additional_config_file_path]).call
17
+ file_paths = PathFinder.new(patterns: @argv).call
18
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)
19
+ @formatter.started(file_paths)
20
+ offenses = file_paths.flat_map do |file_path|
21
+ @formatter.file_started(file_path, {})
22
+ source = ::File.read(file_path)
23
+ offenses_ = investigate(
24
+ auto_correct: options[:auto_correct],
25
+ file_path: file_path,
26
+ rubocop_config: rubocop_config,
27
+ source: source
28
+ )
29
+ if options[:auto_correct]
30
+ correct(
31
+ file_path: file_path,
32
+ offenses: offenses_,
33
+ source: source
34
+ )
35
+ end
36
+ @formatter.file_finished(file_path, offenses_)
37
+ offenses_
38
+ end
39
+ @formatter.finished(file_paths)
23
40
  exit(offenses.empty? ? 0 : 1)
24
41
  end
25
42
 
26
43
  private
27
44
 
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
45
+ # @param [String] file_path
46
+ # @param [Array<Slimcop::Offense>] offenses
47
+ # @param [String] source
48
+ def correct(file_path:, offenses:, source:)
49
+ rewritten_source = SlimCorrector.new(
50
+ file_path: file_path,
51
+ offenses: offenses,
52
+ source: source
53
+ ).call
54
+ ::File.write(file_path, rewritten_source)
38
55
  end
39
56
 
40
57
  # @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)
58
+ # @param [String] file_path
59
+ # @param [String] rubocop_config
60
+ # @param [String] source
61
+ # @return [Array<Slimcop::Offense>]
62
+ def investigate(auto_correct:, file_path:, rubocop_config:, source:)
63
+ SlimOffenseCollector.new(
64
+ auto_correct: auto_correct,
65
+ file_path: file_path,
66
+ rubocop_config: rubocop_config,
67
+ source: source
68
+ ).call
67
69
  end
68
70
 
69
71
  # @return [Hash]
@@ -74,6 +76,9 @@ module Slimcop
74
76
  parser.on('-a', '--auto-correct', 'Auto-correct offenses.') do
75
77
  options[:auto_correct] = true
76
78
  end
79
+ parser.on('-c', '--config=', 'Specify configuration file.') do |file_path|
80
+ options[:additional_config_file_path] = file_path
81
+ end
77
82
  parser.on('--[no-]color', 'Force color output on or off.') do |value|
78
83
  options[:color] = value
79
84
  end
@@ -1,52 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+
3
5
  require 'parser'
6
+ require 'rubocop'
4
7
 
5
8
  module Slimcop
6
9
  class Offense
10
+ extend ::Forwardable
11
+
12
+ # @return [String]
13
+ attr_reader :file_path
14
+
7
15
  # @return [Integer]
8
16
  attr_reader :offset
9
17
 
10
- # @return [RuboCop::Cop::Offense]
11
- attr_reader :rubocop_offense
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
+ )
12
33
 
13
34
  # @param [Integer] offset
14
35
  # @param [RuboCop::Cop::Offense] rubocop_offense
15
36
  # @param [String] source Slim code.
16
- def initialize(offset:, rubocop_offense:, source:)
37
+ def initialize(file_path:, offset:, rubocop_offense:, source:)
38
+ @file_path = file_path
17
39
  @offset = offset
18
40
  @rubocop_offense = rubocop_offense
19
41
  @source = source
20
42
  end
21
43
 
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
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
+ )
50
51
  end
51
52
 
52
53
  private
@@ -59,12 +60,15 @@ module Slimcop
59
60
  )
60
61
  end
61
62
 
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
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
68
72
  )
69
73
  end
70
74
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Slimcop
6
+ # Collect file paths from given path patterns.
7
+ class PathFinder
8
+ # @param [Array<String>] patterns Patterns normally given as CLI arguments (e.g. `["app/views/**/*.html.slim"]`).
9
+ def initialize(patterns:)
10
+ @patterns = patterns
11
+ end
12
+
13
+ # @return [Array<String>]
14
+ def call
15
+ @patterns.flat_map do |pattern|
16
+ ::Pathname.glob(pattern).select(&:file?).map(&:to_s)
17
+ end.sort
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop'
4
+
5
+ module Slimcop
6
+ class RuboCopConfigGenerator
7
+ # @param [String] additional_config_file_path
8
+ def initialize(additional_config_file_path: nil)
9
+ @additional_config_file_path = additional_config_file_path
10
+ end
11
+
12
+ # @return [RuboCop::Config]
13
+ def call
14
+ ::RuboCop::ConfigLoader.merge_with_default(merged_config, loaded_path)
15
+ end
16
+
17
+ private
18
+
19
+ # @return [String]
20
+ def loaded_path
21
+ @additional_config_file_path || slimcop_default_config_file_path
22
+ end
23
+
24
+ # @return [RuboCop::Config]
25
+ def merged_config
26
+ ::RuboCop::Config.create(merged_config_hash, loaded_path)
27
+ end
28
+
29
+ # @return [Hash]
30
+ def merged_config_hash
31
+ result = slimcop_default_config
32
+ result = ::RuboCop::ConfigLoader.merge(result, additional_config) if @additional_config_file_path
33
+ result
34
+ end
35
+
36
+ # @return [RuboCop::Config, nil]
37
+ def additional_config
38
+ ::RuboCop::ConfigLoader.load_file(@additional_config_file_path) if @additional_config_file_path
39
+ end
40
+
41
+ # @return [RuboCop::Config]
42
+ def slimcop_default_config
43
+ ::RuboCop::ConfigLoader.load_file(slimcop_default_config_file_path)
44
+ end
45
+
46
+ # @return [String]
47
+ def slimcop_default_config_file_path
48
+ @slimcop_default_config_file_path ||= ::File.expand_path('../../default.yml', __dir__)
49
+ end
50
+ end
51
+ end
@@ -16,9 +16,10 @@ module Slimcop
16
16
  @source = source
17
17
  end
18
18
 
19
- # @return [Array<RuboCop::Cop::Offense>, nil]
19
+ # @return [Array<RuboCop::Cop::Offense>]
20
20
  def call
21
- return unless rubocop_processed_source.valid_syntax?
21
+ # Skip if invalid syntax Ruby code is given. (e.g. "- if a?")
22
+ return [] unless rubocop_processed_source.valid_syntax?
22
23
 
23
24
  rubocop_team.investigate(rubocop_processed_source).offenses
24
25
  end
@@ -24,7 +24,7 @@ module Slimcop
24
24
 
25
25
  # @return [Array<Proc>]
26
26
  def corrections
27
- @offenses.map do |offense|
27
+ @offenses.select(&:corrector).map do |offense|
28
28
  lambda do |corrector|
29
29
  corrector.import!(offense.corrector, offset: offense.offset)
30
30
  end
@@ -24,6 +24,7 @@ module Slimcop
24
24
  source: snippet[:code]
25
25
  ).call.map do |rubocop_offense|
26
26
  Offense.new(
27
+ file_path: @file_path,
27
28
  offset: snippet[:begin_],
28
29
  rubocop_offense: rubocop_offense,
29
30
  source: @source
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Slimcop
4
- VERSION = '0.3.0'
4
+ VERSION = '0.7.0'
5
5
  end
data/lib/slimcop.rb CHANGED
@@ -4,9 +4,9 @@ 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
7
  autoload :Offense, 'slimcop/offense'
8
+ autoload :PathFinder, 'slimcop/path_finder'
9
+ autoload :RuboCopConfigGenerator, 'slimcop/rubo_cop_config_generator'
10
10
  autoload :RubyExtractor, 'slimcop/ruby_extractor'
11
11
  autoload :RubyOffenseCollector, 'slimcop/ruby_offense_collector'
12
12
  autoload :SlimCorrector, 'slimcop/slim_corrector'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slimcop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.7.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-24 00:00:00.000000000 Z
11
+ date: 2021-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -75,9 +75,9 @@ files:
75
75
  - exe/slimcop
76
76
  - lib/slimcop.rb
77
77
  - lib/slimcop/cli.rb
78
- - lib/slimcop/configuration.rb
79
- - lib/slimcop/formatter.rb
80
78
  - lib/slimcop/offense.rb
79
+ - lib/slimcop/path_finder.rb
80
+ - lib/slimcop/rubo_cop_config_generator.rb
81
81
  - lib/slimcop/ruby_extractor.rb
82
82
  - lib/slimcop/ruby_offense_collector.rb
83
83
  - lib/slimcop/slim_corrector.rb
@@ -1,16 +0,0 @@
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
@@ -1,72 +0,0 @@
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