From 4ef7e05f3a8e3e91b0c0691c6c02077e2408b681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ondrej=20Va=C5=A1ko?= Date: Thu, 6 Jun 2019 09:59:00 +0200 Subject: [PATCH] truthy: Add allowed-values configuration option Allows using key `allowed-values` for `truthy` section in configuration file (#150). This allows to use configuration `truthy: allowed-values: ["yes", "no", "..."]`, to set custom allowed truthy values. This is especially useful for people using ansible, where values like `yes` or `no` are valid and officially supported, but yamllint reports them as illegal. Implemented by difference of set of TRUTHY constants and configured allowed values. Signed-off-by: Ondrej Vasko --- tests/rules/test_truthy.py | 62 ++++++++++++++++++++++++++++++++++++++ yamllint/rules/truthy.py | 40 +++++++++++++++++++++--- 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/tests/rules/test_truthy.py b/tests/rules/test_truthy.py index b0402ed..796f3c7 100644 --- a/tests/rules/test_truthy.py +++ b/tests/rules/test_truthy.py @@ -49,6 +49,68 @@ class TruthyTestCase(RuleTestCase): problem3=(7, 3), problem4=(7, 7), problem5=(8, 3), problem6=(8, 7)) + def test_different_allowed_values(self): + conf = ('truthy:\n' + ' allowed-values: ["yes", "no"]\n') + self.check('---\n' + 'key1: foo\n' + 'key2: yes\n' + 'key3: bar\n' + 'key4: no\n', conf) + self.check('---\n' + 'key1: true\n' + 'key2: Yes\n' + 'key3: false\n' + 'key4: no\n' + 'key5: yes\n', + conf, + problem1=(2, 7), problem2=(3, 7), + problem3=(4, 7)) + + def test_combined_allowed_values(self): + conf = ('truthy:\n' + ' allowed-values: ["yes", "no", "true", "false"]\n') + self.check('---\n' + 'key1: foo\n' + 'key2: yes\n' + 'key3: bar\n' + 'key4: no\n', conf) + self.check('---\n' + 'key1: true\n' + 'key2: Yes\n' + 'key3: false\n' + 'key4: no\n' + 'key5: yes\n', + conf, problem1=(3, 7)) + + def test_no_allowed_values(self): + conf = ('truthy:\n' + ' allowed-values: []\n') + self.check('---\n' + 'key1: foo\n' + 'key2: bar\n', conf) + self.check('---\n' + 'key1: true\n' + 'key2: yes\n' + 'key3: false\n' + 'key4: no\n', conf, + problem1=(2, 7), problem2=(3, 7), + problem3=(4, 7), problem4=(5, 7)) + + def test_empty_string_allowed_values(self): + conf = ('truthy:\n' + ' allowed-values: ["", ""]\n') + self.check('---\n' + 'key1: foo\n' + 'key2: bar\n', conf) + self.check('---\n' + 'key1: true\n' + 'key2: yes\n' + 'key3: false\n' + 'key4: no\n', conf, + problem1=(2, 7), problem2=(3, 7), + problem3=(4, 7), problem4=(5, 7)) + def test_explicit_types(self): conf = 'truthy: enable\n' self.check('---\n' diff --git a/yamllint/rules/truthy.py b/yamllint/rules/truthy.py index b738dc2..89fbfff 100644 --- a/yamllint/rules/truthy.py +++ b/yamllint/rules/truthy.py @@ -22,6 +22,14 @@ This can be useful to prevent surprises from YAML parsers transforming ``[yes, FALSE, Off]`` into ``[true, false, false]`` or ``{y: 1, yes: 2, on: 3, true: 4, True: 5}`` into ``{y: 1, true: 5}``. +Default list of prohibited truthy values is ``YES, Yes, yes, NO, No, no, +TRUE, True, FALSE, False, ON, On, on, OFF, Off, off``. + +.. rubric:: Options + +* ``allowed-values`` defines list of truthy values, which will be ignored + during linting. + .. rubric:: Examples #. With ``truthy: {}`` @@ -63,6 +71,26 @@ This can be useful to prevent surprises from YAML parsers transforming yes: 1 on: 2 True: 3 + +#. With ``truthy: {allowed-values: ["yes", "no"]}`` + + the following code snippet would **PASS**: + :: + + - yes + - no + - "true" + - 'false' + - foo + - bar + + the following code snippet would **FAIL**: + :: + + - true + - false + - on + - off """ import yaml @@ -71,11 +99,13 @@ from yamllint.linter import LintProblem ID = 'truthy' TYPE = 'token' +CONF = {'allowed-values': list} +DEFAULT = {'allowed-values': ['true', 'false']} TRUTHY = ['YES', 'Yes', 'yes', 'NO', 'No', 'no', - 'TRUE', 'True', # 'true' is a boolean - 'FALSE', 'False', # 'false' is a boolean + 'TRUE', 'True', 'true', + 'FALSE', 'False', 'false', 'ON', 'On', 'on', 'OFF', 'Off', 'off'] @@ -85,7 +115,9 @@ def check(conf, token, prev, next, nextnext, context): return if isinstance(token, yaml.tokens.ScalarToken): - if token.value in TRUTHY and token.style is None: + if (token.value in (set(TRUTHY) - set(conf['allowed-values'])) and + token.style is None): yield LintProblem(token.start_mark.line + 1, token.start_mark.column + 1, - "truthy value should be true or false") + "truthy value should be one of [" + + ", ".join(sorted(conf['allowed-values'])) + "]")