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

Support for global config #169

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ cannot be found by ascending the current working directory (i.e., against a
temporary file buffer in your editor), you can specify the config location with
`--config path/to/.standard.yml`.

You can also set a global configuration by creating a `.standard_global.yml` in your home directory.

## What you might do if you're REALLY clever

Because StandardRB is essentially a wrapper on top of
Expand Down
22 changes: 21 additions & 1 deletion lib/standard/loads_yaml_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,36 @@ module Standard
class LoadsYamlConfig
def initialize
@parses_cli_option = ParsesCliOption.new
@global_config_dir = ENV["HOME"]
end

def call(argv, search_path)
yaml_path = @parses_cli_option.call(argv, "--config") ||
FileFinder.new.call(".standard.yml", search_path)
construct_config(yaml_path, load_standard_yaml(yaml_path))

# global config
global_yaml_path = FileFinder.new.call(".standard_global.yml", @global_config_dir)

standard_yaml = resolve_config(load_standard_yaml(global_yaml_path), load_standard_yaml(yaml_path))
construct_config(yaml_path, standard_yaml)
end

private

def resolve_config(global_config, custom_config)
keys = %w[ruby_version fix format parallel default_ignores]
config = global_config.slice(*keys).merge(custom_config.slice(*keys))

return config unless global_config["ignore"] || custom_config["ignore"]
# merge `ignore`
config["ignore"] = arrayify(custom_config["ignore"]).to_set
.merge(arrayify(global_config["ignore"]).to_set)
.to_a
.compact

config
end

def load_standard_yaml(yaml_path)
if yaml_path
YAML.load_file(yaml_path) || {}
Expand Down
9 changes: 9 additions & 0 deletions test/fixture/config/t/.standard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fix: false
ruby_version: 2.2
ignore:
- hello/**/*
- neat/cool.rb:
- Fake/Hi
- Fake/Lol
- nest/file.rb:
- Fake/T
10 changes: 10 additions & 0 deletions test/fixture/config/t/.standard_global.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fix: true
parallel: true
format: progress
ruby_version: 1.8.7
default_ignores: false
ignore:
- monkey/**/*
- neat/cool.rb:
- Fake/Lol
- Fake/Kek
Empty file.
11 changes: 11 additions & 0 deletions test/fixture/config/u/.standard_global.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fix: true
parallel: true
format: progress
ruby_version: 1.8.7
default_ignores: false
ignore:
- monkey/**/*
- neat/cool.rb:
- Fake/Lol
- Fake/Kek

49 changes: 49 additions & 0 deletions test/standard/builds_config_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,55 @@ def test_specified_standard_yaml_raises
assert_match(/Configuration file ".*fake\.file" not found/, err.message)
end

def test_global_standard_yaml
loads_yaml_config = @subject.instance_variable_get(:@loads_yaml_config)
assert_equal ENV["HOME"], loads_yaml_config.instance_variable_get(:@global_config_dir)

loads_yaml_config.instance_variable_set(:@global_config_dir, path("test/fixture/config/u"))
result = @subject.call([], path("test/fixture/config/u"))

assert_equal DEFAULT_OPTIONS.merge(
auto_correct: true,
safe_auto_correct: true,
parallel: true,
formatters: [["progress", nil]]
), result.rubocop_options

expected_config = RuboCop::ConfigStore.new.tap do |config_store|
config_store.options_config = path("config/ruby-1.8.yml")
options_config = config_store.instance_variable_get("@options_config")
options_config["AllCops"]["Exclude"] |= [path("test/fixture/config/u/monkey/**/*")]
options_config["Fake/Lol"] = {"Exclude" => [path("test/fixture/config/u/neat/cool.rb")]}
options_config["Fake/Kek"] = {"Exclude" => [path("test/fixture/config/u/neat/cool.rb")]}
end.for("").to_h
assert_equal expected_config, result.rubocop_config_store.for("").to_h
end

def test_specified_standard_yaml_overrides_global
loads_yaml_config = @subject.instance_variable_get(:@loads_yaml_config)
assert_equal ENV["HOME"], loads_yaml_config.instance_variable_get(:@global_config_dir)

loads_yaml_config.instance_variable_set(:@global_config_dir, path("test/fixture/config/t"))
result = @subject.call([], path("test/fixture/config/t"))

assert_equal DEFAULT_OPTIONS.merge(
safe_auto_correct: false,
parallel: true,
formatters: [["progress", nil]]
), result.rubocop_options

expected_config = RuboCop::ConfigStore.new.tap do |config_store|
config_store.options_config = path("config/ruby-2.2.yml")
options_config = config_store.instance_variable_get("@options_config")
options_config["AllCops"]["Exclude"] |= [path("test/fixture/config/t/hello/**/*"), path("test/fixture/config/t/monkey/**/*")]
options_config["Fake/Hi"] = {"Exclude" => [path("test/fixture/config/t/neat/cool.rb")]}
options_config["Fake/Lol"] = {"Exclude" => [path("test/fixture/config/t/neat/cool.rb")]}
options_config["Fake/T"] = {"Exclude" => [path("test/fixture/config/t/nest/file.rb")]}
options_config["Fake/Kek"] = {"Exclude" => [path("test/fixture/config/t/neat/cool.rb")]}
end.for("").to_h
assert_equal expected_config, result.rubocop_config_store.for("").to_h
end

private

def config_store(config_root = nil, rubocop_yml = "config/base.yml", ruby_version = RUBY_VERSION)
Expand Down