Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
483a8d89a5 | ||
|
|
fa87913566 |
@@ -1,6 +1,11 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
1.22.1 (2020-04-15)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Fix ``quoted-strings`` rule with ``only-when-needed`` on corner cases
|
||||||
|
|
||||||
1.22.0 (2020-04-13)
|
1.22.0 (2020-04-13)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|||||||
@@ -316,3 +316,44 @@ class QuotedTestCase(RuleTestCase):
|
|||||||
' "word 1\\\n' # fails
|
' "word 1\\\n' # fails
|
||||||
' word 2"\n',
|
' word 2"\n',
|
||||||
conf, problem1=(12, 3))
|
conf, problem1=(12, 3))
|
||||||
|
|
||||||
|
def test_only_when_needed_corner_cases(self):
|
||||||
|
conf = 'quoted-strings: {required: only-when-needed}\n'
|
||||||
|
|
||||||
|
self.check('---\n'
|
||||||
|
'- ""\n'
|
||||||
|
'- "- item"\n'
|
||||||
|
'- "key: value"\n'
|
||||||
|
'- "%H:%M:%S"\n'
|
||||||
|
'- "%wheel ALL=(ALL) NOPASSWD: ALL"\n'
|
||||||
|
'- \'"quoted"\'\n'
|
||||||
|
'- "\'foo\' == \'bar\'"\n'
|
||||||
|
'- "\'Mac\' in ansible_facts.product_name"\n',
|
||||||
|
conf)
|
||||||
|
self.check('---\n'
|
||||||
|
'k1: ""\n'
|
||||||
|
'k2: "- item"\n'
|
||||||
|
'k3: "key: value"\n'
|
||||||
|
'k4: "%H:%M:%S"\n'
|
||||||
|
'k5: "%wheel ALL=(ALL) NOPASSWD: ALL"\n'
|
||||||
|
'k6: \'"quoted"\'\n'
|
||||||
|
'k7: "\'foo\' == \'bar\'"\n'
|
||||||
|
'k8: "\'Mac\' in ansible_facts.product_name"\n',
|
||||||
|
conf)
|
||||||
|
|
||||||
|
self.check('---\n'
|
||||||
|
'- ---\n'
|
||||||
|
'- "---"\n' # fails
|
||||||
|
'- ----------\n'
|
||||||
|
'- "----------"\n' # fails
|
||||||
|
'- :wq\n'
|
||||||
|
'- ":wq"\n', # fails
|
||||||
|
conf, problem1=(3, 3), problem2=(5, 3), problem3=(7, 3))
|
||||||
|
self.check('---\n'
|
||||||
|
'k1: ---\n'
|
||||||
|
'k2: "---"\n' # fails
|
||||||
|
'k3: ----------\n'
|
||||||
|
'k4: "----------"\n' # fails
|
||||||
|
'k5: :wq\n'
|
||||||
|
'k6: ":wq"\n', # fails
|
||||||
|
conf, problem1=(3, 5), problem2=(5, 5), problem3=(7, 5))
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ indentation, etc."""
|
|||||||
|
|
||||||
|
|
||||||
APP_NAME = 'yamllint'
|
APP_NAME = 'yamllint'
|
||||||
APP_VERSION = '1.22.0'
|
APP_VERSION = '1.22.1'
|
||||||
APP_DESCRIPTION = __doc__
|
APP_DESCRIPTION = __doc__
|
||||||
|
|
||||||
__author__ = u'Adrien Vergé'
|
__author__ = u'Adrien Vergé'
|
||||||
|
|||||||
@@ -77,16 +77,30 @@ DEFAULT = {'quote-type': 'any',
|
|||||||
'required': True}
|
'required': True}
|
||||||
|
|
||||||
DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
|
DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
|
||||||
START_TOKENS = {'#', '*', '!', '?', '@', '`', '&',
|
|
||||||
',', '-', '{', '}', '[', ']', ':'}
|
|
||||||
|
|
||||||
|
|
||||||
def quote_match(quote_type, token_style):
|
def _quote_match(quote_type, token_style):
|
||||||
return ((quote_type == 'any') or
|
return ((quote_type == 'any') or
|
||||||
(quote_type == 'single' and token_style == "'") or
|
(quote_type == 'single' and token_style == "'") or
|
||||||
(quote_type == 'double' and token_style == '"'))
|
(quote_type == 'double' and token_style == '"'))
|
||||||
|
|
||||||
|
|
||||||
|
def _quotes_are_needed(string):
|
||||||
|
loader = yaml.BaseLoader('key: ' + string)
|
||||||
|
# Remove the 5 first tokens corresponding to 'key: ' (StreamStartToken,
|
||||||
|
# BlockMappingStartToken, KeyToken, ScalarToken(value=key), ValueToken)
|
||||||
|
for _ in range(5):
|
||||||
|
loader.get_token()
|
||||||
|
try:
|
||||||
|
a, b = loader.get_token(), loader.get_token()
|
||||||
|
if (isinstance(a, yaml.ScalarToken) and a.style is None and
|
||||||
|
isinstance(b, yaml.BlockEndToken)):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except yaml.scanner.ScannerError:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check(conf, token, prev, next, nextnext, context):
|
def check(conf, token, prev, next, nextnext, context):
|
||||||
if not (isinstance(token, yaml.tokens.ScalarToken) and
|
if not (isinstance(token, yaml.tokens.ScalarToken) and
|
||||||
isinstance(prev, (yaml.BlockEntryToken, yaml.FlowEntryToken,
|
isinstance(prev, (yaml.BlockEntryToken, yaml.FlowEntryToken,
|
||||||
@@ -121,25 +135,25 @@ def check(conf, token, prev, next, nextnext, context):
|
|||||||
if required is True:
|
if required is True:
|
||||||
|
|
||||||
# Quotes are mandatory and need to match config
|
# Quotes are mandatory and need to match config
|
||||||
if token.style is None or not quote_match(quote_type, token.style):
|
if token.style is None or not _quote_match(quote_type, token.style):
|
||||||
msg = "string value is not quoted with %s quotes" % (quote_type)
|
msg = "string value is not quoted with %s quotes" % (quote_type)
|
||||||
|
|
||||||
elif required is False:
|
elif required is False:
|
||||||
|
|
||||||
# Quotes are not mandatory but when used need to match config
|
# Quotes are not mandatory but when used need to match config
|
||||||
if token.style and not quote_match(quote_type, token.style):
|
if token.style and not _quote_match(quote_type, token.style):
|
||||||
msg = "string value is not quoted with %s quotes" % (quote_type)
|
msg = "string value is not quoted with %s quotes" % (quote_type)
|
||||||
|
|
||||||
elif not token.plain:
|
elif not token.plain:
|
||||||
|
|
||||||
# Quotes are disallowed when not needed
|
# Quotes are disallowed when not needed
|
||||||
if (tag == DEFAULT_SCALAR_TAG and token.value
|
if (tag == DEFAULT_SCALAR_TAG and token.value and
|
||||||
and token.value[0] not in START_TOKENS):
|
not _quotes_are_needed(token.value)):
|
||||||
msg = "string value is redundantly quoted with %s quotes" % (
|
msg = "string value is redundantly quoted with %s quotes" % (
|
||||||
quote_type)
|
quote_type)
|
||||||
|
|
||||||
# But when used need to match config
|
# But when used need to match config
|
||||||
elif token.style and not quote_match(quote_type, token.style):
|
elif token.style and not _quote_match(quote_type, token.style):
|
||||||
msg = "string value is not quoted with %s quotes" % (quote_type)
|
msg = "string value is not quoted with %s quotes" % (quote_type)
|
||||||
|
|
||||||
if msg is not None:
|
if msg is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user