From d4f7174ddcf8fead8a9380872425f302ff749e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:18:32 +0200 Subject: [PATCH 1/9] feat: add the ability to ignored keys while sorting --- tests/rules/test_key_ordering.py | 25 +++++++++++++++++++++++++ yamllint/rules/key_ordering.py | 28 ++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index 7d17603e..1c059570 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -147,3 +147,28 @@ def test_locale_accents(self): 'hais: true\n' 'haïr: true\n', conf, problem=(3, 1)) + + def test_ignored_key(self): + conf = 'key-ordering:\n ignored: ["name"]' + self.check('---\n' + 'versions:\n' + ' - name: v1alpha1\n' + ' foo: bar\n' + ' - name: v2\n' + ' baz: qux\n', conf) + self.check('---\n' + 'versions:\n' + ' - name: v1alpha1\n' + ' foo: bar\n' + ' baz: qux\n' + ' - name: v2\n' + ' baz: qux\n' + ' - baz: qux\n' + ' name: v3\n' + ' value: whatever\n', conf, + problem=(5, 5)) + self.check('---\n' + 'age: 30\n' + 'name: John\n' + 'address: 123 Street\n', conf, + problem=(4, 1)) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index ec0716d9..23932510 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -19,6 +19,7 @@ ordering is case-sensitive and not accent-friendly (see examples below). This can be changed by setting the global ``locale`` option. This allows one to sort case and accents properly. +It also allows one to ignore certain keys by setting the ``ignored`` option. .. rubric:: Examples @@ -78,6 +79,15 @@ haïr: true hais: true haïssable: true + +#. With rule ``key-ordering: {ignored: ["name"]}`` + + the following code snippet would **PASS**: + :: + + - name: John + age: 30 + city: New York """ from locale import strcoll @@ -88,7 +98,8 @@ ID = 'key-ordering' TYPE = 'token' - +CONF = {'ignored': [str]} +DEFAULT = {'ignored': []} MAP, SEQ = range(2) @@ -117,10 +128,11 @@ def check(conf, token, prev, next, nextnext, context): # 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(strcoll(next.value, key) < 0 - for key in context['stack'][-1].keys): - yield LintProblem( - next.start_mark.line + 1, next.start_mark.column + 1, - f'wrong ordering of key "{next.value}" in mapping') - else: - context['stack'][-1].keys.append(next.value) + if next.value not in conf['ignored']: + if any(strcoll(next.value, key) < 0 + for key in context['stack'][-1].keys): + yield LintProblem( + next.start_mark.line + 1, next.start_mark.column + 1, + f'wrong ordering of key "{next.value}" in mapping') + else: + context['stack'][-1].keys.append(next.value) From 00330c08412bd3a5b2ba6bf026e8b331c7587a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:02:13 +0200 Subject: [PATCH 2/9] chore: refactor --- yamllint/rules/key_ordering.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index 23932510..7cfcf335 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -128,11 +128,11 @@ def check(conf, token, prev, next, nextnext, context): # 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 next.value not in conf['ignored']: - if any(strcoll(next.value, key) < 0 - for key in context['stack'][-1].keys): - yield LintProblem( - next.start_mark.line + 1, next.start_mark.column + 1, - f'wrong ordering of key "{next.value}" in mapping') - else: - context['stack'][-1].keys.append(next.value) + if any(strcoll(next.value, key) < 0 + for key in context['stack'][-1].keys + if key not in conf['ignored']): + yield LintProblem( + next.start_mark.line + 1, next.start_mark.column + 1, + f'wrong ordering of key "{next.value}" in mapping') + else: + context['stack'][-1].keys.append(next.value) From b2f15a2c0b0d788b5bd757ac1aafd356151e2aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:58:06 +0100 Subject: [PATCH 3/9] fix: PR review --- tests/rules/test_key_ordering.py | 8 ++++---- yamllint/rules/key_ordering.py | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index 1c059570..379677ad 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -149,7 +149,7 @@ def test_locale_accents(self): problem=(3, 1)) def test_ignored_key(self): - conf = 'key-ordering:\n ignored: ["name"]' + conf = 'key-ordering:\n ignored-keys: ["n(am|omm)e"]' self.check('---\n' 'versions:\n' ' - name: v1alpha1\n' @@ -158,13 +158,13 @@ def test_ignored_key(self): ' baz: qux\n', conf) self.check('---\n' 'versions:\n' - ' - name: v1alpha1\n' + ' - nomme: v1alpha1\n' ' foo: bar\n' ' baz: qux\n' - ' - name: v2\n' + ' - nomme: v2\n' ' baz: qux\n' ' - baz: qux\n' - ' name: v3\n' + ' nomme: v3\n' ' value: whatever\n', conf, problem=(5, 5)) self.check('---\n' diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index 7cfcf335..3998253d 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -19,7 +19,8 @@ ordering is case-sensitive and not accent-friendly (see examples below). This can be changed by setting the global ``locale`` option. This allows one to sort case and accents properly. -It also allows one to ignore certain keys by setting the ``ignored`` option. +It also allows one to ignore certain keys by setting the ``ignored-keys`` +(PCRE regexes list) option. .. rubric:: Examples @@ -80,7 +81,7 @@ hais: true haïssable: true -#. With rule ``key-ordering: {ignored: ["name"]}`` +#. With rule ``key-ordering: {ignored-keys: ["name"]}`` the following code snippet would **PASS**: :: @@ -89,7 +90,7 @@ age: 30 city: New York """ - +import re from locale import strcoll import yaml @@ -98,8 +99,9 @@ ID = 'key-ordering' TYPE = 'token' -CONF = {'ignored': [str]} -DEFAULT = {'ignored': []} + +CONF = {'ignored-keys': [str]} +DEFAULT = {'ignored-keys': []} MAP, SEQ = range(2) @@ -128,9 +130,11 @@ def check(conf, token, prev, next, nextnext, context): # 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(strcoll(next.value, key) < 0 - for key in context['stack'][-1].keys - if key not in conf['ignored']): + if any( + strcoll(next.value, key) < 0 + for key in context['stack'][-1].keys + if not any(re.search(r, key) for r in conf['ignored-keys']) + ): yield LintProblem( next.start_mark.line + 1, next.start_mark.column + 1, f'wrong ordering of key "{next.value}" in mapping') From b9aaf4f0d57e6b6526d8c6ef99fe403a5056cff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:20:11 +0100 Subject: [PATCH 4/9] chore: add another test --- tests/rules/test_key_ordering.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index 379677ad..9cc1d5f8 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -148,8 +148,8 @@ def test_locale_accents(self): 'haïr: true\n', conf, problem=(3, 1)) - def test_ignored_key(self): - conf = 'key-ordering:\n ignored-keys: ["n(am|omm)e"]' + def test_ignored_keys(self): + conf = 'key-ordering:\n ignored-keys: ["n(am|omm)e", "^b.*$"]' self.check('---\n' 'versions:\n' ' - name: v1alpha1\n' @@ -167,6 +167,18 @@ def test_ignored_key(self): ' nomme: v3\n' ' value: whatever\n', conf, problem=(5, 5)) + self.check('---\n' + 'versions:\n' + ' - name: v1alpha1\n' + ' baz: qux\n' + ' zzz: bad\n' + ' foo: bar\n' + ' - name: v2\n' + ' bar: baz\n' + ' - baz: qux\n' + ' name: v3\n' + ' value: whatever\n', conf, + problem=(6, 5)) self.check('---\n' 'age: 30\n' 'name: John\n' From 186dcd99082ed44cbba354f5c8ce6f36efa41363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:08:05 +0100 Subject: [PATCH 5/9] chore: missing rubricoptions --- yamllint/rules/key_ordering.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index 3998253d..b096cf47 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -22,6 +22,19 @@ It also allows one to ignore certain keys by setting the ``ignored-keys`` (PCRE regexes list) option. +.. rubric:: Options + +* ``ignored-keys`` is a list of PCRE regexes defining a set of keys to be ignored while ordering, if + they match any regex. Default is an empty list. + +.. rubric:: Default values (when enabled) + +.. code-block:: yaml + + rules: + key-ordering: + ignored-keys: [] + .. rubric:: Examples #. With ``key-ordering: {}`` From ffafaedcb77e8632ba256ee3de60f21ec064ea45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:21:44 +0100 Subject: [PATCH 6/9] fix: lint --- yamllint/rules/key_ordering.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index b096cf47..262d58b0 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -24,8 +24,8 @@ .. rubric:: Options -* ``ignored-keys`` is a list of PCRE regexes defining a set of keys to be ignored while ordering, if - they match any regex. Default is an empty list. +* ``ignored-keys`` is a list of PCRE regexes defining a set of keys to be + ignored while ordering, if they match any regex. Default is an empty list. .. rubric:: Default values (when enabled) From 13ca6dfa09f9acdc77c92e958b2a9ed751c436d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Wed, 11 Dec 2024 23:49:50 +0100 Subject: [PATCH 7/9] fix: PR review --- tests/rules/test_key_ordering.py | 59 +++++++++++++------------------- yamllint/rules/key_ordering.py | 8 +++-- 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index 9cc1d5f8..03fe5bf2 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -149,38 +149,27 @@ def test_locale_accents(self): problem=(3, 1)) def test_ignored_keys(self): - conf = 'key-ordering:\n ignored-keys: ["n(am|omm)e", "^b.*$"]' - self.check('---\n' - 'versions:\n' - ' - name: v1alpha1\n' - ' foo: bar\n' - ' - name: v2\n' - ' baz: qux\n', conf) - self.check('---\n' - 'versions:\n' - ' - nomme: v1alpha1\n' - ' foo: bar\n' - ' baz: qux\n' - ' - nomme: v2\n' - ' baz: qux\n' - ' - baz: qux\n' - ' nomme: v3\n' - ' value: whatever\n', conf, - problem=(5, 5)) - self.check('---\n' - 'versions:\n' - ' - name: v1alpha1\n' - ' baz: qux\n' - ' zzz: bad\n' - ' foo: bar\n' - ' - name: v2\n' - ' bar: baz\n' - ' - baz: qux\n' - ' name: v3\n' - ' value: whatever\n', conf, - problem=(6, 5)) - self.check('---\n' - 'age: 30\n' - 'name: John\n' - 'address: 123 Street\n', conf, - problem=(4, 1)) + conf = ( + 'key-ordering:\n' + ' ignored-keys: ["n(a|o)me", "^b"]\n' + ) + self.check( + '---\n' + 'a:\n' + 'b:\n' + 'c:\n' + 'name: ignored\n' + 'first-name: ignored\n' + 'nome: ignored\n' + 'gnomes: ignored\n' + 'd:\n' + 'e:\n' + 'boat: ignored\n' + '.boat: ERROR\n' + 'call: ERROR\n' + 'f:\n' + 'g:\n', + conf, + problem1=(12, 1), + problem2=(13, 1), + ) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index 262d58b0..bc946bff 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -103,6 +103,7 @@ age: 30 city: New York """ + import re from locale import strcoll @@ -142,11 +143,14 @@ def check(conf, token, prev, next, nextnext, context): 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 ( + len(context['stack']) > 0 + and context['stack'][-1].type == MAP + and not any(re.search(r, next.value) for r in conf['ignored-keys']) + ): if any( strcoll(next.value, key) < 0 for key in context['stack'][-1].keys - if not any(re.search(r, key) for r in conf['ignored-keys']) ): yield LintProblem( next.start_mark.line + 1, next.start_mark.column + 1, From 2200174fd4848250c75bcc7ded914d748d704885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:18:17 +0100 Subject: [PATCH 8/9] fix: leftovers from PR review --- yamllint/rules/key_ordering.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index bc946bff..ee1408e6 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -99,9 +99,12 @@ the following code snippet would **PASS**: :: - - name: John - age: 30 - city: New York + - a: + b: + name: ignored + first-name: ignored + c: + d: """ import re @@ -143,15 +146,11 @@ def check(conf, token, prev, next, nextnext, context): 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 - and not any(re.search(r, next.value) for r in conf['ignored-keys']) - ): - if any( - strcoll(next.value, key) < 0 - for key in context['stack'][-1].keys - ): + if (len(context['stack']) > 0 and context['stack'][-1].type == MAP and + not any(re.search(r, next.value) + for r in conf['ignored-keys'])): + if any(strcoll(next.value, key) < 0 + for key in context['stack'][-1].keys): yield LintProblem( next.start_mark.line + 1, next.start_mark.column + 1, f'wrong ordering of key "{next.value}" in mapping') From 1efd875f7d52016a6a28a71b9ce240ab0dde998f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Fern=C3=A1ndez?= <7312236+fernandezcuesta@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:25:25 +0100 Subject: [PATCH 9/9] fix: test style --- tests/rules/test_key_ordering.py | 44 +++++++++++++++----------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/tests/rules/test_key_ordering.py b/tests/rules/test_key_ordering.py index 03fe5bf2..ddedcf8a 100644 --- a/tests/rules/test_key_ordering.py +++ b/tests/rules/test_key_ordering.py @@ -149,27 +149,23 @@ def test_locale_accents(self): problem=(3, 1)) def test_ignored_keys(self): - conf = ( - 'key-ordering:\n' - ' ignored-keys: ["n(a|o)me", "^b"]\n' - ) - self.check( - '---\n' - 'a:\n' - 'b:\n' - 'c:\n' - 'name: ignored\n' - 'first-name: ignored\n' - 'nome: ignored\n' - 'gnomes: ignored\n' - 'd:\n' - 'e:\n' - 'boat: ignored\n' - '.boat: ERROR\n' - 'call: ERROR\n' - 'f:\n' - 'g:\n', - conf, - problem1=(12, 1), - problem2=(13, 1), - ) + conf = ('key-ordering:\n' + ' ignored-keys: ["n(a|o)me", "^b"]\n') + self.check('---\n' + 'a:\n' + 'b:\n' + 'c:\n' + 'name: ignored\n' + 'first-name: ignored\n' + 'nome: ignored\n' + 'gnomes: ignored\n' + 'd:\n' + 'e:\n' + 'boat: ignored\n' + '.boat: ERROR\n' + 'call: ERROR\n' + 'f:\n' + 'g:\n', + conf, + problem1=(12, 1), + problem2=(13, 1))