Skip to content

Commit

Permalink
Add --init option to rubocop command
Browse files Browse the repository at this point in the history
This PR adds `--init` option to `rubocop` command.

```console
% mkdir example
% cd /tmp/example
% rubocop --init
Writing new .rubocop.yml to /private/tmp/example/.rubocop.yml
% cat .rubocop.yml
# The behavior of RuboCop can be controlled via the .rubocop.yml
# configuration file. It makes it possible to enable/disable
# certain cops (checks) and to alter their behavior if they accept
# any parameters. The file can be placed either in your home
# directory or in some project directory.
#
# RuboCop will start looking for the configuration file in the directory
# where the inspected file is and continue its way up to the root directory.
#
# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
% rubocop --init # A warning will occur when .rubocop.yml already exists
.rubocop.yml already exists at /private/tmp/example/.rubocop.yml
```

It may be good to add a simple commented examples of basic configuration in the future.

First of all, this PR aims to generate .rubocop.yml which contains the following configuration URL.
https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md

And the generated .rubocop.yml text is quoted from the above URL.
  • Loading branch information
koic authored and bbatsov committed Apr 14, 2019
1 parent cdf442b commit ab27faf
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### New features

* [#6928](https://github.com/rubocop-hq/rubocop/pull/6928): Add `--init` option for generate `.rubocop.yml` file in the current directory. ([@koic][])

### Bug fixes

* [#6914](https://github.com/rubocop-hq/rubocop/issues/6914): [Fix #6914] Fix an error for `Rails/RedundantAllowNil` when with interpolations. ([@Blue-Pix][])
Expand Down
44 changes: 40 additions & 4 deletions lib/rubocop/cli.rb
Expand Up @@ -41,10 +41,15 @@ def initialize
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def run(args = ARGV)
@options, paths = Options.new.parse(args)
validate_options_vs_config
act_on_options
apply_default_formatter
execute_runners(paths)

if @options[:init]
init_dotfile
else
validate_options_vs_config
act_on_options
apply_default_formatter
execute_runners(paths)
end
rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
warn e.message
STATUS_ERROR
Expand Down Expand Up @@ -132,6 +137,37 @@ def run_all_cops_auto_gen_config(line_length_contents, paths)
result
end

def init_dotfile
path = File.expand_path(ConfigLoader::DOTFILE)

if File.exist?(ConfigLoader::DOTFILE)
warn Rainbow("#{ConfigLoader::DOTFILE} already exists at #{path}").red

STATUS_ERROR
else
description = <<-DESC.strip_indent
# The behavior of RuboCop can be controlled via the .rubocop.yml
# configuration file. It makes it possible to enable/disable
# certain cops (checks) and to alter their behavior if they accept
# any parameters. The file can be placed either in your home
# directory or in some project directory.
#
# RuboCop will start looking for the configuration file in the directory
# where the inspected file is and continue its way up to the root directory.
#
# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
DESC

File.open(ConfigLoader::DOTFILE, 'w') do |f|
f.write(description)
end

puts "Writing new #{ConfigLoader::DOTFILE} to #{path}"

STATUS_SUCCESS
end
end

def reset_config_and_auto_gen_file
@config_store = ConfigStore.new
@config_store.options_config = @options[:config] if @options[:config]
Expand Down
5 changes: 4 additions & 1 deletion lib/rubocop/options.rb
Expand Up @@ -117,6 +117,8 @@ def add_auto_gen_options(opts)
option(opts, '--no-auto-gen-timestamp') do
@options[:no_auto_gen_timestamp] = true
end

option(opts, '--init')
end

def add_formatting_options(opts)
Expand Down Expand Up @@ -435,7 +437,8 @@ module OptionsHelp
parallel: ['Use available CPUs to execute inspection in',
'parallel.'],
stdin: ['Pipe source from STDIN, using FILE in offense',
'reports. This is useful for editor integration.']
'reports. This is useful for editor integration.'],
init: 'Generate a .rubocop.yml file in the current directory.'
}.freeze
end
end
1 change: 1 addition & 0 deletions manual/basic_usage.md
Expand Up @@ -117,6 +117,7 @@ Command flag | Description
` --force-exclusion` | Force excluding files specified in the configuration `Exclude` even if they are explicitly passed as arguments.
`-h/--help` | Print usage information.
` --ignore-parent-exlusion` | Ignores all Exclude: settings from all .rubocop.yml files present in parent folders. This is useful when you are importing submodules when you want to test them without being affected by the parent module's rubocop settings.
` --init` | Generate a .rubocop.yml file in the current directory.
`-l/--lint` | Run only lint cops.
`-L/--list-target-files` | List all files RuboCop will inspect.
` --no-auto-gen-timestamp` | Don't include the date and time when --auto-gen-config was run in the config file it generates
Expand Down
30 changes: 30 additions & 0 deletions spec/rubocop/cli_spec.rb
Expand Up @@ -209,6 +209,36 @@ def and_with_args
RESULT
end

describe 'Specify `--init` option to `rubocop` command' do
context 'when .rubocop.yml does not exist' do
it 'generate a .rubocop.yml file' do
expect(cli.run(['--init'])).to eq(0)
expect($stdout.string).to start_with('Writing new .rubocop.yml to')
expect(IO.read('.rubocop.yml')).to eq(<<-YAML.strip_indent)
# The behavior of RuboCop can be controlled via the .rubocop.yml
# configuration file. It makes it possible to enable/disable
# certain cops (checks) and to alter their behavior if they accept
# any parameters. The file can be placed either in your home
# directory or in some project directory.
#
# RuboCop will start looking for the configuration file in the directory
# where the inspected file is and continue its way up to the root directory.
#
# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
YAML
end
end

context 'when .rubocop.yml already exists' do
it 'fails with an error message' do
create_empty_file('.rubocop.yml')

expect(cli.run(['--init'])).to eq(2)
expect($stderr.string).to start_with('.rubocop.yml already exists at')
end
end
end

context 'when --auto-correct is given' do
it 'does not trigger UnneededCopDisableDirective due to ' \
'lines moving around' do
Expand Down
1 change: 1 addition & 0 deletions spec/rubocop/options_spec.rb
Expand Up @@ -61,6 +61,7 @@ def abs(path)
--no-auto-gen-timestamp Do not include the date and time when
the --auto-gen-config was run in the file it
generates.
--init Generate a .rubocop.yml file in the current directory.
-f, --format FORMATTER Choose an output formatter. This option
can be specified multiple times to enable
multiple formatters at the same time.
Expand Down

0 comments on commit ab27faf

Please sign in to comment.