Compare commits

..

11 Commits

Author SHA1 Message Date
Adrien Vergé
13a0f11e7c yamllint version 1.20.0 2019-12-26 16:06:29 +01:00
Sylvestre Ledru
43b95e99d1 Use 'syntax' as rule name upon syntax errors 2019-12-17 19:29:49 +01:00
ffapitalle
8fa9eb3ced Add --no-warnings option to suppress warning messages
Use `--no-warnings` option to hide warning messages. It only shows
problems marked as errors.
2019-12-12 09:12:53 +01:00
Adrien Vergé
da3788e95a yamllint version 1.19.0 2019-11-19 11:28:21 +01:00
Joel Baranick
fb400dc64b Allow disabling all checks for a file
Allow disabling of a file, even if it is invalid YAML (syntax error) by
including `# yamllint disable-file` in the first line.
2019-11-19 11:26:31 +01:00
Adrien Vergé
92324ae730 yamllint version 1.18.0 2019-10-15 09:49:20 +02:00
Imran Iqbal
7359785ea0 fix(default.yaml): disable empty-values & octal-values by default
* Close #204
2019-10-15 09:41:32 +02:00
Hossein Zolfi
579a975b70 docs: Fix pre-commit config file
* pre-commit show warning for unsupported key (sha)
* Demonstrate how to use custom yamllint
2019-10-01 11:36:07 +02:00
Imran Iqbal
f3d9196aa0 docs(configuration): improve yaml-files code example
* A straight copy/paste of the existing example into the `.yamllint` file results in a `yamllint` error!
2019-09-10 19:47:25 +02:00
Ibrahim AshShohail
881d301883 feat: Support reading config from .yamllint.yml and .yamllint.yaml
Signed-off-by: Ibrahim AshShohail <me@ibrasho.com>
2019-08-27 09:49:09 +02:00
Adrien Vergé
b62b424dd4 feat: Lint .yamllint by default 2019-08-26 10:01:40 +02:00
15 changed files with 234 additions and 21 deletions

View File

@@ -1,6 +1,26 @@
Changelog Changelog
========= =========
1.20.0 (2019-12-26)
-------------------
- Add --no-warnings option to suppress warning messages
- Use 'syntax' as rule name upon syntax errors
1.19.0 (2019-11-19)
-------------------
- Allow disabling all checks for a file with ``# yamllint disable-file``
1.18.0 (2019-10-15)
-------------------
- Lint ``.yamllint`` config file by default
- Also read config from ``.yamllint.yml`` and ``.yamllint.yaml``
- Improve documentation for ``yaml-files``
- Update documentation for ``pre-commit``
- Explicitly disable ``empty-values`` and ``octal-values`` rules
1.17.0 (2019-08-12) 1.17.0 (2019-08-12)
------------------- -------------------

View File

@@ -14,7 +14,8 @@ To use a custom configuration file, use the ``-c`` option:
If ``-c`` is not provided, yamllint will look for a configuration file in the If ``-c`` is not provided, yamllint will look for a configuration file in the
following locations (by order of preference): following locations (by order of preference):
- ``.yamllint`` in the current working directory - ``.yamllint``, ``.yamllint.yaml`` or ``.yamllint.yml`` in the current working
directory
- ``$XDG_CONFIG_HOME/yamllint/config`` - ``$XDG_CONFIG_HOME/yamllint/config``
- ``~/.config/yamllint/config`` - ``~/.config/yamllint/config``
@@ -115,6 +116,9 @@ return code will be:
* ``1`` if one or more errors occur * ``1`` if one or more errors occur
* ``2`` if no errors occur, but one or more warnings occur * ``2`` if no errors occur, but one or more warnings occur
If the script is invoked with the ``--no-warnings`` option, it won't output
warning level problems, only error level ones.
YAML files extensions YAML files extensions
--------------------- ---------------------
@@ -126,6 +130,7 @@ configuration option. The default is:
yaml-files: yaml-files:
- '*.yaml' - '*.yaml'
- '*.yml' - '*.yml'
- '.yamllint'
The same rules as for ignoring paths apply (``.gitignore``-style path pattern, The same rules as for ignoring paths apply (``.gitignore``-style path pattern,
see below). see below).

View File

@@ -73,3 +73,31 @@ It is possible, although not recommend, to disabled **all** rules:
If you need to disable multiple rules, it is allowed to chain rules like this: If you need to disable multiple rules, it is allowed to chain rules like this:
``# yamllint disable rule:hyphens rule:commas rule:indentation``. ``# yamllint disable rule:hyphens rule:commas rule:indentation``.
Disabling all checks for a file
-------------------------------
To prevent yamllint from reporting problems for a specific file, add the
directive comment ``# yamllint disable-file`` as the first line of the file.
For instance:
.. code-block:: yaml
# yamllint disable-file
# The following mapping contains the same key twice, but I know what I'm doing:
key: value 1
key: value 2
- This line is waaaaaaaaaay too long but yamllint will not report anything about it.
This line will be checked by yamllint.
or:
.. code-block:: jinja
# yamllint disable-file
# This file is not valid YAML because it is a Jinja template
{% if extra_info %}
key1: value1
{% endif %}
key2: value2

View File

@@ -10,8 +10,10 @@ Here is an example, to add in your .pre-commit-config.yaml
.. code:: yaml .. code:: yaml
--- ---
# Update the sha variable with the release version that you want, from the yamllint repo # Update the rev variable with the release version that you want, from the yamllint repo
# You can pass your custom .yamllint with args attribute.
- repo: https://github.com/adrienverge/yamllint.git - repo: https://github.com/adrienverge/yamllint.git
sha: v1.8.1 rev: v1.17.0
hooks: hooks:
- id: yamllint - id: yamllint
args: [-c=/path/to/.yamllint]

View File

@@ -28,7 +28,9 @@ class OctalValuesTestCase(RuleTestCase):
self.check('user-city: 0o10', conf) self.check('user-city: 0o10', conf)
def test_implicit_octal_values(self): def test_implicit_octal_values(self):
conf = ('octal-values: {forbid-implicit-octal: true}\n' conf = ('octal-values:\n'
' forbid-implicit-octal: true\n'
' forbid-explicit-octal: false\n'
'new-line-at-end-of-file: disable\n' 'new-line-at-end-of-file: disable\n'
'document-start: disable\n') 'document-start: disable\n')
self.check('user-city: 010', conf, problem=(1, 15)) self.check('user-city: 010', conf, problem=(1, 15))
@@ -50,7 +52,9 @@ class OctalValuesTestCase(RuleTestCase):
' - 0e3\n', conf) ' - 0e3\n', conf)
def test_explicit_octal_values(self): def test_explicit_octal_values(self):
conf = ('octal-values: {forbid-explicit-octal: true}\n' conf = ('octal-values:\n'
' forbid-implicit-octal: false\n'
' forbid-explicit-octal: true\n'
'new-line-at-end-of-file: disable\n' 'new-line-at-end-of-file: disable\n'
'document-start: disable\n') 'document-start: disable\n')
self.check('user-city: 0o10', conf, problem=(1, 16)) self.check('user-city: 0o10', conf, problem=(1, 16))

View File

@@ -530,5 +530,40 @@ class CommandLineTestCase(unittest.TestCase):
out, err = sys.stdout.getvalue(), sys.stderr.getvalue() out, err = sys.stdout.getvalue(), sys.stderr.getvalue()
self.assertEqual(out, ( self.assertEqual(out, (
'stdin:2:10: [error] syntax error: ' 'stdin:2:10: [error] syntax error: '
'mapping values are not allowed here\n')) 'mapping values are not allowed here (syntax)\n'))
self.assertEqual(err, '') self.assertEqual(err, '')
def test_run_no_warnings(self):
file = os.path.join(self.wd, 'a.yaml')
sys.stdout, sys.stderr = StringIO(), StringIO()
with self.assertRaises(SystemExit) as ctx:
cli.run((file, '--no-warnings', '-f', 'auto'))
self.assertEqual(ctx.exception.code, 1)
out, err = sys.stdout.getvalue(), sys.stderr.getvalue()
self.assertEqual(out, (
'%s\n'
' 2:4 error trailing spaces (trailing-spaces)\n'
' 3:4 error no new line character at the end of file '
'(new-line-at-end-of-file)\n'
'\n' % file))
self.assertEqual(err, '')
file = os.path.join(self.wd, 'warn.yaml')
sys.stdout, sys.stderr = StringIO(), StringIO()
with self.assertRaises(SystemExit) as ctx:
cli.run((file, '--no-warnings', '-f', 'auto'))
self.assertEqual(ctx.exception.code, 0)
def test_run_no_warnings_and_strict(self):
file = os.path.join(self.wd, 'warn.yaml')
sys.stdout, sys.stderr = StringIO(), StringIO()
with self.assertRaises(SystemExit) as ctx:
cli.run((file, '--no-warnings', '-s'))
self.assertEqual(ctx.exception.code, 2)

View File

@@ -448,11 +448,13 @@ class IgnorePathConfigTestCase(unittest.TestCase):
out = sys.stdout.getvalue() out = sys.stdout.getvalue()
out = '\n'.join(sorted(out.splitlines())) out = '\n'.join(sorted(out.splitlines()))
docstart = '[warning] missing document start "---" (document-start)'
keydup = '[error] duplication of key "key" in mapping (key-duplicates)' keydup = '[error] duplication of key "key" in mapping (key-duplicates)'
trailing = '[error] trailing spaces (trailing-spaces)' trailing = '[error] trailing spaces (trailing-spaces)'
hyphen = '[error] too many spaces after hyphen (hyphens)' hyphen = '[error] too many spaces after hyphen (hyphens)'
self.assertEqual(out, '\n'.join(( self.assertEqual(out, '\n'.join((
'./.yamllint:1:1: ' + docstart,
'./bin/file.lint-me-anyway.yaml:3:3: ' + keydup, './bin/file.lint-me-anyway.yaml:3:3: ' + keydup,
'./bin/file.lint-me-anyway.yaml:4:17: ' + trailing, './bin/file.lint-me-anyway.yaml:4:17: ' + trailing,
'./bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen,

View File

@@ -302,3 +302,104 @@ class YamllintDirectivesTestCase(RuleTestCase):
' c: [x]\n', ' c: [x]\n',
conf, conf,
problem=(6, 2, 'comments-indentation')) problem=(6, 2, 'comments-indentation'))
def test_disable_file_directive(self):
conf = ('comments: {min-spaces-from-content: 2}\n'
'comments-indentation: {}\n')
self.check('# yamllint disable-file\n'
'---\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf)
self.check('# yamllint disable-file\n'
'---\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf)
self.check('#yamllint disable-file\n'
'---\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf)
self.check('#yamllint disable-file \n'
'---\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf)
self.check('---\n'
'# yamllint disable-file\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf,
problem1=(3, 8, 'comments'),
problem2=(5, 2, 'comments-indentation'))
self.check('# yamllint disable-file: rules cannot be specified\n'
'---\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf,
problem1=(3, 8, 'comments'),
problem2=(5, 2, 'comments-indentation'))
self.check('AAAA yamllint disable-file\n'
'---\n'
'- a: 1 # comment too close\n'
' b:\n'
' # wrong indentation\n'
' c: [x]\n',
conf,
problem1=(1, 1, 'document-start'),
problem2=(3, 8, 'comments'),
problem3=(5, 2, 'comments-indentation'))
def test_disable_file_directive_not_at_first_position(self):
self.check('# yamllint disable-file\n'
'---\n'
'- bad : colon and spaces \n',
self.conf)
self.check('---\n'
'# yamllint disable-file\n'
'- bad : colon and spaces \n',
self.conf,
problem1=(3, 7, 'colons'),
problem2=(3, 26, 'trailing-spaces'))
def test_disable_file_directive_with_syntax_error(self):
self.check('# This file is not valid YAML (it is a Jinja template)\n'
'{% if extra_info %}\n'
'key1: value1\n'
'{% endif %}\n'
'key2: value2\n',
self.conf,
problem=(2, 2, 'syntax'))
self.check('# yamllint disable-file\n'
'# This file is not valid YAML (it is a Jinja template)\n'
'{% if extra_info %}\n'
'key1: value1\n'
'{% endif %}\n'
'key2: value2\n',
self.conf)
def test_disable_file_directive_with_dos_lines(self):
self.check('# yamllint disable-file\r\n'
'---\r\n'
'- bad : colon and spaces \r\n',
self.conf)
self.check('# yamllint disable-file\r\n'
'# This file is not valid YAML (it is a Jinja template)\r\n'
'{% if extra_info %}\r\n'
'key1: value1\r\n'
'{% endif %}\r\n'
'key2: value2\r\n',
self.conf)

View File

@@ -22,7 +22,7 @@ indentation, etc."""
APP_NAME = 'yamllint' APP_NAME = 'yamllint'
APP_VERSION = '1.17.0' APP_VERSION = '1.20.0'
APP_DESCRIPTION = __doc__ APP_DESCRIPTION = __doc__
__author__ = u'Adrien Vergé' __author__ = u'Adrien Vergé'

View File

@@ -84,11 +84,14 @@ class Format(object):
return line return line
def show_problems(problems, file, args_format): def show_problems(problems, file, args_format, no_warn):
max_level = 0 max_level = 0
first = True first = True
for problem in problems: for problem in problems:
max_level = max(max_level, PROBLEM_LEVELS[problem.level])
if no_warn and (problem.level != 'error'):
continue
if args_format == 'parsable': if args_format == 'parsable':
print(Format.parsable(problem, file)) print(Format.parsable(problem, file))
elif args_format == 'colored' or \ elif args_format == 'colored' or \
@@ -102,7 +105,6 @@ def show_problems(problems, file, args_format):
print(file) print(file)
first = False first = False
print(Format.standard(problem, file)) print(Format.standard(problem, file))
max_level = max(max_level, PROBLEM_LEVELS[problem.level])
if not first and args_format != 'parsable': if not first and args_format != 'parsable':
print('') print('')
@@ -133,6 +135,9 @@ def run(argv=None):
action='store_true', action='store_true',
help='return non-zero exit code on warnings ' help='return non-zero exit code on warnings '
'as well as errors') 'as well as errors')
parser.add_argument('--no-warnings',
action='store_true',
help='output only error level problems')
parser.add_argument('-v', '--version', action='version', parser.add_argument('-v', '--version', action='version',
version='{} {}'.format(APP_NAME, APP_VERSION)) version='{} {}'.format(APP_NAME, APP_VERSION))
@@ -154,6 +159,10 @@ 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 os.path.isfile('.yamllint.yaml'):
conf = YamlLintConfig(file='.yamllint.yaml')
elif os.path.isfile('.yamllint.yml'):
conf = YamlLintConfig(file='.yamllint.yml')
elif os.path.isfile(user_global_config): elif os.path.isfile(user_global_config):
conf = YamlLintConfig(file=user_global_config) conf = YamlLintConfig(file=user_global_config)
else: else:
@@ -172,7 +181,8 @@ def run(argv=None):
except EnvironmentError as e: except EnvironmentError as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
sys.exit(-1) sys.exit(-1)
prob_level = show_problems(problems, file, args_format=args.format) prob_level = show_problems(problems, file, args_format=args.format,
no_warn=args.no_warnings)
max_level = max(max_level, prob_level) max_level = max(max_level, prob_level)
# read yaml from stdin # read yaml from stdin
@@ -182,7 +192,8 @@ def run(argv=None):
except EnvironmentError as e: except EnvironmentError as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
sys.exit(-1) sys.exit(-1)
prob_level = show_problems(problems, 'stdin', args_format=args.format) prob_level = show_problems(problems, 'stdin', args_format=args.format,
no_warn=args.no_warnings)
max_level = max(max_level, prob_level) max_level = max(max_level, prob_level)
if max_level == PROBLEM_LEVELS['error']: if max_level == PROBLEM_LEVELS['error']:

View File

@@ -3,6 +3,7 @@
yaml-files: yaml-files:
- '*.yaml' - '*.yaml'
- '*.yml' - '*.yml'
- '.yamllint'
rules: rules:
braces: enable braces: enable
@@ -17,7 +18,7 @@ rules:
document-start: document-start:
level: warning level: warning
empty-lines: enable empty-lines: enable
empty-values: enable empty-values: disable
hyphens: enable hyphens: enable
indentation: enable indentation: enable
key-duplicates: enable key-duplicates: enable
@@ -25,7 +26,7 @@ rules:
line-length: enable line-length: enable
new-line-at-end-of-file: enable new-line-at-end-of-file: enable
new-lines: enable new-lines: enable
octal-values: enable octal-values: disable
quoted-strings: disable quoted-strings: disable
trailing-spaces: enable trailing-spaces: enable
truthy: truthy:

View File

@@ -33,7 +33,7 @@ class YamlLintConfig(object):
self.ignore = None self.ignore = None
self.yaml_files = pathspec.PathSpec.from_lines( self.yaml_files = pathspec.PathSpec.from_lines(
'gitwildmatch', ['*.yaml', '*.yml']) 'gitwildmatch', ['*.yaml', '*.yml', '.yamllint'])
if file is not None: if file is not None:
with open(file) as f: with open(file) as f:

View File

@@ -180,7 +180,7 @@ def get_syntax_error(buffer):
except yaml.error.MarkedYAMLError as e: except yaml.error.MarkedYAMLError as e:
problem = LintProblem(e.problem_mark.line + 1, problem = LintProblem(e.problem_mark.line + 1,
e.problem_mark.column + 1, e.problem_mark.column + 1,
'syntax error: ' + e.problem) 'syntax error: ' + e.problem + ' (syntax)')
problem.level = 'error' problem.level = 'error'
return problem return problem
@@ -189,6 +189,10 @@ def _run(buffer, conf, filepath):
assert hasattr(buffer, '__getitem__'), \ assert hasattr(buffer, '__getitem__'), \
'_run() argument must be a buffer, not a stream' '_run() argument must be a buffer, not a stream'
first_line = next(parser.line_generator(buffer)).content
if re.match(r'^#\s*yamllint disable-file\s*$', first_line):
return
# If the document contains a syntax error, save it and yield it at the # If the document contains a syntax error, save it and yield it at the
# right line # right line
syntax_error = get_syntax_error(buffer) syntax_error = get_syntax_error(buffer)

View File

@@ -75,8 +75,8 @@ ID = 'empty-values'
TYPE = 'token' TYPE = 'token'
CONF = {'forbid-in-block-mappings': bool, CONF = {'forbid-in-block-mappings': bool,
'forbid-in-flow-mappings': bool} 'forbid-in-flow-mappings': bool}
DEFAULT = {'forbid-in-block-mappings': False, DEFAULT = {'forbid-in-block-mappings': True,
'forbid-in-flow-mappings': False} 'forbid-in-flow-mappings': True}
def check(conf, token, prev, next, nextnext, context): def check(conf, token, prev, next, nextnext, context):

View File

@@ -66,8 +66,8 @@ ID = 'octal-values'
TYPE = 'token' TYPE = 'token'
CONF = {'forbid-implicit-octal': bool, CONF = {'forbid-implicit-octal': bool,
'forbid-explicit-octal': bool} 'forbid-explicit-octal': bool}
DEFAULT = {'forbid-implicit-octal': False, DEFAULT = {'forbid-implicit-octal': True,
'forbid-explicit-octal': False} 'forbid-explicit-octal': True}
def check(conf, token, prev, next, nextnext, context): def check(conf, token, prev, next, nextnext, context):