diff --git a/docs/configuration.rst b/docs/configuration.rst index 817a16d..f7f8ffa 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -115,6 +115,21 @@ return code will be: * ``1`` if one or more errors occur * ``2`` if no errors occur, but one or more warnings occur +YAML files extensions +--------------------- + +To configure what yamllint should consider as YAML files, set ``yaml-files`` +configuration option. The default is: + +.. code-block:: yaml + + yaml-files: + - '*.yaml' + - '*.yml' + +The same rules as for ignoring paths apply (``.gitignore``-style path pattern, +see below). + Ignoring paths -------------- diff --git a/tests/test_cli.py b/tests/test_cli.py index b5ef82a..fbdf75f 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -29,6 +29,7 @@ import unittest from tests.common import build_temp_workspace from yamllint import cli +from yamllint import config class CommandLineTestCase(unittest.TestCase): @@ -73,8 +74,9 @@ class CommandLineTestCase(unittest.TestCase): shutil.rmtree(cls.wd) def test_find_files_recursively(self): + conf = config.YamlLintConfig('extends: default') self.assertEqual( - sorted(cli.find_files_recursively([self.wd])), + sorted(cli.find_files_recursively([self.wd], conf)), [os.path.join(self.wd, 'a.yaml'), os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), @@ -85,14 +87,14 @@ class CommandLineTestCase(unittest.TestCase): items = [os.path.join(self.wd, 'sub/ok.yaml'), os.path.join(self.wd, 'empty-dir')] self.assertEqual( - sorted(cli.find_files_recursively(items)), + sorted(cli.find_files_recursively(items, conf)), [os.path.join(self.wd, 'sub/ok.yaml')], ) items = [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's')] self.assertEqual( - sorted(cli.find_files_recursively(items)), + sorted(cli.find_files_recursively(items, conf)), [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml')], ) @@ -100,11 +102,77 @@ class CommandLineTestCase(unittest.TestCase): items = [os.path.join(self.wd, 'sub'), os.path.join(self.wd, '/etc/another/file')] self.assertEqual( - sorted(cli.find_files_recursively(items)), + sorted(cli.find_files_recursively(items, conf)), [os.path.join(self.wd, '/etc/another/file'), os.path.join(self.wd, 'sub/ok.yaml')], ) + conf = config.YamlLintConfig('extends: default\n' + 'yaml-files:\n' + ' - \'*.yaml\' \n') + self.assertEqual( + sorted(cli.find_files_recursively([self.wd], conf)), + [os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml')] + ) + + conf = config.YamlLintConfig('extends: default\n' + 'yaml-files:\n' + ' - \'*.yml\'\n') + self.assertEqual( + sorted(cli.find_files_recursively([self.wd], conf)), + [os.path.join(self.wd, 'empty.yml')] + ) + + conf = config.YamlLintConfig('extends: default\n' + 'yaml-files:\n' + ' - \'*.json\'\n') + self.assertEqual( + sorted(cli.find_files_recursively([self.wd], conf)), + [os.path.join(self.wd, 'no-yaml.json')] + ) + + conf = config.YamlLintConfig('extends: default\n' + 'yaml-files:\n' + ' - \'*\'\n') + self.assertEqual( + sorted(cli.find_files_recursively([self.wd], conf)), + [os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'no-yaml.json'), + os.path.join(self.wd, 'non-ascii/utf-8'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml')] + ) + + conf = config.YamlLintConfig('extends: default\n' + 'yaml-files:\n' + ' - \'*.yaml\'\n' + ' - \'*\'\n' + ' - \'**\'\n') + self.assertEqual( + sorted(cli.find_files_recursively([self.wd], conf)), + [os.path.join(self.wd, 'a.yaml'), + os.path.join(self.wd, 'empty.yml'), + os.path.join(self.wd, 'no-yaml.json'), + os.path.join(self.wd, 'non-ascii/utf-8'), + os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), + os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'warn.yaml')] + ) + + conf = config.YamlLintConfig('extends: default\n' + 'yaml-files:\n' + ' - \'s/**\'\n' + ' - \'**/utf-8\'\n') + self.assertEqual( + sorted(cli.find_files_recursively([self.wd], conf)), + [os.path.join(self.wd, 'non-ascii/utf-8')] + ) + def test_run_with_bad_arguments(self): sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: diff --git a/yamllint/cli.py b/yamllint/cli.py index 9975b4e..d8f4927 100644 --- a/yamllint/cli.py +++ b/yamllint/cli.py @@ -27,13 +27,14 @@ from yamllint.config import YamlLintConfig, YamlLintConfigError from yamllint.linter import PROBLEM_LEVELS -def find_files_recursively(items): +def find_files_recursively(items, conf): for item in items: if os.path.isdir(item): for root, dirnames, filenames in os.walk(item): - for filename in [f for f in filenames - if f.endswith(('.yml', '.yaml'))]: - yield os.path.join(root, filename) + for f in filenames: + filepath = os.path.join(root, f) + if conf.is_yaml_file(filepath): + yield filepath else: yield item @@ -163,7 +164,7 @@ def run(argv=None): max_level = 0 - for file in find_files_recursively(args.files): + for file in find_files_recursively(args.files, conf): filepath = file[2:] if file.startswith('./') else file try: with open(file) as f: diff --git a/yamllint/conf/default.yaml b/yamllint/conf/default.yaml index da9701e..f0c1edd 100644 --- a/yamllint/conf/default.yaml +++ b/yamllint/conf/default.yaml @@ -1,5 +1,9 @@ --- +yaml-files: + - '*.yaml' + - '*.yml' + rules: braces: enable brackets: enable diff --git a/yamllint/config.py b/yamllint/config.py index 2cafe8a..a9384d6 100644 --- a/yamllint/config.py +++ b/yamllint/config.py @@ -32,6 +32,9 @@ class YamlLintConfig(object): self.ignore = None + self.yaml_files = pathspec.PathSpec.from_lines( + 'gitwildmatch', ['*.yaml', '*.yml']) + if file is not None: with open(file) as f: content = f.read() @@ -42,6 +45,9 @@ class YamlLintConfig(object): def is_file_ignored(self, filepath): return self.ignore and self.ignore.match_file(filepath) + def is_yaml_file(self, filepath): + return self.yaml_files.match_file(filepath) + def enabled_rules(self, filepath): return [yamllint.rules.get(id) for id, val in self.rules.items() if val is not False and ( @@ -96,6 +102,15 @@ class YamlLintConfig(object): self.ignore = pathspec.PathSpec.from_lines( 'gitwildmatch', conf['ignore'].splitlines()) + if 'yaml-files' in conf: + if not (isinstance(conf['yaml-files'], list) + and all(isinstance(i, str) for i in conf['yaml-files'])): + raise YamlLintConfigError( + 'invalid config: yaml-files ' + 'should be a list of file patterns') + self.yaml_files = pathspec.PathSpec.from_lines('gitwildmatch', + conf['yaml-files']) + def validate(self): for id in self.rules: try: