slimcop 0.9.0 → 0.12.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: 4ddeb0d894aab7002ef81c70937513071636e1d048f5fd8e94300fd9af6c96a4
4
- data.tar.gz: c12290288593975b5e2ca620fd023ada7b6c04d39c41dcbae8155f9f8245809f
3
+ metadata.gz: dd949a834535638a785282759fe46fb6fd368282d3030d17a113fa5253755bd7
4
+ data.tar.gz: 70be88bc581d8ba538879cffabcef3c58e21bbddda4ce8c7812c32e465ab5108
5
5
  SHA512:
6
- metadata.gz: 02b791ca65f375995f387c08cb107c7d7d37791fdcfa6546cef9ae60869e00bd21bed8610bce6f5dad8b8641f48b1ab8528f29538ee2352af356a08d10cc7ae5
7
- data.tar.gz: 7d58c62120d8fc325d339f5837d7d3f4ef9e72209ca106f2c3b5a9ce96f27d57f7a8b9fbd5da0e9292e479dcb2cb9459907189a9622f98d9d9f2cfd27666eca8
6
+ metadata.gz: 377b550717a43db56aefd5c66eb78622e2945c93436a45de5c50b8c9a61312a9d62d3e37d25108238788a5c08e0a4964dcc0401bd34531a620f02e62917091d3
7
+ data.tar.gz: db3cb5e5f9bf3ea5cf56d0a3e15bd430907721b2d33dd7d0e59bb2bd65e2d1fe78d8e51aee8ada603c8b92142694dc415921ce16e7e08e70633f918ef8ea830f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.12.0 - 2022-01-12
6
+
7
+ ### Changed
8
+
9
+ - Keep trying auto-correction up to 7 times until no offense detected.
10
+
11
+ ## 0.11.0 - 2022-01-10
12
+
13
+ ### Changed
14
+
15
+ - Detect offenses from code that containing `if`, `unless`, `do`, etc.
16
+
17
+ ## 0.10.0 - 2022-01-06
18
+
19
+ ### Added
20
+
21
+ - Use .slimcop.yml as its 1st default config file.
22
+
23
+ ## 0.9.1 - 2022-01-04
24
+
25
+ ### Fixed
26
+
27
+ - Fix $LOAD_PATH at ./exe/slimcop.
28
+
5
29
  ## 0.9.0 - 2022-01-02
6
30
 
7
31
  ### Changed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- slimcop (0.9.0)
4
+ slimcop (0.12.0)
5
5
  rainbow
6
6
  rubocop (>= 0.87)
7
7
  slimi (>= 0.5.1)
@@ -45,10 +45,12 @@ GEM
45
45
  rubocop-rspec (2.6.0)
46
46
  rubocop (~> 1.19)
47
47
  ruby-progressbar (1.11.0)
48
- slimi (0.5.1)
48
+ slimi (0.7.0)
49
49
  temple
50
+ thor
50
51
  tilt
51
52
  temple (0.8.2)
53
+ thor (1.2.1)
52
54
  tilt (2.0.10)
53
55
  unicode-display_width (2.1.0)
54
56
 
data/README.md CHANGED
@@ -40,7 +40,7 @@ Usage: slimcop [options] [file1, file2, ...]
40
40
  ### Example
41
41
 
42
42
  ```console
43
- $ slimcop
43
+ $ slimcop 'spec/fixtures/**/*.slim'
44
44
  Inspecting 1 file
45
45
  C
46
46
 
data/exe/slimcop CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
4
5
  require 'slimcop'
5
6
 
6
7
  Slimcop::Cli.new(ARGV).call
data/lib/slimcop/cli.rb CHANGED
@@ -15,58 +15,18 @@ module Slimcop
15
15
  rubocop_config = RuboCopConfigGenerator.new(additional_config_file_path: options[:additional_config_file_path]).call
16
16
  file_paths = PathFinder.new(patterns: @argv).call
17
17
 
18
- formatter.started(file_paths)
19
- offenses = file_paths.flat_map do |file_path|
20
- formatter.file_started(file_path, {})
21
- source = ::File.read(file_path)
22
- offenses_ = investigate(
23
- auto_correct: options[:auto_correct],
24
- file_path: file_path,
25
- rubocop_config: rubocop_config,
26
- source: source
27
- )
28
- if options[:auto_correct]
29
- correct(
30
- file_path: file_path,
31
- offenses: offenses_,
32
- source: source
33
- )
34
- end
35
- formatter.file_finished(file_path, offenses_)
36
- offenses_
37
- end
38
- formatter.finished(file_paths)
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
+
39
25
  exit(offenses.empty? ? 0 : 1)
40
26
  end
41
27
 
42
28
  private
43
29
 
44
- # @param [String] file_path
45
- # @param [Array<Slimcop::Offense>] offenses
46
- # @param [String] source
47
- def correct(file_path:, offenses:, source:)
48
- rewritten_source = SlimCorrector.new(
49
- file_path: file_path,
50
- offenses: offenses,
51
- source: source
52
- ).call
53
- ::File.write(file_path, rewritten_source)
54
- end
55
-
56
- # @param [Boolean] auto_correct
57
- # @param [String] file_path
58
- # @param [String] rubocop_config
59
- # @param [String] source
60
- # @return [Array<Slimcop::Offense>]
61
- def investigate(auto_correct:, file_path:, rubocop_config:, source:)
62
- SlimOffenseCollector.new(
63
- auto_correct: auto_correct,
64
- file_path: file_path,
65
- rubocop_config: rubocop_config,
66
- source: source
67
- ).call
68
- end
69
-
70
30
  # @return [Hash]
71
31
  def parse!
72
32
  options = {}
@@ -76,7 +36,7 @@ module Slimcop
76
36
  parser.on('-a', '--auto-correct', 'Auto-correct offenses.') do
77
37
  options[:auto_correct] = true
78
38
  end
79
- parser.on('-c', '--config=', 'Specify configuration file. (default: .rubocop.yml if it exists)') do |file_path|
39
+ parser.on('-c', '--config=', 'Specify configuration file. (default: .slimcop.yml or .rubocop.yml)') do |file_path|
80
40
  options[:additional_config_file_path] = file_path
81
41
  end
82
42
  parser.on('--[no-]color', 'Force color output on or off.') do |value|
@@ -4,7 +4,8 @@ require 'rubocop'
4
4
 
5
5
  module Slimcop
6
6
  class RuboCopConfigGenerator
7
- DEFAULT_ADDITIONAL_CONFIG_PATH = '.rubocop.yml'
7
+ DEFAULT_ADDITIONAL_CONFIG_PATH1 = '.slimcop.yml'
8
+ DEFAULT_ADDITIONAL_CONFIG_PATH2 = '.rubocop.yml'
8
9
 
9
10
  # @param [String] additional_config_file_path
10
11
  def initialize(additional_config_file_path: nil)
@@ -43,8 +44,10 @@ module Slimcop
43
44
  @additional_config = \
44
45
  if @additional_config_file_path
45
46
  ::RuboCop::ConfigLoader.load_file(@additional_config_file_path)
46
- elsif ::File.exist?(DEFAULT_ADDITIONAL_CONFIG_PATH)
47
- ::RuboCop::ConfigLoader.load_file(DEFAULT_ADDITIONAL_CONFIG_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)
48
51
  end
49
52
  end
50
53
  end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slimcop
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
@@ -3,7 +3,7 @@
3
3
  require 'slimi'
4
4
 
5
5
  module Slimcop
6
- # Extract codes from Slim source.
6
+ # Extract Ruby codes from Slim source.
7
7
  class RubyExtractor
8
8
  # @param [String, nil] file_path
9
9
  # @param [String] source
@@ -15,10 +15,10 @@ module Slimcop
15
15
  # @return [Array<Hash>]
16
16
  def call
17
17
  ranges.map do |(begin_, end_)|
18
+ clipped = RubyClipper.new(@source[begin_...end_]).call
18
19
  {
19
- begin_: begin_,
20
- code: @source[begin_...end_],
21
- end_: end_
20
+ code: clipped[:code],
21
+ offset: begin_ + clipped[:offset]
22
22
  }
23
23
  end
24
24
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slimcop
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<Slimcop::Offense>] offenses
34
+ # @param [String] source
35
+ def correct(file_path:, offenses:, source:)
36
+ rewritten_source = SlimCorrector.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<Slimcop::Offense>]
49
+ def investigate(auto_correct:, file_path:, rubocop_config:, source:)
50
+ SlimOffenseCollector.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
@@ -25,7 +25,7 @@ module Slimcop
25
25
  ).call.map do |rubocop_offense|
26
26
  Offense.new(
27
27
  file_path: @file_path,
28
- offset: snippet[:begin_],
28
+ offset: snippet[:offset],
29
29
  rubocop_offense: rubocop_offense,
30
30
  source: @source
31
31
  )
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Slimcop
4
- VERSION = '0.9.0'
4
+ VERSION = '0.12.0'
5
5
  end
data/lib/slimcop.rb CHANGED
@@ -7,8 +7,10 @@ module Slimcop
7
7
  autoload :Offense, 'slimcop/offense'
8
8
  autoload :PathFinder, 'slimcop/path_finder'
9
9
  autoload :RuboCopConfigGenerator, 'slimcop/rubo_cop_config_generator'
10
+ autoload :RubyClipper, 'slimcop/ruby_clipper'
10
11
  autoload :RubyExtractor, 'slimcop/ruby_extractor'
11
12
  autoload :RubyOffenseCollector, 'slimcop/ruby_offense_collector'
13
+ autoload :Runner, 'slimcop/runner'
12
14
  autoload :SlimCorrector, 'slimcop/slim_corrector'
13
15
  autoload :SlimOffenseCollector, 'slimcop/slim_offense_collector'
14
16
  end
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.9.0
4
+ version: 0.12.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-02 00:00:00.000000000 Z
11
+ date: 2022-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -78,8 +78,10 @@ files:
78
78
  - lib/slimcop/offense.rb
79
79
  - lib/slimcop/path_finder.rb
80
80
  - lib/slimcop/rubo_cop_config_generator.rb
81
+ - lib/slimcop/ruby_clipper.rb
81
82
  - lib/slimcop/ruby_extractor.rb
82
83
  - lib/slimcop/ruby_offense_collector.rb
84
+ - lib/slimcop/runner.rb
83
85
  - lib/slimcop/slim_corrector.rb
84
86
  - lib/slimcop/slim_offense_collector.rb
85
87
  - lib/slimcop/version.rb