From 46e9108419c40d2a048dc79aec5c71cb6ef7ba77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Sun, 6 Mar 2016 15:42:16 +0100 Subject: [PATCH] Rules: indentation: Add 'consistent' option for 'indent-sequences' Using `indent-sequences: consistent` allows block sequences to be indented or not to be, as long as it remains the same within the file. --- tests/rules/test_indentation.py | 58 ++++++++++++++++++++++++++++++--- yamllint/rules/indentation.py | 40 +++++++++++++++++++---- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/tests/rules/test_indentation.py b/tests/rules/test_indentation.py index c2934f0..0dde86e 100644 --- a/tests/rules/test_indentation.py +++ b/tests/rules/test_indentation.py @@ -615,6 +615,56 @@ class IndentationTestCase(RuleTestCase): '- b\n' '- c\n', conf, problem=(6, 1, 'syntax')) + def test_indent_sequences_consistent(self): + conf = 'indentation: {spaces: 4, indent-sequences: consistent}' + self.check('---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list:\n' + ' two:\n' + ' - a\n' + ' - b\n' + ' - c\n', conf) + self.check('---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list:\n' + ' two:\n' + ' - a\n' + ' - b\n' + ' - c\n', conf) + self.check('---\n' + 'list one:\n' + '- 1\n' + '- 2\n' + '- 3\n' + 'list two:\n' + ' - a\n' + ' - b\n' + ' - c\n', conf, problem=(7, 5)) + self.check('---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', conf, problem=(7, 1)) + self.check('---\n' + 'list one:\n' + ' - 1\n' + ' - 2\n' + ' - 3\n' + 'list two:\n' + '- a\n' + '- b\n' + '- c\n', conf, problem1=(3, 2), problem2=(7, 1)) + def test_direct_flows(self): # flow: [ ... # ] @@ -854,7 +904,7 @@ class IndentationTestCase(RuleTestCase): problem3=(9, 9), problem4=(11, 7), problem5=(13, 1)) def test_under_indented(self): - conf = 'indentation: {spaces: 2, indent-sequences: yes}' + conf = 'indentation: {spaces: 2, indent-sequences: consistent}' self.check('---\n' 'object:\n' ' val: 1\n' @@ -870,7 +920,7 @@ class IndentationTestCase(RuleTestCase): ' - name: Unix\n' ' date: 1969\n' '...\n', conf, problem=(5, 6, 'syntax')) - conf = 'indentation: {spaces: 4, indent-sequences: yes}' + conf = 'indentation: {spaces: 4, indent-sequences: consistent}' self.check('---\n' 'object:\n' ' val: 1\n' @@ -888,7 +938,7 @@ class IndentationTestCase(RuleTestCase): '...\n', conf, problem=(5, 10, 'syntax')) def test_over_indented(self): - conf = 'indentation: {spaces: 2, indent-sequences: yes}' + conf = 'indentation: {spaces: 2, indent-sequences: consistent}' self.check('---\n' 'object:\n' ' val: 1\n' @@ -904,7 +954,7 @@ class IndentationTestCase(RuleTestCase): ' - name: Unix\n' ' date: 1969\n' '...\n', conf, problem=(5, 12, 'syntax')) - conf = 'indentation: {spaces: 4, indent-sequences: yes}' + conf = 'indentation: {spaces: 4, indent-sequences: consistent}' self.check('---\n' 'object:\n' ' val: 1\n' diff --git a/yamllint/rules/indentation.py b/yamllint/rules/indentation.py index 33883ba..15f57d2 100644 --- a/yamllint/rules/indentation.py +++ b/yamllint/rules/indentation.py @@ -26,8 +26,9 @@ Use this rule to control the indentation. * ``indent-sequences`` defines whether block sequences should be indented or not (when in a mapping, this indentation is not mandatory -- some people perceive the ``-`` as part of the indentation). Possible values: ``yes``, - ``no`` and ``whatever`` (the latter means either indenting or not indenting - block sequences is OK. + ``no``, ``whatever`` and ``consistent``. ``consistent`` requires either all + block sequences to be indented, or none to be. ``whatever`` means either + indenting or not indenting individual block sequences is OK. * ``check-multi-line-strings`` defines whether to lint indentation in multi-line strings. Set to ``yes`` to enable, ``no`` to disable. @@ -129,6 +130,28 @@ Use this rule to control the indentation. - spaghetti - sauce +#. With ``indentation: {spaces: 2, indent-sequences: consistent}`` + + the following code snippet would **PASS**: + :: + + - flying: + - spaghetti + - monster + - not flying: + - spaghetti + - sauce + + the following code snippet would **FAIL**: + :: + + - flying: + - spaghetti + - monster + - not flying: + - spaghetti + - sauce + #. With ``indentation: {spaces: 4, check-multi-line-strings: yes}`` the following code snippet would **PASS**: @@ -176,7 +199,7 @@ from yamllint.rules.common import is_explicit_key, get_real_end_line ID = 'indentation' TYPE = 'token' CONF = {'spaces': (int, 'consistent'), - 'indent-sequences': (True, False, 'whatever'), + 'indent-sequences': (bool, 'whatever', 'consistent'), 'check-multi-line-strings': bool} ROOT, B_MAP, F_MAP, B_SEQ, F_SEQ, B_ENT, KEY, VAL = range(8) @@ -277,6 +300,7 @@ def check(conf, token, prev, next, nextnext, context): context['stack'] = [Parent(ROOT, 0)] context['cur_line'] = -1 context['spaces'] = conf['spaces'] + context['indent-sequences'] = conf['indent-sequences'] # Step 1: Lint @@ -443,17 +467,21 @@ def check(conf, token, prev, next, nextnext, context): # yaml.scan()ning this: # '- lib:\n' # ' - var\n' - if conf['indent-sequences'] is False: + if context['indent-sequences'] is False: indent = context['stack'][-1].indent - elif conf['indent-sequences'] is True: + elif context['indent-sequences'] is True: indent = detect_indent(context['stack'][-1].indent, next) - else: # 'whatever' + else: # 'whatever' or 'consistent' if next.start_mark.column == context['stack'][-1].indent: # key: # - e1 # - e2 + if context['indent-sequences'] == 'consistent': + context['indent-sequences'] = False indent = context['stack'][-1].indent else: + if context['indent-sequences'] == 'consistent': + context['indent-sequences'] = True # key: # - e1 # - e2