Compare commits

...

4 Commits

Author SHA1 Message Date
Adrien Vergé
3f264806b9 yamllint version 0.7.1 2016-02-03 14:43:09 +01:00
Adrien Vergé
9a82b99d4b Rules: indentation: Fix multi-line flows
To detect this as correct indentations:

    top:
      rules: [
        {
          foo: 1
        },
        {
          foo: 2
          bar: [
            a, b, c
          ],
        },
      ]
2016-02-03 12:05:22 +01:00
Adrien Vergé
ba140ad42c Tests: Remove ghost character from YAML spec example 2016-02-01 23:27:49 +01:00
Adrien Vergé
0e04ee29e6 Doc: Update description 2016-02-01 23:03:25 +01:00
7 changed files with 195 additions and 53 deletions

View File

@@ -3,8 +3,9 @@ yamllint
A linter for YAML files. A linter for YAML files.
yamllint does not only check for syntax validity, but for common cosmetic yamllint does not only check for syntax validity, but for weirdnesses like key
conventions such as lines length, trailing spaces, indentation, etc. repetition and cosmetic problems such as lines length, trailing spaces,
indentation, etc.
.. image:: .. image::
https://travis-ci.org/adrienverge/yamllint.svg?branch=master https://travis-ci.org/adrienverge/yamllint.svg?branch=master

View File

@@ -1,10 +1,7 @@
yamllint documentation yamllint documentation
====================== ======================
A linter for YAML files. .. automodule:: yamllint
yamllint does not only check for syntax validity, but for common cosmetic
conventions such as lines length, trailing spaces, indentation, etc.
Screenshot Screenshot
---------- ----------

View File

@@ -169,7 +169,9 @@ class IndentationTestCase(RuleTestCase):
'- b\n' '- b\n'
'- c\n', conf, problem=(6, 1, 'syntax')) '- c\n', conf, problem=(6, 1, 'syntax'))
def test_flow_mappings(self): def test_direct_flows(self):
# flow: [ ...
# ]
conf = 'indentation: {spaces: 2}' conf = 'indentation: {spaces: 2}'
self.check('---\n' self.check('---\n'
'a: {x: 1,\n' 'a: {x: 1,\n'
@@ -183,10 +185,46 @@ class IndentationTestCase(RuleTestCase):
'a: {x: 1,\n' 'a: {x: 1,\n'
' y,\n' ' y,\n'
' z: 1}\n', conf, problem=(3, 6)) ' z: 1}\n', conf, problem=(3, 6))
self.check('---\n'
'a: {x: 1,\n'
' y, z: 1}\n', conf, problem=(3, 3))
self.check('---\n'
'a: {x: 1,\n'
' y, z: 1\n'
'}\n', conf)
self.check('---\n' self.check('---\n'
'a: {x: 1,\n' 'a: {x: 1,\n'
' y, z: 1\n' ' y, z: 1\n'
'}\n', conf, problem=(3, 3)) '}\n', conf, problem=(3, 3))
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf)
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf, problem=(3, 4))
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf, problem=(3, 6))
self.check('---\n'
'a: [x,\n'
' y, z]\n', conf, problem=(3, 3))
self.check('---\n'
'a: [x,\n'
' y, z\n'
']\n', conf)
self.check('---\n'
'a: [x,\n'
' y, z\n'
']\n', conf, problem=(3, 3))
def test_broken_flows(self):
# flow: [
# ...
# ]
conf = 'indentation: {spaces: 2}'
self.check('---\n' self.check('---\n'
'a: {\n' 'a: {\n'
' x: 1,\n' ' x: 1,\n'
@@ -206,25 +244,6 @@ class IndentationTestCase(RuleTestCase):
' x: 1,\n' ' x: 1,\n'
' y, z: 1\n' ' y, z: 1\n'
' }\n', conf, problem=(5, 3)) ' }\n', conf, problem=(5, 3))
def test_flow_sequences(self):
conf = 'indentation: {spaces: 2}'
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf)
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf, problem=(3, 4))
self.check('---\n'
'a: [x,\n'
' y,\n'
' z]\n', conf, problem=(3, 6))
self.check('---\n'
'a: [x,\n'
' y, z\n'
']\n', conf, problem=(3, 3))
self.check('---\n' self.check('---\n'
'a: [\n' 'a: [\n'
' x,\n' ' x,\n'
@@ -244,6 +263,138 @@ class IndentationTestCase(RuleTestCase):
' x,\n' ' x,\n'
' y, z\n' ' y, z\n'
' ]\n', conf, problem=(5, 3)) ' ]\n', conf, problem=(5, 3))
self.check('---\n'
'obj: {\n'
' a: 1,\n'
' b: 2,\n'
' c: 3\n'
'}\n', conf, problem1=(4, 4), problem2=(5, 2))
self.check('---\n'
'list: [\n'
' 1,\n'
' 2,\n'
' 3\n'
']\n', conf, problem1=(4, 4), problem2=(5, 2))
self.check('---\n'
'top:\n'
' rules: [\n'
' 1, 2,\n'
' ]\n', conf)
self.check('---\n'
'top:\n'
' rules: [\n'
' 1, 2,\n'
']\n'
' rulez: [\n'
' 1, 2,\n'
' ]\n', conf, problem1=(5, 1), problem2=(8, 5))
self.check('---\n'
'top:\n'
' rules:\n'
' here: {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf)
self.check('---\n'
'top:\n'
' rules:\n'
' here: {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n'
' there: {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf, problem1=(7, 7), problem2=(11, 3))
def test_cleared_flows(self):
# flow:
# [
# ...
# ]
conf = 'indentation: {spaces: 2}'
self.check('---\n'
'top:\n'
' rules:\n'
' {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf)
self.check('---\n'
'top:\n'
' rules:\n'
' {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf, problem=(5, 8))
self.check('---\n'
'top:\n'
' rules:\n'
' {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf, problem=(4, 4))
self.check('---\n'
'top:\n'
' rules:\n'
' {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf, problem=(7, 4))
self.check('---\n'
'top:\n'
' rules:\n'
' {\n'
' foo: 1,\n'
' bar: 2\n'
' }\n', conf, problem=(7, 6))
self.check('---\n'
'top:\n'
' [\n'
' a, b, c\n'
' ]\n', conf)
self.check('---\n'
'top:\n'
' [\n'
' a, b, c\n'
' ]\n', conf, problem=(4, 6))
self.check('---\n'
'top:\n'
' [\n'
' a, b, c\n'
' ]\n', conf, problem=(3, 4))
self.check('---\n'
'top:\n'
' [\n'
' a, b, c\n'
' ]\n', conf, problem=(5, 4))
self.check('---\n'
'top:\n'
' rules: [\n'
' {\n'
' foo: 1\n'
' },\n'
' {\n'
' foo: 2,\n'
' bar: [\n'
' a, b, c\n'
' ],\n'
' },\n'
' ]\n', conf)
self.check('---\n'
'top:\n'
' rules: [\n'
' {\n'
' foo: 1\n'
' },\n'
' {\n'
' foo: 2,\n'
' bar: [\n'
' a, b, c\n'
' ],\n'
' },\n'
']\n', conf, problem1=(5, 6), problem2=(6, 6),
problem3=(9, 9), problem4=(11, 7), problem5=(13, 1))
def test_under_indented(self): def test_under_indented(self):
conf = 'indentation: {spaces: 2, indent-sequences: yes}' conf = 'indentation: {spaces: 2, indent-sequences: yes}'
@@ -438,21 +589,6 @@ class IndentationTestCase(RuleTestCase):
'document-start: disable\n') 'document-start: disable\n')
self.check(' a: 1\n', conf, problem=(1, 3)) self.check(' a: 1\n', conf, problem=(1, 3))
def test_broken_inline_flows(self):
conf = 'indentation: {spaces: 2}'
self.check('---\n'
'obj: {\n'
' a: 1,\n'
' b: 2,\n'
' c: 3\n'
'}\n', conf, problem1=(4, 4), problem2=(5, 2))
self.check('---\n'
'list: [\n'
' 1,\n'
' 2,\n'
' 3\n'
']\n', conf, problem1=(4, 4), problem2=(5, 2))
def test_explicit_block_mappings(self): def test_explicit_block_mappings(self):
conf = 'indentation: {spaces: 4}' conf = 'indentation: {spaces: 4}'
self.check('---\n' self.check('---\n'

View File

@@ -35,6 +35,7 @@ from tests.common import RuleTestCase
# for br in span.find_all("br"): # for br in span.find_all("br"):
# br.replace_with("\n") # br.replace_with("\n")
# text = text.replace('\u2193', '') # downwards arrow # text = text.replace('\u2193', '') # downwards arrow
# text = text.replace('\u21d3', '') # double downwards arrow
# text = text.replace('\u00b7', ' ') # visible space # text = text.replace('\u00b7', ' ') # visible space
# text = text.replace('\u21d4', '') # byte order mark # text = text.replace('\u21d4', '') # byte order mark
# text = text.replace('\u2192', '\t') # right arrow # text = text.replace('\u2192', '\t') # right arrow

View File

@@ -2,7 +2,7 @@
# Comments: # Comments:
strip: |- strip: |-
# text # text
# Clip # Clip
# comments: # comments:

View File

@@ -14,12 +14,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
APP_NAME = 'yamllint' """A linter for YAML files.
APP_VERSION = '0.7.0'
APP_DESCRIPTION = """A linter for YAML files.
yamllint does not only check for syntax validity, but for common cosmetic yamllint does not only check for syntax validity, but for weirdnesses like key
conventions such as lines length, trailing spaces, indentation, etc.""" repetition and cosmetic problems such as lines length, trailing spaces,
indentation, etc."""
APP_NAME = 'yamllint'
APP_VERSION = '0.7.1'
APP_DESCRIPTION = __doc__
__author__ = u'Adrien Vergé' __author__ = u'Adrien Vergé'
__copyright__ = u'Copyright 2016, Adrien Vergé' __copyright__ = u'Copyright 2016, Adrien Vergé'

View File

@@ -158,9 +158,10 @@ ROOT, MAP, B_SEQ, F_SEQ, B_ENT, KEY, VAL = range(7)
class Parent(object): class Parent(object):
def __init__(self, type, indent): def __init__(self, type, indent, line_indent=None):
self.type = type self.type = type
self.indent = indent self.indent = indent
self.line_indent = line_indent
self.explicit_key = False self.explicit_key = False
@@ -250,7 +251,7 @@ def check(conf, token, prev, next, context):
if isinstance(token, (yaml.FlowMappingEndToken, if isinstance(token, (yaml.FlowMappingEndToken,
yaml.FlowSequenceEndToken)): yaml.FlowSequenceEndToken)):
expected = 0 expected = context['stack'][-1].line_indent
elif (context['stack'][-1].type == KEY and elif (context['stack'][-1].type == KEY and
context['stack'][-1].explicit_key and context['stack'][-1].explicit_key and
not isinstance(token, yaml.ValueToken)): not isinstance(token, yaml.ValueToken)):
@@ -301,11 +302,12 @@ def check(conf, token, prev, next, context):
indent = next.start_mark.column indent = next.start_mark.column
else: else:
# - { # - {
# a: 1, b: 2 # a: 1, b: 2
# } # }
indent = context['cur_line_indent'] + conf['spaces'] indent = context['cur_line_indent'] + conf['spaces']
context['stack'].append(Parent(MAP, indent)) context['stack'].append(Parent(MAP, indent,
line_indent=context['cur_line_indent']))
elif isinstance(token, yaml.BlockSequenceStartToken): elif isinstance(token, yaml.BlockSequenceStartToken):
# - - a # - - a
@@ -344,7 +346,8 @@ def check(conf, token, prev, next, context):
# ] # ]
indent = context['cur_line_indent'] + conf['spaces'] indent = context['cur_line_indent'] + conf['spaces']
context['stack'].append(Parent(F_SEQ, indent)) context['stack'].append(Parent(F_SEQ, indent,
line_indent=context['cur_line_indent']))
elif isinstance(token, (yaml.BlockEndToken, elif isinstance(token, (yaml.BlockEndToken,
yaml.FlowMappingEndToken, yaml.FlowMappingEndToken,