Rules: comments-indentation: Allow two levels

Previously only comments that were indented like the following content
line were allowed, e.g.:

    prev: line:
      # commented line
      current: line

With this change, such new cases are also allowed:

      prev: line
      # commented line 1
    # commented line 2
    current: line
pull/4/head
Adrien Vergé 9 years ago
parent 01c12f2462
commit f09aef4f89

@ -88,15 +88,39 @@ class CommentsIndentationTestCase(RuleTestCase):
self.check('---\n' self.check('---\n'
'obj1:\n' 'obj1:\n'
' a: 1\n' ' a: 1\n'
' # comments\n' ' # the following line is disabled\n'
' # b: 2\n', conf)
self.check('---\n'
'obj1:\n'
' a: 1\n'
' # b: 2\n'
'\n' '\n'
'obj2:\n' 'obj2:\n'
' b: 2\n', conf, problem=(4, 3)) ' b: 2\n', conf)
self.check('---\n'
'obj1:\n'
' a: 1\n'
' # b: 2\n'
'# this object is useless\n'
'obj2: no\n', conf)
self.check('---\n'
'obj1:\n'
' a: 1\n'
'# this object is useless\n'
' # b: 2\n'
'obj2: no\n', conf, problem=(5, 3))
self.check('---\n' self.check('---\n'
'obj1:\n' 'obj1:\n'
' a: 1\n' ' a: 1\n'
' # comments\n' ' # comments\n'
' b: 2\n', conf) ' b: 2\n', conf)
self.check('---\n'
'mylist:\n'
' - todo 1\n'
' - todo 2\n'
' # commented for now\n'
' # - todo 3\n'
'...\n', conf)
def test_first_line(self): def test_first_line(self):
conf = 'comments-indentation: {}' conf = 'comments-indentation: {}'

@ -18,10 +18,32 @@ import unittest
import yaml import yaml
from yamllint.rules.common import Comment, get_comments_between_tokens from yamllint.rules.common import (Comment, get_line_indent,
get_comments_between_tokens)
class CommonTestCase(unittest.TestCase): class CommonTestCase(unittest.TestCase):
def test_get_line_indent(self):
tokens = list(yaml.scan('a: 1\n'
'b:\n'
' - c: [2, 3, {d: 4}]\n'))
self.assertEqual(tokens[3].value, 'a')
self.assertEqual(tokens[5].value, '1')
self.assertEqual(tokens[7].value, 'b')
self.assertEqual(tokens[13].value, 'c')
self.assertEqual(tokens[16].value, '2')
self.assertEqual(tokens[18].value, '3')
self.assertEqual(tokens[22].value, 'd')
self.assertEqual(tokens[24].value, '4')
for i in (3, 5):
self.assertEqual(get_line_indent(tokens[i]), 0)
for i in (7,):
self.assertEqual(get_line_indent(tokens[i]), 0)
for i in (13, 16, 18, 22, 24):
self.assertEqual(get_line_indent(tokens[i]), 2)
def check_comments(self, buffer, *expected): def check_comments(self, buffer, *expected):
yaml_loader = yaml.BaseLoader(buffer) yaml_loader = yaml.BaseLoader(buffer)

@ -17,27 +17,48 @@
import yaml import yaml
from yamllint.errors import LintProblem from yamllint.errors import LintProblem
from yamllint.rules.common import get_comments_between_tokens from yamllint.rules.common import get_line_indent, get_comments_between_tokens
ID = 'comments-indentation' ID = 'comments-indentation'
TYPE = 'token' TYPE = 'token'
# Case A:
#
# prev: line:
# # commented line
# current: line
#
# Case B:
#
# prev: line
# # commented line 1
# # commented line 2
# current: line
def check(conf, token, prev, next): def check(conf, token, prev, next):
if prev is None: if prev is None:
return return
token_indent = token.start_mark.column curr_line_indent = token.start_mark.column
if isinstance(token, yaml.StreamEndToken): if isinstance(token, yaml.StreamEndToken):
token_indent = 0 curr_line_indent = 0
skip_first = True skip_first_line = True
if isinstance(prev, yaml.StreamStartToken): if isinstance(prev, yaml.StreamStartToken):
skip_first = False skip_first_line = False
prev_line_indent = 0
else:
prev_line_indent = get_line_indent(prev)
if prev_line_indent <= curr_line_indent:
prev_line_indent = -1 # disable it
for comment in get_comments_between_tokens(prev, token, for comment in get_comments_between_tokens(
skip_first_line=skip_first): prev, token, skip_first_line=skip_first_line):
if comment.column != token_indent + 1: if comment.column - 1 == curr_line_indent:
prev_line_indent = -1 # disable it
elif comment.column - 1 != prev_line_indent:
yield LintProblem(comment.line, comment.column, yield LintProblem(comment.line, comment.column,
'comment not indented like content') 'comment not indented like content')

@ -64,6 +64,16 @@ class Comment(object):
str(self) == str(other)) str(self) == str(other))
def get_line_indent(token):
"""Finds the indent of the line the token starts in."""
start = token.start_mark.buffer.rfind('\n', 0,
token.start_mark.pointer) + 1
content = start
while token.start_mark.buffer[content] == ' ':
content += 1
return content - start
def get_comments_between_tokens(token1, token2, skip_first_line=False): def get_comments_between_tokens(token1, token2, skip_first_line=False):
if token2 is None: if token2 is None:
buf = token1.end_mark.buffer[token1.end_mark.pointer:] buf = token1.end_mark.buffer[token1.end_mark.pointer:]

Loading…
Cancel
Save