pronto-rubocop 0.8.1 → 0.11.1

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
- SHA1:
3
- metadata.gz: 0f25431e077763d8bc08d97405887e0b2d9f8968
4
- data.tar.gz: 3db87215b3a0ddb0dc2da910bfad3151e235bbb3
2
+ SHA256:
3
+ metadata.gz: 9d5cd91a500a54c1184c0850685fd32ca72a832a82fd9c3a57b840d5b8eca6b2
4
+ data.tar.gz: 3b41e6777620b40b9d7e3d0d20946294c24acf8b081b32667e5adc69e2f03810
5
5
  SHA512:
6
- metadata.gz: 8315b02d6e4fb04c4e63526a21654456b0c1123e7caf8a718da89a3e75dbc3f314b15c0195e9769946696e997d7838db5f810ed46531efa8dc42a5da6c8537c2
7
- data.tar.gz: 0445514cbd4374be163a5499e9516494092bbcaa568a4002ab031622d59bea7de3bbd1f19333da96c8297037a127e6ff6a9e95160dacbec032c042a5923eb688
6
+ metadata.gz: 7e440e9d28f6ef2b46ba4b6556164dcf97298e7926a972f5997417275dc4b2611e434ecdca32ccf8dc4550daa2d3561ae66871404b1773a306b3d93a8eb90a90
7
+ data.tar.gz: 81f24db46df5d142535c545c3943514ebcb5b138f08171e17a5c8e72178ae014fc1d67b206a425e7e34d04fc6dad7f0839ba56b4a5ea9e3291434ebaf809e74f
@@ -0,0 +1,3 @@
1
+ # Order is important. The last matching pattern takes the most precedence.
2
+ # Default owners for everything in the repo.
3
+ * @prontolabs/core
@@ -0,0 +1,34 @@
1
+ name: Checks
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ unit_tests:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby: ['2.4', '2.5', '2.6', '2.7', '3.0']
15
+ rubocop: ['0.63.1', '0.81.0', '0.84.0', '0.85.0', '0.86.0', '0.87.0', '< 1.0', '1.0.0', '< 2.0']
16
+ include:
17
+ - ruby: '2.3'
18
+ rubocop: '0.63.1'
19
+ - ruby: '2.3'
20
+ rubocop: '0.81.0'
21
+ fail-fast: false
22
+ steps:
23
+ - uses: actions/checkout@v2
24
+ - name: use specific rubocop version
25
+ run: echo "gem 'rubocop', '${{ matrix.rubocop }}'" > Gemfile.local
26
+ - name: use specific rubocop-ast version (if required)
27
+ if: matrix.rubocop == '0.84.0' || matrix.rubocop == '0.85.0'
28
+ run: echo "gem 'rubocop-ast', '< 0.7.0'" >> Gemfile.local
29
+ - uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby }}
32
+ bundler-cache: true
33
+ - name: rake spec
34
+ run: bundle exec rake spec
data/README.md CHANGED
@@ -1,13 +1,54 @@
1
- # Pronto runner for Rubocop
1
+ # Pronto runner for RuboCop
2
2
 
3
- [![Code Climate](https://codeclimate.com/github/mmozuras/pronto-rubocop.png)](https://codeclimate.com/github/mmozuras/pronto-rubocop)
4
- [![Build Status](https://travis-ci.org/mmozuras/pronto-rubocop.png)](https://travis-ci.org/mmozuras/pronto-rubocop)
3
+ [![Code Climate](https://codeclimate.com/github/prontolabs/pronto-rubocop.png)](https://codeclimate.com/github/prontolabs/pronto-rubocop)
4
+ [![Build Status](https://travis-ci.org/prontolabs/pronto-rubocop.svg?branch=master)](https://travis-ci.org/prontolabs/pronto-rubocop)
5
5
  [![Gem Version](https://badge.fury.io/rb/pronto-rubocop.png)](http://badge.fury.io/rb/pronto-rubocop)
6
- [![Dependency Status](https://gemnasium.com/mmozuras/pronto-rubocop.png)](https://gemnasium.com/mmozuras/pronto-rubocop)
7
6
 
8
- Pronto runner for [Rubocop](https://github.com/bbatsov/rubocop), ruby code analyzer. [What is Pronto?](https://github.com/mmozuras/pronto)
7
+ Pronto runner for [RuboCop](https://github.com/bbatsov/rubocop), ruby code
8
+ analyzer. [What is Pronto?](https://github.com/prontolabs/pronto)
9
9
 
10
10
  ## Configuration
11
11
 
12
- Configuring Rubocop via .rubocop.yml will work just fine with pronto-rubocop.
13
- You can also specify a custom `.rubocop.yml` location with the environment variable `RUBOCOP_CONFIG`
12
+ Configuring RuboCop via `.rubocop.yml` will work just fine with
13
+ `pronto-rubocop`.
14
+
15
+ You can also specify a custom `.rubocop.yml` location with the environment
16
+ variable `RUBOCOP_CONFIG`.
17
+
18
+ You can also provide additional configuration via `.pronto.yml`:
19
+
20
+ ```yml
21
+ rubocop:
22
+ # Map of RuboCop severity level to Pronto severity level
23
+ severities:
24
+ refactor: info
25
+ warning: error
26
+
27
+ # Enable suggestions
28
+ suggestions: true
29
+ ```
30
+
31
+ ## Suggestions
32
+
33
+ When suggestions are enabled, the messages will include a line suggesting
34
+ what to change, using [GitHub's](https://twitter.com/wa7son/status/1052326282900443137)
35
+ syntax on Pull Request reviews, that can be approved in one click right from
36
+ the Pull Request.
37
+
38
+ For example:
39
+
40
+ ![GitHub screenshot with suggestion](https://user-images.githubusercontent.com/132/50402757-1bd75b80-0799-11e9-809f-8b8a23ed33f6.png)
41
+
42
+ ## RuboCop versions
43
+
44
+ If you need to use RuboCop v0.84.0 or v0.85.x, you'll need to ensure that
45
+ you've also need to add `gem 'rubocop-ast', '< 0.7.0'` to your Gemfile as
46
+ these were the first versions to use rubocop-ast, and unfortunately the
47
+ dependency was loose enough that rubocop-ast versions >= 0.7.0 were allowed,
48
+ which causes `require 'rubocop'` to fail with
49
+ ```
50
+ NoMethodError:
51
+ undefined method `join' for #<Set: {:==, :===, :!=, :<=, :>=, :>, :<}>
52
+ in rubocop-0.84.0/lib/rubocop/cop/style/redundant_conditional.rb:57:in `<class:RedundantConditional>'
53
+ ```
54
+ This is due to https://github.com/rubocop-hq/rubocop-ast/issues/22
@@ -1,71 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pronto'
2
4
  require 'rubocop'
5
+ require 'pronto/rubocop/patch_cop'
6
+ require 'pronto/rubocop/offense_line'
3
7
 
4
8
  module Pronto
5
9
  class Rubocop < Runner
6
- def initialize(_, _ = nil)
7
- super
8
-
9
- @config_store = ::RuboCop::ConfigStore.new
10
- @config_store.options_config = ENV['RUBOCOP_CONFIG'] if ENV['RUBOCOP_CONFIG']
11
- @inspector = ::RuboCop::Runner.new({}, @config_store)
12
- end
13
-
14
10
  def run
15
- return [] unless @patches
16
-
17
- @patches.select { |patch| valid_patch?(patch) }
18
- .map { |patch| inspect(patch) }
19
- .flatten.compact
20
- end
21
-
22
- def valid_patch?(patch)
23
- return false if patch.additions < 1
24
-
25
- config_store = config_store_for(patch)
26
- path = patch.new_file_full_path
27
-
28
- return false if config_store.file_to_exclude?(path.to_s)
29
- return true if config_store.file_to_include?(path.to_s)
30
-
31
- ruby_file?(path)
32
- end
33
-
34
- def inspect(patch)
35
- processed_source = processed_source_for(patch)
36
- offences = @inspector.send(:inspect_file, processed_source).first
37
-
38
- offences.sort.reject(&:disabled?).map do |offence|
39
- patch.added_lines
40
- .select { |line| line.new_lineno == offence.line }
41
- .map { |line| new_message(offence, line) }
42
- end
43
- end
44
-
45
- def new_message(offence, line)
46
- path = line.patch.delta.new_file[:path]
47
- level = level(offence.severity.name)
48
-
49
- Message.new(path, line, level, offence.message, nil, self.class)
50
- end
51
-
52
- def config_store_for(patch)
53
- path = patch.new_file_full_path.to_s
54
- @config_store.for(path)
55
- end
56
-
57
- def processed_source_for(patch)
58
- path = patch.new_file_full_path.to_s
59
- ::RuboCop::ProcessedSource.from_file(path, RUBY_VERSION[0..2].to_f)
11
+ ruby_patches
12
+ .select { |patch| patch.additions.positive? }
13
+ .flat_map { |patch| PatchCop.new(patch, self).messages }
60
14
  end
61
15
 
62
- def level(severity)
63
- case severity
64
- when :refactor, :convention
65
- :warning
66
- when :warning, :error, :fatal
67
- severity
68
- end
16
+ def pronto_rubocop_config
17
+ @pronto_rubocop_config ||= Pronto::ConfigFile.new.to_h['rubocop'] || {}
69
18
  end
70
19
  end
71
20
  end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pronto
4
+ class Rubocop < Runner
5
+ class OffenseLine
6
+ def initialize(patch_cop, offense, line)
7
+ @patch_cop = patch_cop
8
+ @offense = offense
9
+ @line = line
10
+ end
11
+
12
+ def message
13
+ Message.new(path, line, level, message_text, nil, Pronto::Rubocop)
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :patch_cop, :offense, :line
19
+
20
+ def path
21
+ line.patch.delta.new_file[:path]
22
+ end
23
+
24
+ def processed_source
25
+ patch_cop.processed_source
26
+ end
27
+
28
+ def message_text
29
+ return offense.message unless suggestion_text
30
+
31
+ "#{offense.message}\n\n```suggestion\n#{suggestion_text}```"
32
+ end
33
+
34
+ def suggestion_text
35
+ return unless patch_cop.runner.pronto_rubocop_config['suggestions']
36
+ return if corrections_count.zero?
37
+ return if differing_lines_count != corrections_count
38
+
39
+ @suggestion_text ||= corrected_lines[offense.line - 1]
40
+ end
41
+
42
+ def corrected_lines
43
+ @corrected_lines ||= corrector.rewrite.lines
44
+ end
45
+
46
+ def differing_lines_count
47
+ original_lines.each_with_index.count do |line, index|
48
+ line != corrected_lines[index]
49
+ end
50
+ end
51
+
52
+ def original_lines
53
+ processed_source.lines.join("\n").lines
54
+ end
55
+
56
+ if ::RuboCop::Cop::Team.respond_to?(:mobilize) && ::RuboCop::Cop::Team.public_method_defined?(:investigate)
57
+ # rubocop >= 0.87.0 has both mobilize and public investigate method
58
+ MOBILIZE = :mobilize
59
+
60
+ def report
61
+ @report ||= autocorrect_team.investigate(processed_source).cop_reports.first
62
+ end
63
+
64
+ def corrector
65
+ report.corrector
66
+ end
67
+
68
+ def corrections_count
69
+ report.offenses.size
70
+ end
71
+ else
72
+ # rubocop 0.85.x and 0.86.0 have mobilize, older versions don't
73
+ MOBILIZE = ::RuboCop::Cop::Team.respond_to?(:mobilize) ? :mobilize : :new
74
+
75
+ def corrector
76
+ @corrector ||= begin
77
+ autocorrect_team.inspect_file(processed_source)
78
+ corrector = RuboCop::Cop::Corrector.new(processed_source.buffer)
79
+ corrector.corrections.concat(autocorrect_team.cops.first.corrections)
80
+ corrector
81
+ end
82
+ end
83
+
84
+ def corrections_count
85
+ @corrections_count ||= corrector.corrections.count
86
+ end
87
+ end
88
+
89
+ def autocorrect_team
90
+ @autocorrect_team ||=
91
+ ::RuboCop::Cop::Team.send(MOBILIZE,
92
+ ::RuboCop::Cop::Registry.new([cop_class]),
93
+ patch_cop.rubocop_config,
94
+ auto_correct: true,
95
+ stdin: true)
96
+ end
97
+
98
+ def cop_class
99
+ patch_cop.registry.find_by_cop_name(offense.cop_name)
100
+ end
101
+
102
+ def level
103
+ severities.fetch(offense.severity.name)
104
+ end
105
+
106
+ def severities
107
+ @severities ||= DEFAULT_SEVERITIES.merge(config_severities)
108
+ end
109
+
110
+ def config_severities
111
+ patch_cop
112
+ .runner
113
+ .pronto_rubocop_config
114
+ .fetch('severities', {})
115
+ .map { |k, v| [k.to_sym, v.to_sym] }
116
+ .to_h
117
+ end
118
+
119
+ DEFAULT_SEVERITIES = {
120
+ refactor: :warning,
121
+ convention: :warning,
122
+ warning: :warning,
123
+ error: :error,
124
+ fatal: :fatal
125
+ }.freeze
126
+
127
+ private_constant :DEFAULT_SEVERITIES
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pronto
4
+ class Rubocop < Runner
5
+ class PatchCop
6
+ attr_reader :runner
7
+
8
+ def initialize(patch, runner)
9
+ @patch = patch
10
+ @runner = runner
11
+ end
12
+
13
+ def messages
14
+ return [] unless valid?
15
+
16
+ offenses.flat_map do |offense|
17
+ patch
18
+ .added_lines
19
+ .select { |line| line.new_lineno == offense.line }
20
+ .map { |line| OffenseLine.new(self, offense, line).message }
21
+ end
22
+ end
23
+
24
+ def processed_source
25
+ @processed_source ||= ::RuboCop::ProcessedSource.from_file(
26
+ path,
27
+ rubocop_config.target_ruby_version
28
+ )
29
+ end
30
+
31
+ def registry
32
+ @registry ||= ::RuboCop::Cop::Registry.new(RuboCop::Cop::Cop.all)
33
+ end
34
+
35
+ def rubocop_config
36
+ @rubocop_config ||= begin
37
+ store = ::RuboCop::ConfigStore.new
38
+ store.for(path)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :patch
45
+
46
+ def valid?
47
+ return false if rubocop_config.file_to_exclude?(path)
48
+ return true if rubocop_config.file_to_include?(path)
49
+
50
+ true
51
+ end
52
+
53
+ def path
54
+ @path ||= patch.new_file_full_path.to_s
55
+ end
56
+
57
+ def offenses
58
+ team
59
+ .inspect_file(processed_source)
60
+ .sort
61
+ .reject(&:disabled?)
62
+ end
63
+
64
+ def team
65
+ @team ||=
66
+ if ::RuboCop::Cop::Team.respond_to?(:mobilize)
67
+ # rubocop v0.85.0 and later
68
+ ::RuboCop::Cop::Team.mobilize(registry, rubocop_config)
69
+ else
70
+ ::RuboCop::Cop::Team.new(registry, rubocop_config)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pronto
2
4
  module RubocopVersion
3
- VERSION = '0.8.1'.freeze
5
+ VERSION = '0.11.1'
4
6
  end
5
7
  end
@@ -1,6 +1,6 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
4
  require 'pronto/rubocop/version'
5
5
  require 'English'
6
6
 
@@ -10,11 +10,11 @@ Gem::Specification.new do |s|
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.author = 'Mindaugas Mozūras'
12
12
  s.email = 'mindaugas.mozuras@gmail.com'
13
- s.homepage = 'http://github.org/mmozuras/pronto-rubocop'
13
+ s.homepage = 'http://github.com/mmozuras/pronto-rubocop'
14
14
  s.summary = 'Pronto runner for Rubocop, ruby code analyzer'
15
15
 
16
16
  s.licenses = ['MIT']
17
- s.required_ruby_version = '>= 2.0.0'
17
+ s.required_ruby_version = '>= 2.3.0'
18
18
  s.rubygems_version = '1.8.23'
19
19
 
20
20
  s.files = `git ls-files`.split($RS).reject do |file|
@@ -32,8 +32,8 @@ Gem::Specification.new do |s|
32
32
  s.extra_rdoc_files = ['LICENSE', 'README.md']
33
33
  s.require_paths = ['lib']
34
34
 
35
- s.add_runtime_dependency('rubocop', '~> 0.38', '>= 0.35.0')
36
- s.add_runtime_dependency('pronto', '~> 0.8.0')
35
+ s.add_runtime_dependency('pronto', '~> 0.11.0')
36
+ s.add_runtime_dependency('rubocop', '>= 0.63.1', '< 2.0')
37
37
  s.add_development_dependency('rake', '~> 12.0')
38
38
  s.add_development_dependency('rspec', '~> 3.4')
39
39
  s.add_development_dependency('rspec-its', '~> 1.2')
metadata CHANGED
@@ -1,49 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pronto-rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mindaugas Mozūras
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-05 00:00:00.000000000 Z
11
+ date: 2021-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rubocop
14
+ name: pronto
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.38'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 0.35.0
19
+ version: 0.11.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '0.38'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 0.35.0
26
+ version: 0.11.0
33
27
  - !ruby/object:Gem::Dependency
34
- name: pronto
28
+ name: rubocop
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - "~>"
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.63.1
34
+ - - "<"
38
35
  - !ruby/object:Gem::Version
39
- version: 0.8.0
36
+ version: '2.0'
40
37
  type: :runtime
41
38
  prerelease: false
42
39
  version_requirements: !ruby/object:Gem::Requirement
43
40
  requirements:
44
- - - "~>"
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.63.1
44
+ - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.8.0
46
+ version: '2.0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -94,12 +94,16 @@ extra_rdoc_files:
94
94
  - LICENSE
95
95
  - README.md
96
96
  files:
97
+ - ".github/CODEOWNERS"
98
+ - ".github/workflows/checks.yml"
97
99
  - LICENSE
98
100
  - README.md
99
101
  - lib/pronto/rubocop.rb
102
+ - lib/pronto/rubocop/offense_line.rb
103
+ - lib/pronto/rubocop/patch_cop.rb
100
104
  - lib/pronto/rubocop/version.rb
101
105
  - pronto-rubocop.gemspec
102
- homepage: http://github.org/mmozuras/pronto-rubocop
106
+ homepage: http://github.com/mmozuras/pronto-rubocop
103
107
  licenses:
104
108
  - MIT
105
109
  metadata: {}
@@ -111,15 +115,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
115
  requirements:
112
116
  - - ">="
113
117
  - !ruby/object:Gem::Version
114
- version: 2.0.0
118
+ version: 2.3.0
115
119
  required_rubygems_version: !ruby/object:Gem::Requirement
116
120
  requirements:
117
121
  - - ">="
118
122
  - !ruby/object:Gem::Version
119
123
  version: '0'
120
124
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 2.6.10
125
+ rubygems_version: 3.0.3
123
126
  signing_key:
124
127
  specification_version: 4
125
128
  summary: Pronto runner for Rubocop, ruby code analyzer