From f4edb85a04beebcbdfd63bced0bc4918a514db10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Wed, 19 Jul 2017 09:48:00 +0200 Subject: [PATCH 01/11] fix(config): Be clearer about the `ignore` conf type --- yamllint/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yamllint/config.py b/yamllint/config.py index fb5a161..f9e4de8 100644 --- a/yamllint/config.py +++ b/yamllint/config.py @@ -87,7 +87,7 @@ class YamlLintConfig(object): if 'ignore' in conf: if type(conf['ignore']) != str: raise YamlLintConfigError( - 'invalid config: ignore should be a list of patterns') + 'invalid config: ignore should contain file patterns') self.ignore = pathspec.PathSpec.from_lines( 'gitwildmatch', conf['ignore'].splitlines()) @@ -112,7 +112,7 @@ def validate_rule_conf(rule, conf): type(conf['ignore']) != pathspec.pathspec.PathSpec): if type(conf['ignore']) != str: raise YamlLintConfigError( - 'invalid config: ignore should be a list of patterns') + 'invalid config: ignore should contain file patterns') conf['ignore'] = pathspec.PathSpec.from_lines( 'gitwildmatch', conf['ignore'].splitlines()) From 1c0dd48ccdac9d25e5ab6fd4e6ab14eea8fb3ce1 Mon Sep 17 00:00:00 2001 From: blackillzone Date: Wed, 19 Jul 2017 11:55:22 +0200 Subject: [PATCH 02/11] Update pre-commit hook file --- hooks.yaml => .pre-commit-hooks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename hooks.yaml => .pre-commit-hooks.yaml (89%) diff --git a/hooks.yaml b/.pre-commit-hooks.yaml similarity index 89% rename from hooks.yaml rename to .pre-commit-hooks.yaml index 482f3fb..8c67058 100644 --- a/hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -8,4 +8,4 @@ description: This hook runs yamllint. entry: yamllint language: python - files: \.(yaml|yml)$ + types: [file, yaml] From c8e516be2fc97b7380b9289d817a45148814bdc4 Mon Sep 17 00:00:00 2001 From: blackillzone Date: Wed, 19 Jul 2017 12:08:04 +0200 Subject: [PATCH 03/11] Add documentation for pre-commit --- docs/index.rst | 1 + docs/integration.rst | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 docs/integration.rst diff --git a/docs/index.rst b/docs/index.rst index 97e1fc7..958c951 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,3 +26,4 @@ Table of contents disable_with_comments development text_editors + integration diff --git a/docs/integration.rst b/docs/integration.rst new file mode 100644 index 0000000..131aa29 --- /dev/null +++ b/docs/integration.rst @@ -0,0 +1,16 @@ +Integration with other software +=============================== + +Integration with pre-commit +--------------------------- + +You can integrate yamllint in `pre-commit `_ tool. +Here is an example, to add in your .pre-commit-config.yaml + +.. code:: yaml + + # Update the sha variable with the release version that you want, from the yamllint repo + - repo: https://github.com/adrienverge/yamllint.git + sha: v1.8.1 + hooks: + - id: yamllint From db5712797140a63387f44319df376b825258b32c Mon Sep 17 00:00:00 2001 From: Sebastian Finke Date: Thu, 17 Aug 2017 11:57:40 +0200 Subject: [PATCH 04/11] docs(integration): Fix pre-commit config file --- docs/integration.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/integration.rst b/docs/integration.rst index 131aa29..da67d7f 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -9,6 +9,7 @@ Here is an example, to add in your .pre-commit-config.yaml .. code:: yaml + --- # Update the sha variable with the release version that you want, from the yamllint repo - repo: https://github.com/adrienverge/yamllint.git sha: v1.8.1 From c4a3e15ff0ad2fee8f650b7eb8f372f295f11784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Sun, 3 Sep 2017 15:55:57 +0200 Subject: [PATCH 05/11] docs(readthedocs): Fix builds on yamllint.readthedocs.io Documentation builds on readthedocs.io partly fail because some modules imported by yammlint cannot be imported in Sphinx automodule. This commit fixes that using the tip at [1]. Closes #66 [1]: http://docs.readthedocs.io/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules --- docs/conf.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 26668da..8225094 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,6 +4,7 @@ import sys import os +from unittest.mock import MagicMock sys.path.insert(0, os.path.abspath('..')) # noqa @@ -40,3 +41,15 @@ htmlhelp_basename = 'yamllintdoc' man_pages = [ ('index', 'yamllint', '', [u'Adrien Vergé'], 1) ] + +# -- Build with sphinx automodule without needing to install third-party libs + + +class Mock(MagicMock): + @classmethod + def __getattr__(cls, name): + return MagicMock() + + +MOCK_MODULES = ['pathspec', 'yaml'] +sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) From c8fc170ff0525e639940e4687a3c39cb65ca491d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Tue, 10 Oct 2017 12:30:00 +0200 Subject: [PATCH 06/11] yamllint version 1.8.2 --- CHANGELOG.rst | 7 +++++++ yamllint/__init__.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0b2f9ff..ae6c06e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ Changelog ========= +1.8.2 (2017-10-10) +------------------ + +- Be clearer about the `ignore` conf type +- Update pre-commit hook file +- Add documentation for pre-commit + 1.8.1 (2017-07-04) ------------------ diff --git a/yamllint/__init__.py b/yamllint/__init__.py index e53dce1..99fec21 100644 --- a/yamllint/__init__.py +++ b/yamllint/__init__.py @@ -22,7 +22,7 @@ indentation, etc.""" APP_NAME = 'yamllint' -APP_VERSION = '1.8.1' +APP_VERSION = '1.8.2' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Vergé' From ca540c113bfc4e49b550b6b980b278c9f8d9c85c Mon Sep 17 00:00:00 2001 From: Tim Wade Date: Mon, 16 Oct 2017 12:17:49 -0700 Subject: [PATCH 07/11] Fix indentation rule for key following empty list If a key-value pair follows an empty list, i.e.: ```yaml a: - b: c ``` yamllint will complain: ``` warning wrong indentation: expected 2 but found 0 (indentation) ``` This is because it is expecting the second key to be a continuation of the block entry above: ```yaml a: - b: c ``` However, both are perfectly valid, though structurally different. --- tests/rules/test_indentation.py | 3 +++ yamllint/rules/indentation.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/tests/rules/test_indentation.py b/tests/rules/test_indentation.py index 2733ea7..7d2f966 100644 --- a/tests/rules/test_indentation.py +++ b/tests/rules/test_indentation.py @@ -589,6 +589,9 @@ class IndentationTestCase(RuleTestCase): ' date: 1969\n' ' - name: Linux\n' ' date: 1991\n' + ' k4:\n' + ' -\n' + ' k5: v3\n' '...\n', conf) conf = 'indentation: {spaces: 2, indent-sequences: true}' self.check('---\n' diff --git a/yamllint/rules/indentation.py b/yamllint/rules/indentation.py index 432c23c..fb14faf 100644 --- a/yamllint/rules/indentation.py +++ b/yamllint/rules/indentation.py @@ -399,6 +399,10 @@ def _check(conf, token, prev, next, nextnext, context): # - item 1 # - item 2 indent = next.start_mark.column + elif next.start_mark.column == token.start_mark.column: + # - + # key: value + indent = next.start_mark.column else: # - # item 1 From f82346dac714434d2b6fb00a9b660f1ab7918cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Mon, 16 Oct 2017 22:13:12 +0200 Subject: [PATCH 08/11] indentation: Add more test cases for key following empty list --- tests/rules/test_indentation.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/rules/test_indentation.py b/tests/rules/test_indentation.py index 7d2f966..374f23c 100644 --- a/tests/rules/test_indentation.py +++ b/tests/rules/test_indentation.py @@ -1211,6 +1211,20 @@ class IndentationTestCase(RuleTestCase): ' - name: Linux\n' ' date: 1991\n' '...\n', conf, problem=(5, 10, 'syntax')) + conf = 'indentation: {spaces: 2, indent-sequences: true}' + self.check('---\n' + 'a:\n' + '-\n' # empty list + 'b: c\n' + '...\n', conf, problem=(3, 1)) + conf = 'indentation: {spaces: 2, indent-sequences: consistent}' + self.check('---\n' + 'a:\n' + ' -\n' # empty list + 'b:\n' + '-\n' + 'c: d\n' + '...\n', conf, problem=(5, 1)) def test_over_indented(self): conf = 'indentation: {spaces: 2, indent-sequences: consistent}' @@ -1267,6 +1281,20 @@ class IndentationTestCase(RuleTestCase): ' - subel\n' '...\n', conf, problem=(2, 3)) + conf = 'indentation: {spaces: 2, indent-sequences: false}' + self.check('---\n' + 'a:\n' + ' -\n' # empty list + 'b: c\n' + '...\n', conf, problem=(3, 3)) + conf = 'indentation: {spaces: 2, indent-sequences: consistent}' + self.check('---\n' + 'a:\n' + '-\n' # empty list + 'b:\n' + ' -\n' + 'c: d\n' + '...\n', conf, problem=(5, 3)) def test_multi_lines(self): conf = 'indentation: {spaces: consistent, indent-sequences: true}' From 1543d0e43556cd5165a7e785395964f9badfa404 Mon Sep 17 00:00:00 2001 From: "Johannes F. Knauf" Date: Tue, 19 Sep 2017 09:54:45 +0200 Subject: [PATCH 09/11] New rule key-ordering closes #67 --- docs/rules.rst | 5 ++ tests/rules/test_key_ordering.py | 67 +++++++++++++++++++++++++ yamllint/conf/default.yaml | 1 + yamllint/rules/__init__.py | 2 + yamllint/rules/key_ordering.py | 86 ++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+) create mode 100644 tests/rules/test_key_ordering.py create mode 100644 yamllint/rules/key_ordering.py diff --git a/docs/rules.rst b/docs/rules.rst index da744a0..dab310d 100644 --- a/docs/rules.rst +++ b/docs/rules.rst @@ -74,6 +74,11 @@ key-duplicates .. automodule:: yamllint.rules.key_duplicates +key-ordering +-------------- + +.. automodule:: yamllint.rules.key_ordering + line-length ----------- diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py new file mode 100644 index 0000000..bcd9eef --- /dev/null +++ b/tests/rules/test_key_ordering.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2017 Johannes F. Knauf +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from tests.common import RuleTestCase + + +class KeyOrderingTestCase(RuleTestCase): + rule_id = 'key-ordering' + + def test_disabled(self): + conf = 'key-ordering: disable' + self.check('---\n' + 'block mapping:\n' + ' secondkey: a\n' + ' firstkey: b\n', conf) + self.check('---\n' + 'flow mapping:\n' + ' {secondkey: a, firstkey: b}\n', conf) + self.check('---\n' + 'second: before_first\n' + 'at: root\n', conf) + self.check('---\n' + 'nested but OK:\n' + ' second: {first: 1}\n' + ' third:\n' + ' second: 2\n', conf) + + def test_enabled(self): + conf = 'key-ordering: enable' + self.check('---\n' + 'block mapping:\n' + ' secondkey: a\n' + ' firstkey: b\n', conf, + problem=(4, 3)) + self.check('---\n' + 'flow mapping:\n' + ' {secondkey: a, firstkey: b}\n', conf, + problem=(3, 18)) + self.check('---\n' + 'second: before_first\n' + 'at: root\n', conf, + problem=(3, 1)) + self.check('---\n' + 'nested but OK:\n' + ' second: {first: 1}\n' + ' third:\n' + ' second: 2\n', conf) + + def test_key_tokens_in_flow_sequences(self): + conf = 'key-ordering: enable' + self.check('---\n' + '[\n' + ' key: value, mappings, in, flow: sequence\n' + ']\n', conf) diff --git a/yamllint/conf/default.yaml b/yamllint/conf/default.yaml index c7c4da4..57cff64 100644 --- a/yamllint/conf/default.yaml +++ b/yamllint/conf/default.yaml @@ -39,6 +39,7 @@ rules: indent-sequences: true check-multi-line-strings: false key-duplicates: enable + key-ordering: disable line-length: max: 80 allow-non-breakable-words: true diff --git a/yamllint/rules/__init__.py b/yamllint/rules/__init__.py index 619e32d..83dca76 100644 --- a/yamllint/rules/__init__.py +++ b/yamllint/rules/__init__.py @@ -27,6 +27,7 @@ from yamllint.rules import ( hyphens, indentation, key_duplicates, + key_ordering, line_length, new_line_at_end_of_file, new_lines, @@ -47,6 +48,7 @@ _RULES = { hyphens.ID: hyphens, indentation.ID: indentation, key_duplicates.ID: key_duplicates, + key_ordering.ID: key_ordering, line_length.ID: line_length, new_line_at_end_of_file.ID: new_line_at_end_of_file, new_lines.ID: new_lines, diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py new file mode 100644 index 0000000..4a7e31f --- /dev/null +++ b/yamllint/rules/key_ordering.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2017 Johannes F. Knauf +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Use this rule to enforce alphabetical ordering of keys in mappings. + +.. rubric:: Examples + +#. With ``key-ordering: {}`` + + the following code snippet would **PASS**: + :: + + - key 1: v + key 2: val + key 3: value + - {a: 1, b: 2, c: 3} + + the following code snippet would **FAIL**: + :: + + - key 2: v + key 1: val + + the following code snippet would **FAIL**: + :: + + - {b: 1, a: 2} +""" + +import yaml + +from yamllint.linter import LintProblem + + +ID = 'key-ordering' +TYPE = 'token' +CONF = {} + +MAP, SEQ = range(2) + + +class Parent(object): + def __init__(self, type): + self.type = type + self.keys = [] + + +def check(conf, token, prev, next, nextnext, context): + if 'stack' not in context: + context['stack'] = [] + + if isinstance(token, (yaml.BlockMappingStartToken, + yaml.FlowMappingStartToken)): + context['stack'].append(Parent(MAP)) + elif isinstance(token, (yaml.BlockSequenceStartToken, + yaml.FlowSequenceStartToken)): + context['stack'].append(Parent(SEQ)) + elif isinstance(token, (yaml.BlockEndToken, + yaml.FlowMappingEndToken, + yaml.FlowSequenceEndToken)): + context['stack'].pop() + elif (isinstance(token, yaml.KeyToken) and + isinstance(next, yaml.ScalarToken)): + # This check is done because KeyTokens can be found inside flow + # sequences... strange, but allowed. + if len(context['stack']) > 0 and context['stack'][-1].type == MAP: + if any(next.value < key for key in context['stack'][-1].keys): + yield LintProblem( + next.start_mark.line + 1, next.start_mark.column + 1, + 'wrong ordering of key "%s" in mapping' % next.value) + else: + context['stack'][-1].keys.append(next.value) From 773bfc0f3c6ba3179ced739b9e840478acddb4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Mon, 16 Oct 2017 22:43:36 +0200 Subject: [PATCH 10/11] key-ordering: Add more test cases and documentation --- tests/rules/test_key_ordering.py | 49 ++++++++++++++++++++++++++++++++ yamllint/rules/key_ordering.py | 26 ++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index bcd9eef..dc486af 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -59,6 +59,55 @@ class KeyOrderingTestCase(RuleTestCase): ' third:\n' ' second: 2\n', conf) + def test_word_length(self): + conf = 'key-ordering: enable' + self.check('---\n' + 'a: 1\n' + 'ab: 1\n' + 'abc: 1\n', conf) + self.check('---\n' + 'a: 1\n' + 'abc: 1\n' + 'ab: 1\n', conf, + problem=(4, 1)) + + def test_key_duplicates(self): + conf = ('key-duplicates: disable\n' + 'key-ordering: enable') + self.check('---\n' + 'key: 1\n' + 'key: 2\n', conf) + + def test_case(self): + conf = 'key-ordering: enable' + self.check('---\n' + 'T-shirt: 1\n' + 'T-shirts: 2\n' + 't-shirt: 3\n' + 't-shirts: 4\n', conf) + self.check('---\n' + 'T-shirt: 1\n' + 't-shirt: 2\n' + 'T-shirts: 3\n' + 't-shirts: 4\n', conf, + problem=(4, 1)) + + def test_accents(self): + conf = 'key-ordering: enable' + self.check('---\n' + 'hair: true\n' + 'hais: true\n' + 'haïr: true\n' + 'haïssable: true\n', conf) + self.check('---\n' + 'haïr: true\n' + 'hais: true\n', conf, + problem=(3, 1)) + self.check('---\n' + 'haïr: true\n' + 'hais: true\n', conf, + problem=(3, 1)) + def test_key_tokens_in_flow_sequences(self): conf = 'key-ordering: enable' self.check('---\n' diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index 4a7e31f..3bd93c7 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -15,7 +15,9 @@ # along with this program. If not, see . """ -Use this rule to enforce alphabetical ordering of keys in mappings. +Use this rule to enforce alphabetical ordering of keys in mappings. The sorting +order uses the Unicode code point number. As a result, the ordering is +case-sensitive and not accent-friendly (see examples below). .. rubric:: Examples @@ -28,6 +30,14 @@ Use this rule to enforce alphabetical ordering of keys in mappings. key 2: val key 3: value - {a: 1, b: 2, c: 3} + - T-shirt: 1 + T-shirts: 2 + t-shirt: 3 + t-shirts: 4 + - hair: true + hais: true + haïr: true + haïssable: true the following code snippet would **FAIL**: :: @@ -39,6 +49,20 @@ Use this rule to enforce alphabetical ordering of keys in mappings. :: - {b: 1, a: 2} + + the following code snippet would **FAIL**: + :: + + - T-shirt: 1 + t-shirt: 2 + T-shirts: 3 + t-shirts: 4 + + the following code snippet would **FAIL**: + :: + + - haïr: true + hais: true """ import yaml From 2d931b5a817337fa88aef4325bf613e794e14d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Mon, 16 Oct 2017 22:52:00 +0200 Subject: [PATCH 11/11] yamllint version 1.9.0 --- CHANGELOG.rst | 6 ++++++ yamllint/__init__.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ae6c06e..73de95f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Changelog ========= +1.9.0 (2017-10-16) +------------------ + +- Add a new `key-ordering` rule +- Fix indentation rule for key following empty list + 1.8.2 (2017-10-10) ------------------ diff --git a/yamllint/__init__.py b/yamllint/__init__.py index 99fec21..831da23 100644 --- a/yamllint/__init__.py +++ b/yamllint/__init__.py @@ -22,7 +22,7 @@ indentation, etc.""" APP_NAME = 'yamllint' -APP_VERSION = '1.8.2' +APP_VERSION = '1.9.0' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Vergé'