1# -*- coding: utf-8 -*- 2# Copyright (C) 2016 Adrien Vergé 3# 4# This program is free software: you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation, either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17""" 18Use this rule to control the use of flow mappings or number of spaces inside 19braces (``{`` and ``}``). 20 21.. rubric:: Options 22 23* ``forbid`` is used to forbid the use of flow mappings which are denoted by 24 surrounding braces (``{`` and ``}``). Use ``true`` to forbid the use of flow 25 mappings completely. Use ``non-empty`` to forbid the use of all flow 26 mappings except for empty ones. 27* ``min-spaces-inside`` defines the minimal number of spaces required inside 28 braces. 29* ``max-spaces-inside`` defines the maximal number of spaces allowed inside 30 braces. 31* ``min-spaces-inside-empty`` defines the minimal number of spaces required 32 inside empty braces. 33* ``max-spaces-inside-empty`` defines the maximal number of spaces allowed 34 inside empty braces. 35 36.. rubric:: Default values (when enabled) 37 38.. code-block:: yaml 39 40 rules: 41 braces: 42 forbid: false 43 min-spaces-inside: 0 44 max-spaces-inside: 0 45 min-spaces-inside-empty: -1 46 max-spaces-inside-empty: -1 47 48.. rubric:: Examples 49 50#. With ``braces: {forbid: true}`` 51 52 the following code snippet would **PASS**: 53 :: 54 55 object: 56 key1: 4 57 key2: 8 58 59 the following code snippet would **FAIL**: 60 :: 61 62 object: { key1: 4, key2: 8 } 63 64#. With ``braces: {forbid: non-empty}`` 65 66 the following code snippet would **PASS**: 67 :: 68 69 object: {} 70 71 the following code snippet would **FAIL**: 72 :: 73 74 object: { key1: 4, key2: 8 } 75 76#. With ``braces: {min-spaces-inside: 0, max-spaces-inside: 0}`` 77 78 the following code snippet would **PASS**: 79 :: 80 81 object: {key1: 4, key2: 8} 82 83 the following code snippet would **FAIL**: 84 :: 85 86 object: { key1: 4, key2: 8 } 87 88#. With ``braces: {min-spaces-inside: 1, max-spaces-inside: 3}`` 89 90 the following code snippet would **PASS**: 91 :: 92 93 object: { key1: 4, key2: 8 } 94 95 the following code snippet would **PASS**: 96 :: 97 98 object: { key1: 4, key2: 8 } 99 100 the following code snippet would **FAIL**: 101 :: 102 103 object: { key1: 4, key2: 8 } 104 105 the following code snippet would **FAIL**: 106 :: 107 108 object: {key1: 4, key2: 8 } 109 110#. With ``braces: {min-spaces-inside-empty: 0, max-spaces-inside-empty: 0}`` 111 112 the following code snippet would **PASS**: 113 :: 114 115 object: {} 116 117 the following code snippet would **FAIL**: 118 :: 119 120 object: { } 121 122#. With ``braces: {min-spaces-inside-empty: 1, max-spaces-inside-empty: -1}`` 123 124 the following code snippet would **PASS**: 125 :: 126 127 object: { } 128 129 the following code snippet would **FAIL**: 130 :: 131 132 object: {} 133""" 134 135 136import yaml 137 138from yamllint.linter import LintProblem 139from yamllint.rules.common import spaces_after, spaces_before 140 141 142ID = 'braces' 143TYPE = 'token' 144CONF = {'forbid': (bool, 'non-empty'), 145 'min-spaces-inside': int, 146 'max-spaces-inside': int, 147 'min-spaces-inside-empty': int, 148 'max-spaces-inside-empty': int} 149DEFAULT = {'forbid': False, 150 'min-spaces-inside': 0, 151 'max-spaces-inside': 0, 152 'min-spaces-inside-empty': -1, 153 'max-spaces-inside-empty': -1} 154 155 156def check(conf, token, prev, next, nextnext, context): 157 if (conf['forbid'] is True and 158 isinstance(token, yaml.FlowMappingStartToken)): 159 yield LintProblem(token.start_mark.line + 1, 160 token.end_mark.column + 1, 161 'forbidden flow mapping') 162 163 elif (conf['forbid'] == 'non-empty' and 164 isinstance(token, yaml.FlowMappingStartToken) and 165 not isinstance(next, yaml.FlowMappingEndToken)): 166 yield LintProblem(token.start_mark.line + 1, 167 token.end_mark.column + 1, 168 'forbidden flow mapping') 169 170 elif (isinstance(token, yaml.FlowMappingStartToken) and 171 isinstance(next, yaml.FlowMappingEndToken)): 172 problem = spaces_after(token, prev, next, 173 min=(conf['min-spaces-inside-empty'] 174 if conf['min-spaces-inside-empty'] != -1 175 else conf['min-spaces-inside']), 176 max=(conf['max-spaces-inside-empty'] 177 if conf['max-spaces-inside-empty'] != -1 178 else conf['max-spaces-inside']), 179 min_desc='too few spaces inside empty braces', 180 max_desc='too many spaces inside empty braces') 181 if problem is not None: 182 yield problem 183 184 elif isinstance(token, yaml.FlowMappingStartToken): 185 problem = spaces_after(token, prev, next, 186 min=conf['min-spaces-inside'], 187 max=conf['max-spaces-inside'], 188 min_desc='too few spaces inside braces', 189 max_desc='too many spaces inside braces') 190 if problem is not None: 191 yield problem 192 193 elif (isinstance(token, yaml.FlowMappingEndToken) and 194 (prev is None or 195 not isinstance(prev, yaml.FlowMappingStartToken))): 196 problem = spaces_before(token, prev, next, 197 min=conf['min-spaces-inside'], 198 max=conf['max-spaces-inside'], 199 min_desc='too few spaces inside braces', 200 max_desc='too many spaces inside braces') 201 if problem is not None: 202 yield problem 203