Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 016f336

Browse files
committed
squash! Add support for $XDG_CONFIG_HOME/rspec/options
XDG config file completely overrides HOME file.
1 parent f165f86 commit 016f336

File tree

6 files changed

+79
-32
lines changed

6 files changed

+79
-32
lines changed

features/configuration/default_path.feature

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ Feature: Setting the default spec path
55
This is supported by a `--default-path` option, which is set to `spec` by
66
default. If you prefer to keep your specs in a different directory, or assign
77
an individual file to `--default-path`, you can do so on the command line or
8-
in a configuration file (`.rspec`, `~/.rspec`,
9-
`$XDG_CONFIG_HOME/rspec/options`, or a custom file).
8+
in a configuration file (for example `.rspec`).
109

1110
**NOTE:** this option is not supported on `RSpec.configuration`, as it needs to be
1211
set before spec files are loaded.

features/configuration/read_options_from_file.feature

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
Feature: read command line configuration options from files
22

3-
RSpec reads command line configuration options from files in three different
4-
locations:
3+
RSpec reads command line configuration options from several different files,
4+
all conforming to a specific level of specificity. Options from a higher
5+
specificity will override conflicting options from lower specificity files.
56

6-
* Local: `./.rspec-local` (i.e. in the project's root directory, can be
7-
gitignored)
7+
The locations are:
8+
9+
* **Global options:** First file from the following list (i.e. the user's
10+
personal global options)
811

9-
* Project: `./.rspec` (i.e. in the project's root directory, usually
12+
* `$XDG_CONFIG_HOME/rspec/options` ([XDG Base Directory
13+
Specification](https://specifications.freedesktop.org/basedir-spec/latest/)
14+
config)
15+
* `~/.rspec`
16+
17+
* **Project options:** `./.rspec` (i.e. in the project's root directory, usually
1018
checked into the project)
1119

12-
* Global (HOME): `~/.rspec` (i.e. in the user's home directory)
20+
* **Local:** `./.rspec-local` (i.e. in the project's root directory, can be
21+
gitignored)
1322

14-
* Global (XDG): `$XDG_CONFIG_HOME/rspec/options` (i.e. in the user's
15-
[the XDG Base Directory
16-
Specification](https://specifications.freedesktop.org/basedir-spec/latest/)
17-
config directory)
23+
Options specified at the command-line has even higher specificity, as does
24+
the `SPEC_OPTS` environment variable. That means that a command-line option
25+
would overwrite a project-specific option, which overrides the global value
26+
of that option.
1827

19-
Configuration options are loaded from `$XDG_CONFIG_HOME/rspec/options`,
20-
`~/.rspec`, `.rspec`, `.rspec-local`, command line switches, and the
21-
`SPEC_OPTS` environment variable (listed in lowest to highest precedence; for
22-
example, an option in `~/.rspec` can be overridden by an option in
23-
`.rspec-local`).
28+
The default options files can all be ignored using the `--options`
29+
command-line argument, which selects a custom file to load options from.
2430

2531
Scenario: Color set in `.rspec`
2632
Given a file named ".rspec" with:

lib/rspec/core/configuration.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,24 @@ module Core
99

1010
# Stores runtime configuration information.
1111
#
12-
# Configuration options are loaded from `$XDG_CONFIG_HOME/rspec/options`,
13-
# `~/.rspec`, `.rspec`, `.rspec-local`, command line switches, and the
14-
# `SPEC_OPTS` environment variable (listed in lowest to highest precedence;
15-
# for example, an option in `~/.rspec` can be overridden by an option in
16-
# `.rspec-local`).
12+
# Configuration options are loaded from multiple files and joined together
13+
# with command-line switches and the `SPEC_OPTS` environment variable.
14+
#
15+
# Precedence order (where later entries overwrite earlier entries on
16+
# conflicts):
17+
#
18+
# * Global (`$XDG_CONFIG_HOME/rspec/options`, or `~/.rspec` if it does
19+
# not exist)
20+
# * Project-specific (`./.rspec`)
21+
# * Local (`./.rspec-local`)
22+
# * Command-line options
23+
# * `SPEC_OPTS`
24+
#
25+
# For example, an option set in the local file will override an option set
26+
# in your global file.
27+
#
28+
# The global, project-specific and local files can all be overridden with a
29+
# separate custom file using the --options command-line parameter.
1730
#
1831
# @example Standard settings
1932
# RSpec.configure do |c|

lib/rspec/core/configuration_options.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def file_options
122122
if custom_options_file
123123
[custom_options]
124124
else
125-
[global_xdg_options, global_options, project_options, local_options]
125+
[global_options, project_options, local_options]
126126
end
127127
end
128128

@@ -155,10 +155,6 @@ def global_options
155155
@global_options ||= options_from(global_options_file)
156156
end
157157

158-
def global_xdg_options
159-
@global_xdg_options ||= options_from(global_xdg_options_file)
160-
end
161-
162158
def options_from(path)
163159
args = args_from_options_file(path)
164160
parse_args_ignoring_files_or_dirs_to_run(args, path)
@@ -197,6 +193,17 @@ def local_options_file
197193
end
198194

199195
def global_options_file
196+
xdg_options_file_if_exists || home_options_file_path
197+
end
198+
199+
def xdg_options_file_if_exists
200+
path = xdg_options_file_path
201+
if path && File.exist?(path)
202+
path
203+
end
204+
end
205+
206+
def home_options_file_path
200207
File.join(File.expand_path("~"), ".rspec")
201208
rescue ArgumentError
202209
# :nocov:
@@ -205,7 +212,7 @@ def global_options_file
205212
# :nocov:
206213
end
207214

208-
def global_xdg_options_file
215+
def xdg_options_file_path
209216
xdg_config_home = resolve_xdg_config_home
210217
if xdg_config_home
211218
File.join(xdg_config_home, "rspec", "options")

spec/rspec/core/configuration_options_spec.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,15 +456,36 @@ def expect_parsing_to_fail_mentioning_source(source, options=[])
456456
create_fixture_file("~/.config/rspec/options", "--order defined")
457457
with_env_vars 'SPEC_OPTS' => "--example 'foo bar'" do
458458
options = parse_options("--drb")
459-
expect(options[:color_mode]).to eq(:on)
459+
# $XDG_CONFIG_HOME/rspec/options file ("order") is read, but ~/.rspec
460+
# file ("color") is not read because ~/.rspec has lower priority over
461+
# the file in the XDG config directory.
462+
expect(options[:order]).to eq("defined")
463+
expect(options[:color_mode]).to be_nil
464+
460465
expect(options[:requires]).to eq(["some_file"])
461466
expect(options[:full_description]).to eq([/foo\ bar/])
462467
expect(options[:drb]).to be_truthy
463468
expect(options[:formatters]).to eq([['global']])
464-
expect(options[:order]).to eq("defined")
465469
end
466470
end
467471

472+
it "reads ~/.rspec if $XDG_CONFIG_HOME/rspec/options is not found" do
473+
create_fixture_file("~/.rspec", "--force-color")
474+
475+
options = parse_options()
476+
expect(options[:color_mode]).to eq(:on)
477+
expect(options[:order]).to be_nil
478+
end
479+
480+
it "does not read ~/.rspec if $XDG_CONFIG_HOME/rspec/options is present" do
481+
create_fixture_file("~/.rspec", "--force-color")
482+
create_fixture_file("~/.config/rspec/options", "--order defined")
483+
484+
options = parse_options()
485+
expect(options[:color_mode]).to be_nil
486+
expect(options[:order]).to eq("defined")
487+
end
488+
468489
it "uses $XDG_CONFIG_HOME environment variable when set to find XDG global options" do
469490
create_fixture_file("~/.config/rspec/options", "--format default_xdg")
470491
create_fixture_file("~/.custom-config/rspec/options", "--format overridden_xdg")

spec/support/isolated_home_directory.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
RSpec.shared_context "isolated home directory" do
66
around do |ex|
77
Dir.mktmpdir do |tmp_dir|
8-
# If user has a custom $XDG_CONFIG_HOME, also clear that out when
9-
# changing $HOME so tests don't touch the user's real config files.
8+
# If user running this test suite has a custom $XDG_CONFIG_HOME, also
9+
# clear that out when changing $HOME so tests don't touch the user's real
10+
# configuration files.
1011
without_env_vars "XDG_CONFIG_HOME" do
1112
with_env_vars "HOME" => tmp_dir do
1213
ex.call

0 commit comments

Comments
 (0)