Config: Allow a user-global configuration file

Instead of just looking for `.yamllint` in the current working
directory, also look for `~/.config/yamllint/config` (using
`$XDG_CONFIG_HOME` or `$HOME`, see [1] and [2] for information).

[1]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-0.6.html
[2]: https://wiki.archlinux.org/index.php/XDG_Base_Directory_support

Closes: #6
This commit is contained in:
Adrien Vergé 2016-04-21 22:24:24 +02:00
parent 1f1757ced4
commit eabd349902
4 changed files with 66 additions and 4 deletions

View File

@ -82,7 +82,7 @@ Usage
yamllint -d relaxed file.yaml yamllint -d relaxed file.yaml
# Use a custom lint configuration # Use a custom lint configuration
yamllint -c ~/myconfig file.yml yamllint -c /path/to/myconfig file-to-lint.yaml
.. code:: bash .. code:: bash

View File

@ -5,12 +5,20 @@ yamllint uses a set of *rules* to check sources files for problems. Each rule is
independent from the others, and can be enabled, disabled or tweaked. All these independent from the others, and can be enabled, disabled or tweaked. All these
settings can be gathered in a configuration file. settings can be gathered in a configuration file.
To use a custom configuration file, either name it ``.yamllint`` in your working To use a custom configuration file, use the ``-c`` option:
directory, or use the ``-c`` option:
.. code:: bash .. code:: bash
yamllint -c ~/myconfig file.yaml yamllint -c /path/to/myconfig file-to-lint.yaml
If ``-c`` is not provided, yamllint will look for a configuration file in the
following locations (by order of preference):
- ``.yamllint`` in the current working directory
- ``$XDG_CONFIG_HOME/yamllint/config``
- ``$HOME/.config/yamllint/config``
Finally if no config file is found, the default configuration is applied.
Default configuration Default configuration
--------------------- ---------------------

View File

@ -153,6 +153,49 @@ class CommandLineTestCase(unittest.TestCase):
self.assertEqual(out, '') self.assertEqual(out, '')
self.assertRegexpMatches(err, r'^invalid config: not a dict') self.assertRegexpMatches(err, r'^invalid config: not a dict')
def test_run_with_config_file(self):
with open(os.path.join(self.wd, 'config'), 'w') as f:
f.write('rules: {trailing-spaces: disable}')
with self.assertRaises(SystemExit) as ctx:
cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml')))
self.assertEqual(ctx.exception.code, 0)
with open(os.path.join(self.wd, 'config'), 'w') as f:
f.write('rules: {trailing-spaces: enable}')
with self.assertRaises(SystemExit) as ctx:
cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml')))
self.assertEqual(ctx.exception.code, 1)
def test_run_with_user_global_config_file(self):
home = os.path.join(self.wd, 'fake-home')
os.mkdir(home)
dir = os.path.join(home, '.config')
os.mkdir(dir)
dir = os.path.join(dir, 'yamllint')
os.mkdir(dir)
config = os.path.join(dir, 'config')
temp = os.environ['HOME']
os.environ['HOME'] = home
with open(config, 'w') as f:
f.write('rules: {trailing-spaces: disable}')
with self.assertRaises(SystemExit) as ctx:
cli.run((os.path.join(self.wd, 'a.yaml'), ))
self.assertEqual(ctx.exception.code, 0)
with open(config, 'w') as f:
f.write('rules: {trailing-spaces: enable}')
with self.assertRaises(SystemExit) as ctx:
cli.run((os.path.join(self.wd, 'a.yaml'), ))
self.assertEqual(ctx.exception.code, 1)
os.environ['HOME'] = temp
def test_run_version(self): def test_run_version(self):
sys.stdout, sys.stderr = StringIO(), StringIO() sys.stdout, sys.stderr = StringIO(), StringIO()
with self.assertRaises(SystemExit) as ctx: with self.assertRaises(SystemExit) as ctx:

View File

@ -86,6 +86,15 @@ def run(argv=None):
'simultaneously.', file=sys.stderr) 'simultaneously.', file=sys.stderr)
sys.exit(-1) sys.exit(-1)
# User-global config is supposed to be in ~/.config/yamllint/config
user_global_config = None
if 'XDG_CONFIG_HOME' in os.environ:
user_global_config = os.path.join(
os.environ['XDG_CONFIG_HOME'], 'yamllint', 'config')
elif 'HOME' in os.environ:
user_global_config = os.path.join(
os.environ['HOME'], '.config', 'yamllint', 'config')
try: try:
if args.config_data is not None: if args.config_data is not None:
if args.config_data != '' and ':' not in args.config_data: if args.config_data != '' and ':' not in args.config_data:
@ -95,6 +104,8 @@ def run(argv=None):
conf = YamlLintConfig(file=args.config_file) conf = YamlLintConfig(file=args.config_file)
elif os.path.isfile('.yamllint'): elif os.path.isfile('.yamllint'):
conf = YamlLintConfig(file='.yamllint') conf = YamlLintConfig(file='.yamllint')
elif user_global_config and os.path.isfile(user_global_config):
conf = YamlLintConfig(file=user_global_config)
else: else:
conf = YamlLintConfig('extends: default') conf = YamlLintConfig('extends: default')
except YamlLintConfigError as e: except YamlLintConfigError as e: