slimcop 0.9.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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