pronto-rubocop 0.10.0 → 0.11.2

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: '061479d3c9326adbd73af0ee8e79c5a1f46ed3aa8f8ea8dfa7b7946a899e4aff'
4
- data.tar.gz: 22ab34372429508f391103d663cb462650fac8c08110771ff897400a22662a42
3
+ metadata.gz: 9966d2906f3d406926909048fe99e8814afa4b58e4a54963553652a1d502092b
4
+ data.tar.gz: d8be4f7a23e51f8c98debc7a41440289f34b2b11c3a52ae7af5507e8e628ff70
5
5
  SHA512:
6
- metadata.gz: c921d367340e6b725fd6f5c057c0d7ba3fbdab8b03f1ea5a56a559a6336ca646fca67f0f4f6467822db4c300779a015565fb48cf099bf22a38a549f6af8f846e
7
- data.tar.gz: f1711fd2fb7c1bdd9c2374307879eb91e3af059928668a92864def3fea788f3f884075c08b9416623e770aa6309b13a6088d0308a4451047ee5ef529dea55647
6
+ metadata.gz: a69bc7d7de258f3bfe7b000b5d7a0c1dde7fa1075d0d665d7e695cf325fe6c4ff771178c7bc70b24c77175361fbd0320d33daa6d68415ee529efd3446c9b778f
7
+ data.tar.gz: 32042282d15f1e5b65c34efb771918f19a6db84dbcc4e6ce8d04dd54b21dee5131bc5f4a6893832eb30b2fe99ffff07ba021a338c0dbc999b57c9dd2ebc02d90
@@ -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,46 @@
1
+ name: Checks
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+ workflow_dispatch:
9
+ schedule:
10
+ - cron: '0 6 * * 1' # 6am every Monday
11
+
12
+ jobs:
13
+ unit_tests:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ ruby: ['2.4', '2.5', '2.6', '2.7', '3.0']
18
+ rubocop: ['0.63.1', '0.81.0', '0.84.0', '0.85.0', '0.86.0', '0.87.0', '< 1.0', '1.0.0', '1.29.1', '1.30.0', '< 2.0']
19
+ include:
20
+ - ruby: '2.3'
21
+ rubocop: '0.63.1'
22
+ - ruby: '2.3'
23
+ rubocop: '0.81.0'
24
+ exclude:
25
+ - ruby: '2.4'
26
+ rubocop: '1.29.1'
27
+ - ruby: '2.4'
28
+ rubocop: '1.30.0'
29
+ - ruby: '2.5'
30
+ rubocop: '1.29.1'
31
+ - ruby: '2.5'
32
+ rubocop: '1.30.0'
33
+ fail-fast: false
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - name: use specific rubocop version
37
+ run: echo "gem 'rubocop', '${{ matrix.rubocop }}'" > Gemfile.local
38
+ - name: use specific rubocop-ast version (if required)
39
+ if: matrix.rubocop == '0.84.0' || matrix.rubocop == '0.85.0'
40
+ run: echo "gem 'rubocop-ast', '< 0.7.0'" >> Gemfile.local
41
+ - uses: ruby/setup-ruby@v1
42
+ with:
43
+ ruby-version: ${{ matrix.ruby }}
44
+ bundler-cache: true
45
+ - name: rake spec
46
+ run: bundle exec rake spec
data/README.md CHANGED
@@ -1,12 +1,54 @@
1
- # Pronto runner for Rubocop
1
+ # Pronto runner for RuboCop
2
2
 
3
3
  [![Code Climate](https://codeclimate.com/github/prontolabs/pronto-rubocop.png)](https://codeclimate.com/github/prontolabs/pronto-rubocop)
4
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
6
 
7
- Pronto runner for [Rubocop](https://github.com/bbatsov/rubocop), ruby code analyzer. [What is Pronto?](https://github.com/prontolabs/pronto)
7
+ Pronto runner for [RuboCop](https://github.com/bbatsov/rubocop), ruby code
8
+ analyzer. [What is Pronto?](https://github.com/prontolabs/pronto)
8
9
 
9
10
  ## Configuration
10
11
 
11
- Configuring Rubocop via .rubocop.yml will work just fine with pronto-rubocop.
12
- 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
@@ -0,0 +1,134 @@
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
+ # rubocop 1.30.0 renamed from auto_correct to autocorrect
60
+ AUTOCORRECT = Gem::Version.new(::RuboCop::Version::STRING) >= Gem::Version.new("1.30.0") ? :autocorrect : :auto_correct
61
+
62
+ def report
63
+ @report ||= autocorrect_team.investigate(processed_source).cop_reports.first
64
+ end
65
+
66
+ def corrector
67
+ report.corrector
68
+ end
69
+
70
+ def corrections_count
71
+ # Some lines may contain more than one offense
72
+ report.offenses.map(&:line).uniq.size
73
+ end
74
+ else
75
+ # rubocop 0.85.x and 0.86.0 have mobilize, older versions don't
76
+ MOBILIZE = ::RuboCop::Cop::Team.respond_to?(:mobilize) ? :mobilize : :new
77
+ AUTOCORRECT = :auto_correct
78
+
79
+ def corrector
80
+ @corrector ||= begin
81
+ autocorrect_team.inspect_file(processed_source)
82
+ corrector = RuboCop::Cop::Corrector.new(processed_source.buffer)
83
+ corrector.corrections.concat(autocorrect_team.cops.first.corrections)
84
+ corrector
85
+ end
86
+ end
87
+
88
+ def corrections_count
89
+ @corrections_count ||= corrector.corrections.count
90
+ end
91
+ end
92
+
93
+ def autocorrect_team
94
+ @autocorrect_team ||=
95
+ ::RuboCop::Cop::Team.send(MOBILIZE,
96
+ ::RuboCop::Cop::Registry.new([cop_class]),
97
+ patch_cop.rubocop_config,
98
+ **{ AUTOCORRECT => true, stdin: true })
99
+ end
100
+
101
+ def cop_class
102
+ patch_cop.registry.find_by_cop_name(offense.cop_name)
103
+ end
104
+
105
+ def level
106
+ severities.fetch(offense.severity.name)
107
+ end
108
+
109
+ def severities
110
+ @severities ||= DEFAULT_SEVERITIES.merge(config_severities)
111
+ end
112
+
113
+ def config_severities
114
+ patch_cop
115
+ .runner
116
+ .pronto_rubocop_config
117
+ .fetch('severities', {})
118
+ .map { |k, v| [k.to_sym, v.to_sym] }
119
+ .to_h
120
+ end
121
+
122
+ DEFAULT_SEVERITIES = {
123
+ info: :info,
124
+ refactor: :warning,
125
+ convention: :warning,
126
+ warning: :warning,
127
+ error: :error,
128
+ fatal: :fatal
129
+ }.freeze
130
+
131
+ private_constant :DEFAULT_SEVERITIES
132
+ end
133
+ end
134
+ end
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pronto
2
4
  class Rubocop < Runner
3
5
  class PatchCop
6
+ attr_reader :runner
7
+
4
8
  def initialize(patch, runner)
5
9
  @patch = patch
6
10
  @runner = runner
@@ -9,21 +13,40 @@ module Pronto
9
13
  def messages
10
14
  return [] unless valid?
11
15
 
12
- offences.map do |offence|
16
+ offenses.flat_map do |offense|
13
17
  patch
14
18
  .added_lines
15
- .select { |line| line.new_lineno == offence.line }
16
- .map { |line| new_message(offence, line) }
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)
17
39
  end
18
40
  end
19
41
 
20
42
  private
21
43
 
22
- attr_reader :patch, :runner
44
+ attr_reader :patch
23
45
 
24
46
  def valid?
25
- return false if config.file_to_exclude?(path)
26
- return true if config.file_to_include?(path)
47
+ return false if rubocop_config.file_to_exclude?(path)
48
+ return true if rubocop_config.file_to_include?(path)
49
+
27
50
  true
28
51
  end
29
52
 
@@ -31,15 +54,7 @@ module Pronto
31
54
  @path ||= patch.new_file_full_path.to_s
32
55
  end
33
56
 
34
- def config
35
- @config ||= begin
36
- store = ::RuboCop::ConfigStore.new
37
- store.options_config = ENV['RUBOCOP_CONFIG'] if ENV['RUBOCOP_CONFIG']
38
- store.for(path)
39
- end
40
- end
41
-
42
- def offences
57
+ def offenses
43
58
  team
44
59
  .inspect_file(processed_source)
45
60
  .sort
@@ -47,32 +62,13 @@ module Pronto
47
62
  end
48
63
 
49
64
  def team
50
- @team ||= ::RuboCop::Cop::Team.new(registry, config)
51
- end
52
-
53
- def registry
54
- @registry ||= ::RuboCop::Cop::Registry.new(RuboCop::Cop::Cop.all)
55
- end
56
-
57
- def processed_source
58
- @processed_source ||=
59
- ::RuboCop::ProcessedSource.from_file(path, config.target_ruby_version)
60
- end
61
-
62
- def new_message(offence, line)
63
- path = line.patch.delta.new_file[:path]
64
- level = level(offence.severity.name)
65
-
66
- Message.new(path, line, level, offence.message, nil, runner.class)
67
- end
68
-
69
- def level(severity)
70
- case severity
71
- when :refactor, :convention
72
- :warning
73
- when :warning, :error, :fatal
74
- severity
75
- end
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
76
72
  end
77
73
  end
78
74
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pronto
2
4
  module RubocopVersion
3
- VERSION = '0.10.0'.freeze
5
+ VERSION = '0.11.2'
4
6
  end
5
7
  end
@@ -1,14 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pronto'
2
4
  require 'rubocop'
3
5
  require 'pronto/rubocop/patch_cop'
6
+ require 'pronto/rubocop/offense_line'
4
7
 
5
8
  module Pronto
6
9
  class Rubocop < Runner
7
10
  def run
8
11
  ruby_patches
9
- .select { |patch| patch.additions > 0 }
10
- .map { |patch| PatchCop.new(patch, self).messages }
11
- .flatten
12
+ .select { |patch| patch.additions.positive? }
13
+ .flat_map { |patch| PatchCop.new(patch, self).messages }
14
+ end
15
+
16
+ def pronto_rubocop_config
17
+ @pronto_rubocop_config ||= Pronto::ConfigFile.new.to_h['rubocop'] || {}
12
18
  end
13
19
  end
14
20
  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
 
@@ -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.50', '>= 0.49.1')
36
- s.add_runtime_dependency('pronto', '~> 0.10.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.10.0
4
+ version: 0.11.2
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: 2019-02-03 00:00:00.000000000 Z
11
+ date: 2022-06-29 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
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 0.49.1
20
17
  - - "~>"
21
18
  - !ruby/object:Gem::Version
22
- version: '0.50'
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
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: 0.49.1
30
24
  - - "~>"
31
25
  - !ruby/object:Gem::Version
32
- version: '0.50'
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.10.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.10.0
46
+ version: '2.0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -94,9 +94,12 @@ 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
100
103
  - lib/pronto/rubocop/patch_cop.rb
101
104
  - lib/pronto/rubocop/version.rb
102
105
  - pronto-rubocop.gemspec
@@ -119,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
122
  - !ruby/object:Gem::Version
120
123
  version: '0'
121
124
  requirements: []
122
- rubygems_version: 3.0.1
125
+ rubygems_version: 3.0.3.1
123
126
  signing_key:
124
127
  specification_version: 4
125
128
  summary: Pronto runner for Rubocop, ruby code analyzer