key-duplicates: Add forbid-duplicated-merge-keys option

This commit is contained in:
Travis Bale 2023-12-10 12:54:15 -05:00 committed by GitHub
parent 0dcf5f4175
commit e5fdfd2ae5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 1 deletions

View File

@ -179,3 +179,57 @@ class KeyDuplicatesTestCase(RuleTestCase):
'[\n'
' flow: sequence, with, key: value, mappings\n'
']\n', conf)
def test_forbid_duplicated_merge_keys(self):
conf = 'key-duplicates: {forbid-duplicated-merge-keys: true}'
self.check('---\n'
'Multiple Merge Keys are NOT OK:\n'
'anchor_one: &anchor_one\n'
' one: one\n'
'anchor_two: &anchor_two\n'
' two: two\n'
'anchor_reference:\n'
' <<: *anchor_one\n'
' <<: *anchor_two\n', conf, problem=(9, 3))
self.check('---\n'
'Multiple Merge Keys are NOT OK:\n'
'anchor_one: &anchor_one\n'
' one: one\n'
'anchor_two: &anchor_two\n'
' two: two\n'
'anchor_three: &anchor_three\n'
' two: three\n'
'anchor_reference:\n'
' <<: *anchor_one\n'
' <<: *anchor_two\n'
' <<: *anchor_three\n', conf,
problem1=(11, 3), problem2=(12, 3))
self.check('---\n'
'Multiple Merge Keys are NOT OK:\n'
'anchor_one: &anchor_one\n'
' one: one\n'
'anchor_two: &anchor_two\n'
' two: two\n'
'anchor_reference:\n'
' a: 1\n'
' <<: *anchor_one\n'
' b: 2\n'
' <<: *anchor_two\n', conf, problem=(11, 3))
self.check('---\n'
'Single Merge Key is OK:\n'
'anchor_one: &anchor_one\n'
' one: one\n'
'anchor_two: &anchor_two\n'
' two: two\n'
'anchor_reference:\n'
' <<: [*anchor_one, *anchor_two]\n', conf)
self.check('---\n'
'Duplicate keys without Merge Keys:\n'
' key: a\n'
' otherkey: b\n'
' key: c\n', conf,
problem=(5, 3))
self.check('---\n'
'No Merge Keys:\n'
' key: a\n'
' otherkey: b\n', conf)

View File

@ -16,6 +16,19 @@
"""
Use this rule to prevent multiple entries with the same key in mappings.
.. rubric:: Options
* Use ``forbid-duplicated-merge-keys`` to forbid the usage of
multiple merge keys ``<<``.
.. rubric:: Default values (when enabled)
.. code-block:: yaml
rules:
key-duplicates:
forbid-duplicated-merge-keys: false
.. rubric:: Examples
#. With ``key-duplicates: {}``
@ -51,6 +64,29 @@ Use this rule to prevent multiple entries with the same key in mappings.
other
duplication
: 2
#. With `key-duplicates`: {forbid-duplicated-merge-keys: true}``
the following code snippet would **PASS**:
::
anchor_one: &anchor_one
one: one
anchor_two: &anchor_two
two: two
anchor_reference:
<<: [*anchor_one, *anchor_two]
the following code snippet would **FAIL**:
::
anchor_one: &anchor_one
one: one
anchor_two: &anchor_two
two: two
anchor_reference:
<<: *anchor_one
<<: *anchor_two
"""
import yaml
@ -60,6 +96,8 @@ from yamllint.linter import LintProblem
ID = 'key-duplicates'
TYPE = 'token'
CONF = {'forbid-duplicated-merge-keys': bool}
DEFAULT = {'forbid-duplicated-merge-keys': False}
MAP, SEQ = range(2)
@ -92,7 +130,8 @@ def check(conf, token, prev, next, nextnext, context):
if len(context['stack']) > 0 and context['stack'][-1].type == MAP:
if (next.value in context['stack'][-1].keys and
# `<<` is "merge key", see http://yaml.org/type/merge.html
next.value != '<<'):
(next.value != '<<' or
conf['forbid-duplicated-merge-keys'])):
yield LintProblem(
next.start_mark.line + 1, next.start_mark.column + 1,
f'duplication of key "{next.value}" in mapping')