Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallel static analysis by default #10000

Merged
merged 1 commit into from Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 1 addition & 6 deletions Rakefile
Expand Up @@ -22,12 +22,7 @@ require 'rubocop/rake_task'
Dir['tasks/**/*.rake'].each { |t| load t }

desc 'Run RuboCop over itself'
RuboCop::RakeTask.new(:internal_investigation).tap do |task|
if RUBY_ENGINE == 'ruby' &&
!/mswin|msys|mingw|cygwin|bccwin|wince|emc/.match?(RbConfig::CONFIG['host_os'])
task.options = %w[--parallel]
end
end
RuboCop::RakeTask.new(:internal_investigation)

task default: %i[documentation_syntax_check spec ascii_spec internal_investigation]

Expand Down
1 change: 1 addition & 0 deletions changelog/new_parallel_static_analysis_by_default.md
@@ -0,0 +1 @@
* [#10000](https://github.com/rubocop/rubocop/pull/10000): Parallel static analysis by default. ([@koic][])
18 changes: 18 additions & 0 deletions lib/rubocop/cli.rb
Expand Up @@ -8,6 +8,11 @@ class CLI
STATUS_OFFENSES = 1
STATUS_ERROR = 2
STATUS_INTERRUPTED = 128 + Signal.list['INT']
DEFAULT_PARALLEL_OPTIONS = %i[
color debug display_style_guide display_time display_only_fail_level_offenses
display_only_failed except extra_details fail_level fix_layout format
ignore_disable_comments lint only only_guide_cops require safe
].freeze

class Finished < RuntimeError; end

Expand Down Expand Up @@ -37,6 +42,7 @@ def run(args = ARGV)
else
act_on_options
validate_options_vs_config
parallel_by_default!
apply_default_formatter
execute_runners
end
Expand Down Expand Up @@ -84,6 +90,18 @@ def validate_options_vs_config
'with AllCops: UseCache: false is not allowed.'
end

def parallel_by_default!
# See https://github.com/rubocop/rubocop/pull/4537 for JRuby and Windows constraints.
return if RUBY_ENGINE != 'ruby' || RuboCop::Platform.windows?

if (@options.keys - DEFAULT_PARALLEL_OPTIONS).empty? &&
@config_store.for_pwd.for_all_cops['UseCache'] != false
puts 'Use parallel by default.' if @options[:debug]

@options[:parallel] = true
end
end

def act_on_options
set_options_to_config_loader

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/options.rb
Expand Up @@ -492,7 +492,7 @@ module OptionsHelp
version: 'Display version.',
verbose_version: 'Display verbose version.',
parallel: ['Use available CPUs to execute inspection in',
'parallel. Default is false.'],
'parallel. Default is true.'],
stdin: ['Pipe source from STDIN, using FILE in offense',
'reports. This is useful for editor integration.'],
init: 'Generate a .rubocop.yml file in the current directory.'
Expand Down
63 changes: 63 additions & 0 deletions spec/rubocop/cli_spec.rb
Expand Up @@ -197,6 +197,69 @@ def and_with_args
end
end

if RUBY_ENGINE == 'ruby' && !RuboCop::Platform.windows?
# NOTE: It has been tested for parallelism with `--debug` option.
# In other words, even if no option is specified, it will be parallelized by default.
describe 'when parallel static by default' do
context 'when specifying `--debug` option only`' do
it 'fails with an error message' do
create_file('example1.rb', <<~RUBY)
# frozen_string_literal: true

puts 'hello'
RUBY
expect(cli.run(['--debug'])).to eq(0)
expect($stdout.string).to include('Use parallel by default.')
end
end

# NOTE: Cannot be auto-corrected with `parallel`.
context 'when specifying `--debug` and `-a` options`' do
it 'fails with an error message' do
create_file('example1.rb', <<~RUBY)
# frozen_string_literal: true

puts 'hello'
RUBY
expect(cli.run(['--debug', '-a'])).to eq(0)
expect($stdout.string).not_to include('Use parallel by default.')
end
end

context 'when setting `UseCache: true`' do
it 'fails with an error message' do
create_file('example.rb', <<~RUBY)
# frozen_string_literal: true

puts 'hello'
RUBY
create_file('.rubocop.yml', <<~YAML)
AllCops:
UseCache: true
YAML
expect(cli.run(['--debug'])).to eq(0)
expect($stdout.string).to include('Use parallel by default.')
end
end

context 'when setting `UseCache: false`' do
it 'fails with an error message' do
create_file('example.rb', <<~RUBY)
# frozen_string_literal: true

puts 'hello'
RUBY
create_file('.rubocop.yml', <<~YAML)
AllCops:
UseCache: false
YAML
expect(cli.run(['--debug'])).to eq(0)
expect($stdout.string).not_to include('Use parallel by default.')
end
end
end
end

describe 'rubocop:disable comment' do
it 'can disable all cops in a code section' do
src = ['# rubocop:disable all',
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/options_spec.rb
Expand Up @@ -138,7 +138,7 @@ def abs(path)
-v, --version Display version.
-V, --verbose-version Display verbose version.
-P, --[no-]parallel Use available CPUs to execute inspection in
parallel. Default is false.
parallel. Default is true.
-l, --lint Run only lint cops.
-x, --fix-layout Run only layout cops, with auto-correct on.
-s, --stdin FILE Pipe source from STDIN, using FILE in offense
Expand Down