From 9ee8c27ac95359e0f1fb2d82e632b04388b75b77 Mon Sep 17 00:00:00 2001 From: Mathieu Couette <12388398+MathieuCouette@users.noreply.github.com> Date: Tue, 29 Sep 2020 12:11:09 -0400 Subject: [PATCH 01/31] tests: Replace deprecated aliases https://docs.python.org/3/library/unittest.html#deprecated-aliases --- tests/test_cli.py | 16 ++++++++-------- tests/test_config.py | 6 +++--- tests/test_module.py | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 020b371..b243b93 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -246,19 +246,19 @@ class CommandLineTestCase(unittest.TestCase): cli.run(()) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches(ctx.stderr, r'^usage') + self.assertRegex(ctx.stderr, r'^usage') with RunContext(self) as ctx: cli.run(('--unknown-arg', )) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches(ctx.stderr, r'^usage') + self.assertRegex(ctx.stderr, r'^usage') with RunContext(self) as ctx: cli.run(('-c', './conf.yaml', '-d', 'relaxed', 'file')) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches( + self.assertRegex( ctx.stderr.splitlines()[-1], r'^yamllint: error: argument -d\/--config-data: ' r'not allowed with argument -c\/--config-file$' @@ -269,21 +269,21 @@ class CommandLineTestCase(unittest.TestCase): cli.run(('-', 'file')) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches(ctx.stderr, r'^usage') + self.assertRegex(ctx.stderr, r'^usage') def test_run_with_bad_config(self): with RunContext(self) as ctx: cli.run(('-d', 'rules: {a: b}', 'file')) self.assertEqual(ctx.returncode, -1) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches(ctx.stderr, r'^invalid config: no such rule') + self.assertRegex(ctx.stderr, r'^invalid config: no such rule') def test_run_with_empty_config(self): with RunContext(self) as ctx: cli.run(('-d', '', 'file')) self.assertEqual(ctx.returncode, -1) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches(ctx.stderr, r'^invalid config: not a dict') + self.assertRegex(ctx.stderr, r'^invalid config: not a dict') def test_run_with_config_file(self): with open(os.path.join(self.wd, 'config'), 'w') as f: @@ -386,7 +386,7 @@ class CommandLineTestCase(unittest.TestCase): with RunContext(self) as ctx: cli.run(('--version', )) self.assertEqual(ctx.returncode, 0) - self.assertRegexpMatches(ctx.stdout + ctx.stderr, r'yamllint \d+\.\d+') + self.assertRegex(ctx.stdout + ctx.stderr, r'yamllint \d+\.\d+') def test_run_non_existing_file(self): path = os.path.join(self.wd, 'i-do-not-exist.yaml') @@ -395,7 +395,7 @@ class CommandLineTestCase(unittest.TestCase): cli.run(('-f', 'parsable', path)) self.assertEqual(ctx.returncode, -1) self.assertEqual(ctx.stdout, '') - self.assertRegexpMatches(ctx.stderr, r'No such file or directory') + self.assertRegex(ctx.stderr, r'No such file or directory') def test_run_one_problem_file(self): path = os.path.join(self.wd, 'a.yaml') diff --git a/tests/test_config.py b/tests/test_config.py index b48546c..01ca5af 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -48,7 +48,7 @@ class SimpleConfigTestCase(unittest.TestCase): config.YamlLintConfig('not: valid: yaml') def test_unknown_rule(self): - with self.assertRaisesRegexp( + with self.assertRaisesRegex( config.YamlLintConfigError, 'invalid config: no such rule: "this-one-does-not-exist"'): config.YamlLintConfig('rules:\n' @@ -67,7 +67,7 @@ class SimpleConfigTestCase(unittest.TestCase): self.assertEqual(c.rules['colons']['max-spaces-after'], 1) def test_unknown_option(self): - with self.assertRaisesRegexp( + with self.assertRaisesRegex( config.YamlLintConfigError, 'invalid config: unknown option "abcdef" for rule "colons"'): config.YamlLintConfig('rules:\n' @@ -105,7 +105,7 @@ class SimpleConfigTestCase(unittest.TestCase): self.assertEqual(c.rules['indentation']['check-multi-line-strings'], False) - with self.assertRaisesRegexp( + with self.assertRaisesRegex( config.YamlLintConfigError, 'invalid config: option "indent-sequences" of "indentation" ' 'should be in '): diff --git a/tests/test_module.py b/tests/test_module.py index e1bf066..0407ad8 100644 --- a/tests/test_module.py +++ b/tests/test_module.py @@ -47,7 +47,7 @@ class ModuleTestCase(unittest.TestCase): subprocess.check_output([PYTHON, '-m', 'yamllint'], stderr=subprocess.STDOUT) self.assertEqual(ctx.exception.returncode, 2) - self.assertRegexpMatches(ctx.exception.output.decode(), + self.assertRegex(ctx.exception.output.decode(), r'^usage: yamllint') def test_run_module_on_bad_dir(self): @@ -55,7 +55,7 @@ class ModuleTestCase(unittest.TestCase): subprocess.check_output([PYTHON, '-m', 'yamllint', '/does/not/exist'], stderr=subprocess.STDOUT) - self.assertRegexpMatches(ctx.exception.output.decode(), + self.assertRegex(ctx.exception.output.decode(), r'No such file or directory') def test_run_module_on_file(self): From 11b1f1c14e2c5433d267c53c3e2aa6ce57210962 Mon Sep 17 00:00:00 2001 From: Mathieu Couette <12388398+MathieuCouette@users.noreply.github.com> Date: Thu, 8 Oct 2020 17:29:06 -0400 Subject: [PATCH 02/31] tests: Fix indentation issues --- tests/test_module.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_module.py b/tests/test_module.py index 0407ad8..570992d 100644 --- a/tests/test_module.py +++ b/tests/test_module.py @@ -47,8 +47,7 @@ class ModuleTestCase(unittest.TestCase): subprocess.check_output([PYTHON, '-m', 'yamllint'], stderr=subprocess.STDOUT) self.assertEqual(ctx.exception.returncode, 2) - self.assertRegex(ctx.exception.output.decode(), - r'^usage: yamllint') + self.assertRegex(ctx.exception.output.decode(), r'^usage: yamllint') def test_run_module_on_bad_dir(self): with self.assertRaises(subprocess.CalledProcessError) as ctx: @@ -56,7 +55,7 @@ class ModuleTestCase(unittest.TestCase): '/does/not/exist'], stderr=subprocess.STDOUT) self.assertRegex(ctx.exception.output.decode(), - r'No such file or directory') + r'No such file or directory') def test_run_module_on_file(self): out = subprocess.check_output( From cef0b48993820349947d1963bff7fea388f6ecdb Mon Sep 17 00:00:00 2001 From: Mathieu Couette <12388398+MathieuCouette@users.noreply.github.com> Date: Fri, 9 Oct 2020 04:36:57 -0400 Subject: [PATCH 03/31] tests: Add unittest aliases to Python 2.7 --- tests/test_cli.py | 5 +++++ tests/test_config.py | 9 +++++++++ tests/test_module.py | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/tests/test_cli.py b/tests/test_cli.py index b243b93..0a4e01c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -71,6 +71,11 @@ class CommandLineTestCase(unittest.TestCase): def setUpClass(cls): super(CommandLineTestCase, cls).setUpClass() + # https://docs.python.org/3/library/unittest.html#deprecated-aliases + if sys.version_info < (3, 2): + cls.assertRegex = cls.assertRegexpMatches + cls.assertRaisesRegex = cls.assertRaisesRegexp + cls.wd = build_temp_workspace({ # .yaml file at root 'a.yaml': '---\n' diff --git a/tests/test_config.py b/tests/test_config.py index 01ca5af..5e33e4b 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -31,6 +31,15 @@ from yamllint import config class SimpleConfigTestCase(unittest.TestCase): + @classmethod + def setUpClass(cls): + super(SimpleConfigTestCase, cls).setUpClass() + + # https://docs.python.org/3/library/unittest.html#deprecated-aliases + if sys.version_info < (3, 2): + cls.assertRegex = cls.assertRegexpMatches + cls.assertRaisesRegex = cls.assertRaisesRegexp + def test_parse_config(self): new = config.YamlLintConfig('rules:\n' ' colons:\n' diff --git a/tests/test_module.py b/tests/test_module.py index 570992d..b72e767 100644 --- a/tests/test_module.py +++ b/tests/test_module.py @@ -26,6 +26,15 @@ PYTHON = sys.executable or 'python' class ModuleTestCase(unittest.TestCase): + @classmethod + def setUpClass(cls): + super(ModuleTestCase, cls).setUpClass() + + # https://docs.python.org/3/library/unittest.html#deprecated-aliases + if sys.version_info < (3, 2): + cls.assertRegex = cls.assertRegexpMatches + cls.assertRaisesRegex = cls.assertRaisesRegexp + def setUp(self): self.wd = tempfile.mkdtemp(prefix='yamllint-tests-') From 0f9dffde237bbbc01fc36692c7c45ed8cdaadbc4 Mon Sep 17 00:00:00 2001 From: Rex Ledesma Date: Sat, 24 Oct 2020 04:24:55 -0700 Subject: [PATCH 04/31] docs: Add configuration for integration with Arcanist --- docs/integration.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/integration.rst b/docs/integration.rst index b094edc..75a1f0c 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -51,3 +51,22 @@ An example workflow using GitHub Actions: - name: Lint YAML files run: yamllint . + +Integration with Arcanist +------------------------- + +You can configure yamllint to run on ``arc lint``. Here is an example +``.arclint`` file that makes use of this configuration. + +.. code:: json + + { + "linters": { + "yamllint": { + "type": "script-and-regex", + "script-and-regex.script": "yamllint", + "script-and-regex.regex": "/^(?P\\d+):(?P\\d+) +(?Pwarning|error) +(?P.*) +\\((?P.*)\\)$/m", + "include": "(\\.(yml|yaml)$)" + } + } + } From 22335b294d0cf5d152c0f092dd323b851593af74 Mon Sep 17 00:00:00 2001 From: Jason Mobarak Date: Thu, 3 Dec 2020 22:15:50 -0800 Subject: [PATCH 05/31] Add support for Python 3.9, drop Python 3.4 Add support for Python 3.9 since it was officially released in October and drop support for Python 3.4 since it is end-of-life (EOL). --- .travis.yml | 1 + setup.cfg | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c7c311c..5857563 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ python: - 3.6 - 3.7 - 3.8 + - 3.9 - nightly env: - REMOVE_LOCALES=false diff --git a/setup.cfg b/setup.cfg index 246c468..1690ac2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,11 +29,11 @@ classifiers = Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Topic :: Software Development Topic :: Software Development :: Debuggers Topic :: Software Development :: Quality Assurance @@ -48,7 +48,7 @@ project_urls = [options] packages = find: -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* include_package_data = True install_requires = From ee4d163ff831b17103001fc450b9ea1470b51e29 Mon Sep 17 00:00:00 2001 From: Rusty Geldmacher Date: Tue, 15 Dec 2020 05:52:21 -0500 Subject: [PATCH 06/31] Allow only non-empty brackets/braces We'd like to disallow brackets and braces in our YAML, but there's a catch: the only way to describe an empty array or hash in YAML is to supply an empty one (`[]` or `{}`). Otherwise, the value will be null. This commit adds a `non-empty` option to `forbid` for brackets and braces. When it is set, all flow and sequence mappings will cause errors _except_ for empty ones. --- tests/rules/test_braces.py | 24 ++++++++++++++++++++++++ tests/rules/test_brackets.py | 23 +++++++++++++++++++++++ yamllint/rules/braces.py | 27 ++++++++++++++++++++++++--- yamllint/rules/brackets.py | 27 ++++++++++++++++++++++++--- 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/tests/rules/test_braces.py b/tests/rules/test_braces.py index 69c5461..cae7014 100644 --- a/tests/rules/test_braces.py +++ b/tests/rules/test_braces.py @@ -61,6 +61,30 @@ class ColonTestCase(RuleTestCase): ' a: 1\n' '}\n', conf, problem=(2, 8)) + conf = ('braces:\n' + ' forbid: non-empty\n') + self.check('---\n' + 'dict:\n' + ' a: 1\n', conf) + self.check('---\n' + 'dict: {}\n', conf) + self.check('---\n' + 'dict: {\n' + '}\n', conf) + self.check('---\n' + 'dict: {\n' + '# commented: value\n' + '# another: value2\n' + '}\n', conf) + self.check('---\n' + 'dict: {a}\n', conf, problem=(2, 8)) + self.check('---\n' + 'dict: {a: 1}\n', conf, problem=(2, 8)) + self.check('---\n' + 'dict: {\n' + ' a: 1\n' + '}\n', conf, problem=(2, 8)) + def test_min_spaces(self): conf = ('braces:\n' ' max-spaces-inside: -1\n' diff --git a/tests/rules/test_brackets.py b/tests/rules/test_brackets.py index a35eff9..41f20a7 100644 --- a/tests/rules/test_brackets.py +++ b/tests/rules/test_brackets.py @@ -60,6 +60,29 @@ class ColonTestCase(RuleTestCase): ' b\n' ']\n', conf, problem=(2, 9)) + conf = ('brackets:\n' + ' forbid: non-empty\n') + self.check('---\n' + 'array:\n' + ' - a\n' + ' - b\n', conf) + self.check('---\n' + 'array: []\n', conf) + self.check('---\n' + 'array: [\n\n' + ']\n', conf) + self.check('---\n' + 'array: [\n' + '# a comment\n' + ']\n', conf) + self.check('---\n' + 'array: [a, b]\n', conf, problem=(2, 9)) + self.check('---\n' + 'array: [\n' + ' a,\n' + ' b\n' + ']\n', conf, problem=(2, 9)) + def test_min_spaces(self): conf = ('brackets:\n' ' max-spaces-inside: -1\n' diff --git a/yamllint/rules/braces.py b/yamllint/rules/braces.py index 759306e..d3c03fb 100644 --- a/yamllint/rules/braces.py +++ b/yamllint/rules/braces.py @@ -22,7 +22,8 @@ braces (``{`` and ``}``). * ``forbid`` is used to forbid the use of flow mappings which are denoted by surrounding braces (``{`` and ``}``). Use ``true`` to forbid the use of flow - mappings completely. + mappings completely. Use ``non-empty`` to forbid the use of all flow + mappings except for empty ones. * ``min-spaces-inside`` defines the minimal number of spaces required inside braces. * ``max-spaces-inside`` defines the maximal number of spaces allowed inside @@ -60,6 +61,18 @@ braces (``{`` and ``}``). object: { key1: 4, key2: 8 } +#. With ``braces: {forbid: non-empty}`` + + the following code snippet would **PASS**: + :: + + object: {} + + the following code snippet would **FAIL**: + :: + + object: { key1: 4, key2: 8 } + #. With ``braces: {min-spaces-inside: 0, max-spaces-inside: 0}`` the following code snippet would **PASS**: @@ -128,7 +141,7 @@ from yamllint.rules.common import spaces_after, spaces_before ID = 'braces' TYPE = 'token' -CONF = {'forbid': bool, +CONF = {'forbid': (bool, 'non-empty'), 'min-spaces-inside': int, 'max-spaces-inside': int, 'min-spaces-inside-empty': int, @@ -141,7 +154,15 @@ DEFAULT = {'forbid': False, def check(conf, token, prev, next, nextnext, context): - if conf['forbid'] and isinstance(token, yaml.FlowMappingStartToken): + if (conf['forbid'] is True and + isinstance(token, yaml.FlowMappingStartToken)): + yield LintProblem(token.start_mark.line + 1, + token.end_mark.column + 1, + 'forbidden flow mapping') + + elif (conf['forbid'] == 'non-empty' and + isinstance(token, yaml.FlowMappingStartToken) and + not isinstance(next, yaml.FlowMappingEndToken)): yield LintProblem(token.start_mark.line + 1, token.end_mark.column + 1, 'forbidden flow mapping') diff --git a/yamllint/rules/brackets.py b/yamllint/rules/brackets.py index 6ab02df..01fee87 100644 --- a/yamllint/rules/brackets.py +++ b/yamllint/rules/brackets.py @@ -22,7 +22,8 @@ inside brackets (``[`` and ``]``). * ``forbid`` is used to forbid the use of flow sequences which are denoted by surrounding brackets (``[`` and ``]``). Use ``true`` to forbid the use of - flow sequences completely. + flow sequences completely. Use ``non-empty`` to forbid the use of all flow + sequences except for empty ones. * ``min-spaces-inside`` defines the minimal number of spaces required inside brackets. * ``max-spaces-inside`` defines the maximal number of spaces allowed inside @@ -61,6 +62,18 @@ inside brackets (``[`` and ``]``). object: [ 1, 2, abc ] +#. With ``brackets: {forbid: non-empty}`` + + the following code snippet would **PASS**: + :: + + object: [] + + the following code snippet would **FAIL**: + :: + + object: [ 1, 2, abc ] + #. With ``brackets: {min-spaces-inside: 0, max-spaces-inside: 0}`` the following code snippet would **PASS**: @@ -129,7 +142,7 @@ from yamllint.rules.common import spaces_after, spaces_before ID = 'brackets' TYPE = 'token' -CONF = {'forbid': bool, +CONF = {'forbid': (bool, 'non-empty'), 'min-spaces-inside': int, 'max-spaces-inside': int, 'min-spaces-inside-empty': int, @@ -142,7 +155,15 @@ DEFAULT = {'forbid': False, def check(conf, token, prev, next, nextnext, context): - if conf['forbid'] and isinstance(token, yaml.FlowSequenceStartToken): + if (conf['forbid'] is True and + isinstance(token, yaml.FlowSequenceStartToken)): + yield LintProblem(token.start_mark.line + 1, + token.end_mark.column + 1, + 'forbidden flow sequence') + + elif (conf['forbid'] == 'non-empty' and + isinstance(token, yaml.FlowSequenceStartToken) and + not isinstance(next, yaml.FlowSequenceEndToken)): yield LintProblem(token.start_mark.line + 1, token.end_mark.column + 1, 'forbidden flow sequence') From a3fc64d13407869607c07096d8591bdc17ff645f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Tue, 5 Jan 2021 08:20:57 +0100 Subject: [PATCH 07/31] End support for Python 2 As planned and advertized, yamllint drops support for Python 2 on 2021. --- .travis.yml | 10 +++------- README.rst | 6 +----- setup.cfg | 4 +--- tests/rules/test_line_length.py | 4 ---- tests/test_cli.py | 10 +--------- tests/test_config.py | 14 +------------- tests/test_module.py | 9 --------- yamllint/linter.py | 2 +- yamllint/rules/line_length.py | 4 ---- 9 files changed, 8 insertions(+), 55 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5857563..90a432f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069) language: python python: - - 2.7 - 3.5 - 3.6 - 3.7 @@ -13,17 +12,14 @@ env: - REMOVE_LOCALES=false - REMOVE_LOCALES=true install: - - pip install pyyaml coveralls flake8 flake8-import-order doc8 - - if [[ $TRAVIS_PYTHON_VERSION != 2* ]]; then pip install sphinx; fi + - pip install pyyaml coveralls flake8 flake8-import-order doc8 sphinx - pip install . - if [[ $REMOVE_LOCALES = "true" ]]; then sudo rm -rf /usr/lib/locale/*; fi script: - if [[ $TRAVIS_PYTHON_VERSION != nightly ]]; then flake8 .; fi - - if [[ $TRAVIS_PYTHON_VERSION != 2* ]]; then doc8 $(git ls-files '*.rst'); fi + - doc8 $(git ls-files '*.rst') - yamllint --strict $(git ls-files '*.yaml' '*.yml') - coverage run --source=yamllint -m unittest discover - - if [[ $TRAVIS_PYTHON_VERSION != 2* ]]; then - python setup.py build_sphinx; - fi + - python setup.py build_sphinx after_success: coveralls diff --git a/README.rst b/README.rst index 496b152..3383ec4 100644 --- a/README.rst +++ b/README.rst @@ -19,11 +19,7 @@ indentation, etc. :target: https://yamllint.readthedocs.io/en/latest/?badge=latest :alt: Documentation status -Written in Python (compatible with Python 2 & 3). - -⚠ Python 2 upstream support stopped on January 1, 2020. yamllint will keep -best-effort support for Python 2.7 until January 1, 2021. Past that date, -yamllint will drop all Python 2-related code. +Written in Python (compatible with Python 3 only). Documentation ------------- diff --git a/setup.cfg b/setup.cfg index 1690ac2..97b77f4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,8 +26,6 @@ classifiers = Environment :: Console Intended Audience :: Developers License :: OSI Approved :: GNU General Public License v3 (GPLv3) - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 @@ -48,7 +46,7 @@ project_urls = [options] packages = find: -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +python_requires = >=3.5.* include_package_data = True install_requires = diff --git a/tests/rules/test_line_length.py b/tests/rules/test_line_length.py index c1865f1..d63afb3 100644 --- a/tests/rules/test_line_length.py +++ b/tests/rules/test_line_length.py @@ -14,9 +14,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys -import unittest - from tests.common import RuleTestCase @@ -159,7 +156,6 @@ class LineLengthTestCase(RuleTestCase): ' {% this line is' + 99 * ' really' + ' long %}\n', conf, problem=(3, 81)) - @unittest.skipIf(sys.version_info < (3, 0), 'Python 2 not supported') def test_unicode(self): conf = 'line-length: {max: 53}' self.check('---\n' diff --git a/tests/test_cli.py b/tests/test_cli.py index 0a4e01c..0cb300a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -14,10 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -try: - from cStringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO import fcntl import locale import os @@ -71,11 +68,6 @@ class CommandLineTestCase(unittest.TestCase): def setUpClass(cls): super(CommandLineTestCase, cls).setUpClass() - # https://docs.python.org/3/library/unittest.html#deprecated-aliases - if sys.version_info < (3, 2): - cls.assertRegex = cls.assertRegexpMatches - cls.assertRaisesRegex = cls.assertRaisesRegexp - cls.wd = build_temp_workspace({ # .yaml file at root 'a.yaml': '---\n' diff --git a/tests/test_config.py b/tests/test_config.py index 5e33e4b..70a73e0 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -14,10 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -try: - from cStringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO import os import shutil import sys @@ -31,15 +28,6 @@ from yamllint import config class SimpleConfigTestCase(unittest.TestCase): - @classmethod - def setUpClass(cls): - super(SimpleConfigTestCase, cls).setUpClass() - - # https://docs.python.org/3/library/unittest.html#deprecated-aliases - if sys.version_info < (3, 2): - cls.assertRegex = cls.assertRegexpMatches - cls.assertRaisesRegex = cls.assertRaisesRegexp - def test_parse_config(self): new = config.YamlLintConfig('rules:\n' ' colons:\n' diff --git a/tests/test_module.py b/tests/test_module.py index b72e767..570992d 100644 --- a/tests/test_module.py +++ b/tests/test_module.py @@ -26,15 +26,6 @@ PYTHON = sys.executable or 'python' class ModuleTestCase(unittest.TestCase): - @classmethod - def setUpClass(cls): - super(ModuleTestCase, cls).setUpClass() - - # https://docs.python.org/3/library/unittest.html#deprecated-aliases - if sys.version_info < (3, 2): - cls.assertRegex = cls.assertRegexpMatches - cls.assertRaisesRegex = cls.assertRaisesRegexp - def setUp(self): self.wd = tempfile.mkdtemp(prefix='yamllint-tests-') diff --git a/yamllint/linter.py b/yamllint/linter.py index 83e792c..7e0fb55 100644 --- a/yamllint/linter.py +++ b/yamllint/linter.py @@ -233,7 +233,7 @@ def run(input, conf, filepath=None): if conf.is_file_ignored(filepath): return () - if isinstance(input, (type(b''), type(u''))): # compat with Python 2 & 3 + if isinstance(input, (bytes, str)): return _run(input, conf, filepath) elif hasattr(input, 'read'): # Python 2's file or Python 3's io.IOBase # We need to have everything in memory to parse correctly diff --git a/yamllint/rules/line_length.py b/yamllint/rules/line_length.py index b329817..0431240 100644 --- a/yamllint/rules/line_length.py +++ b/yamllint/rules/line_length.py @@ -17,10 +17,6 @@ """ Use this rule to set a limit to lines length. -Note: with Python 2, the ``line-length`` rule may not work properly with -unicode characters because of the way strings are represented in bytes. We -recommend running yamllint with Python 3. - .. rubric:: Options * ``max`` defines the maximal (inclusive) length of lines. From 1b378ed5b9b5429ba949d0440f26b61926fc8bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Tue, 5 Jan 2021 09:56:08 +0100 Subject: [PATCH 08/31] quoted-strings: Fix explicit octal recognition PyYAML implements YAML spec version 1.1, not 1.2. Hence, values starting with `0o` are not considered as numbers: they are just strings, so they need quotes when `quoted-strings: {required: true}`. >>> import yaml >>> yaml.resolver.Resolver().resolve(yaml.nodes.ScalarNode, '100', (True, False)) 'tag:yaml.org,2002:int' >>> yaml.resolver.Resolver().resolve(yaml.nodes.ScalarNode, '0100', (True, False)) 'tag:yaml.org,2002:int' >>> yaml.resolver.Resolver().resolve(yaml.nodes.ScalarNode, '0o100', (True, False)) 'tag:yaml.org,2002:str' Let's try to prevent that. Fixes https://github.com/adrienverge/yamllint/issues/351. --- tests/rules/test_quoted_strings.py | 18 ++++++++++++++++++ yamllint/rules/quoted_strings.py | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/tests/rules/test_quoted_strings.py b/tests/rules/test_quoted_strings.py index 1ee86a1..79f36bc 100644 --- a/tests/rules/test_quoted_strings.py +++ b/tests/rules/test_quoted_strings.py @@ -436,3 +436,21 @@ class QuotedTestCase(RuleTestCase): '- foo bar\n' '- "foo bar"\n', conf, problem1=(3, 3), problem2=(7, 3), problem3=(11, 3)) + + def test_octal_values(self): + conf = 'quoted-strings: {required: true}\n' + + self.check('---\n' + '- 100\n' + '- 0100\n' + '- 0o100\n' + '- 777\n' + '- 0777\n' + '- 0o777\n' + '- 800\n' + '- 0800\n' + '- 0o800\n' + '- "0800"\n' + '- "0o800"\n', + conf, + problem1=(9, 3), problem2=(10, 3)) diff --git a/yamllint/rules/quoted_strings.py b/yamllint/rules/quoted_strings.py index 279cd6a..1ef18db 100644 --- a/yamllint/rules/quoted_strings.py +++ b/yamllint/rules/quoted_strings.py @@ -144,6 +144,17 @@ def VALIDATE(conf): DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' +# https://stackoverflow.com/a/36514274 +yaml.resolver.Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:int', + re.compile(r'''^(?:[-+]?0b[0-1_]+ + |[-+]?0o?[0-7_]+ + |[-+]?0[0-7_]+ + |[-+]?(?:0|[1-9][0-9_]*) + |[-+]?0x[0-9a-fA-F_]+ + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), + list('-+0123456789')) + def _quote_match(quote_type, token_style): return ((quote_type == 'any') or From 0fff4e29e42d170cd0d1ad17736acdc53df97fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Fri, 29 Jan 2021 18:10:35 +0100 Subject: [PATCH 09/31] yamllint version 1.26.0 --- CHANGELOG.rst | 10 ++++++++++ yamllint/__init__.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 39fce9c..4fcc4ea 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,16 @@ Changelog ========= +1.26.0 (2021-01-29) +------------------- + +- End support for Python 2 and Python 3.4, add support for Python 3.9 +- Add ``forbid: non-empty`` option to ``braces`` and ``brackets`` rules +- Fix ``quoted-strings`` for explicit octal recognition +- Add documentation for integration with Arcanist +- Fix typos in changelog and README +- Stop using deprecated ``python setup.py test`` in tests + 1.25.0 (2020-09-29) ------------------- diff --git a/yamllint/__init__.py b/yamllint/__init__.py index bd04714..3c2af07 100644 --- a/yamllint/__init__.py +++ b/yamllint/__init__.py @@ -22,7 +22,7 @@ indentation, etc.""" APP_NAME = 'yamllint' -APP_VERSION = '1.25.0' +APP_VERSION = '1.26.0' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Vergé' From 8f682481c725047d3eb9409faecf0719caec1b8a Mon Sep 17 00:00:00 2001 From: "Daniel M. Capella" Date: Thu, 11 Feb 2021 07:55:08 +0000 Subject: [PATCH 10/31] Remove runtime dep 'setuptools' for Python < 3.8 > In recent versions of setuptools and Python, console-script entry points are using stdlib importlib by default, thus setuptools is no longer needed as a runtime dependency. https://github.com/pypa/setuptools/pull/2197 https://github.com/pypa/setuptools/blob/main/CHANGES.rst#v4730 https://docs.python.org/3/library/importlib.metadata.html --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 97b77f4..c5ef250 100644 --- a/setup.cfg +++ b/setup.cfg @@ -52,7 +52,7 @@ include_package_data = True install_requires = pathspec >= 0.5.3 pyyaml - setuptools + setuptools; python_version < "3.8" test_suite = tests From 66bf76a36288a63d14395542df750221623115c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Mon, 15 Mar 2021 18:36:43 +0100 Subject: [PATCH 11/31] CI: Switch to GitHub Actions Because Travis CI is dead. --- .github/workflows/ci.yaml | 52 +++++++++++++++++++++++++++++++++++++++ .travis.yml | 25 ------------------- setup.cfg | 3 +++ tests/test_cli.py | 1 + 4 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/ci.yaml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..1c47345 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,52 @@ +--- + +name: CI + +on: # yamllint disable-line rule:truthy + push: + pull_request: + branches: + - master + +jobs: + lint: + name: Linters + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - run: python -m pip install flake8 flake8-import-order doc8 sphinx + - run: python -m pip install . + - run: flake8 . + - run: doc8 $(git ls-files '*.rst') + - run: yamllint --strict $(git ls-files '*.yaml' '*.yml') + - run: python setup.py build_sphinx + + test: + name: Tests + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - 3.5 + - 3.6 + - 3.7 + - 3.8 + - 3.9 + - nightly + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.pyver }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.pyver }} + - run: python -m pip install coveralls + - run: python -m pip install . + - run: coverage run --source=yamllint -m unittest discover + - name: Coveralls + uses: AndreMiras/coveralls-python-action@develop diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 90a432f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069) -language: python -python: - - 3.5 - - 3.6 - - 3.7 - - 3.8 - - 3.9 - - nightly -env: - - REMOVE_LOCALES=false - - REMOVE_LOCALES=true -install: - - pip install pyyaml coveralls flake8 flake8-import-order doc8 sphinx - - pip install . - - if [[ $REMOVE_LOCALES = "true" ]]; then sudo rm -rf /usr/lib/locale/*; fi -script: - - if [[ $TRAVIS_PYTHON_VERSION != nightly ]]; then flake8 .; fi - - doc8 $(git ls-files '*.rst') - - yamllint --strict $(git ls-files '*.yaml' '*.yml') - - coverage run --source=yamllint -m unittest discover - - python setup.py build_sphinx -after_success: - coveralls diff --git a/setup.cfg b/setup.cfg index c5ef250..c5adb55 100644 --- a/setup.cfg +++ b/setup.cfg @@ -67,3 +67,6 @@ yamllint = conf/*.yaml [options.entry_points] console_scripts = yamllint = yamllint.cli:run + +[coverage:run] +relative_files = True diff --git a/tests/test_cli.py b/tests/test_cli.py index 0cb300a..79c4320 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -297,6 +297,7 @@ class CommandLineTestCase(unittest.TestCase): cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml'))) self.assertEqual(ctx.returncode, 1) + @unittest.skipIf(os.environ.get('GITHUB_RUN_ID'), '$HOME not overridable') def test_run_with_user_global_config_file(self): home = os.path.join(self.wd, 'fake-home') dir = os.path.join(home, '.config', 'yamllint') From 4515269233164f92352501bcd2a623c57c2177af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Wed, 24 Mar 2021 16:53:03 +0100 Subject: [PATCH 12/31] CI: Fix failing 'coverage' command because of $PATH Very probably due to: https://github.com/actions/virtual-environments/issues/2455#issuecomment-787511010 --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1c47345..4e4b599 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -45,6 +45,8 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.pyver }} + - name: Fix GitHub Actions path + run: echo /home/runner/.local/bin >>$GITHUB_PATH - run: python -m pip install coveralls - run: python -m pip install . - run: coverage run --source=yamllint -m unittest discover From 5d8ef2ea2318f941b6bfe508b479f873bb8294b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Wed, 24 Mar 2021 17:14:38 +0100 Subject: [PATCH 13/31] CI: Simplify 'pip' commands --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4e4b599..54fa582 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -47,8 +47,8 @@ jobs: python-version: ${{ matrix.pyver }} - name: Fix GitHub Actions path run: echo /home/runner/.local/bin >>$GITHUB_PATH - - run: python -m pip install coveralls - - run: python -m pip install . + - run: pip install coveralls + - run: pip install . - run: coverage run --source=yamllint -m unittest discover - name: Coveralls uses: AndreMiras/coveralls-python-action@develop From e53ea093e24c718baf17eeebdbebc3b612adb906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= <69143962+pmalek-sumo@users.noreply.github.com> Date: Wed, 24 Mar 2021 18:04:48 +0100 Subject: [PATCH 14/31] line_length: skip all hash signs starting comment --- tests/rules/test_line_length.py | 21 +++++++++++++++++++++ yamllint/rules/line_length.py | 6 +++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/rules/test_line_length.py b/tests/rules/test_line_length.py index d63afb3..245fe4d 100644 --- a/tests/rules/test_line_length.py +++ b/tests/rules/test_line_length.py @@ -116,6 +116,27 @@ class LineLengthTestCase(RuleTestCase): 'long_line: http://localhost/very/very/long/url\n' '...\n', conf, problem=(2, 21)) + conf = 'line-length: {max: 20, allow-non-breakable-words: true}' + self.check('---\n' + '# http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', conf) + self.check('---\n' + '## http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', conf) + self.check('---\n' + '# # http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', conf, + problem=(2, 21)) + self.check('---\n' + '#A http://www.verylongurlurlurlurlurlurlurlurl.com\n' + 'key:\n' + ' subkey: value\n', conf, + problem1=(2, 2, 'comments'), + problem2=(2, 21, 'line-length')) + conf = ('line-length: {max: 20, allow-non-breakable-words: true}\n' 'trailing-spaces: disable') self.check('---\n' diff --git a/yamllint/rules/line_length.py b/yamllint/rules/line_length.py index 0431240..cfc328c 100644 --- a/yamllint/rules/line_length.py +++ b/yamllint/rules/line_length.py @@ -140,7 +140,11 @@ def check(conf, line): start += 1 if start != line.end: - if line.buffer[start] in ('#', '-'): + if line.buffer[start] == '#': + while line.buffer[start] == '#': + start += 1 + start += 1 + elif line.buffer[start] == '-': start += 2 if line.buffer.find(' ', start, line.end) == -1: From 85ccd625a382423edd988fcb796c4dd5897886fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Tue, 6 Apr 2021 16:02:55 +0200 Subject: [PATCH 15/31] yamllint version 1.26.1 --- CHANGELOG.rst | 6 ++++++ yamllint/__init__.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4fcc4ea..2249895 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Changelog ========= +1.26.1 (2021-04-06) +------------------- + +- Remove runtime dependency ``setuptools`` for Python < 3.8 +- Fix ``line_length`` to skip all hash signs starting comment + 1.26.0 (2021-01-29) ------------------- diff --git a/yamllint/__init__.py b/yamllint/__init__.py index 3c2af07..1153277 100644 --- a/yamllint/__init__.py +++ b/yamllint/__init__.py @@ -22,7 +22,7 @@ indentation, etc.""" APP_NAME = 'yamllint' -APP_VERSION = '1.26.0' +APP_VERSION = '1.26.1' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Vergé' From 43744902e90fb33905f1000875c60acd06661f2c Mon Sep 17 00:00:00 2001 From: Kyle Finley Date: Thu, 10 Jun 2021 10:16:22 -0400 Subject: [PATCH 16/31] setup: update python_requires to comply with PEP 345/440 According to PEP 345 Requires-Python (https://www.python.org/dev/peps/pep-0345/#requires-python), the value of this field must be a valid Version Specifier (https://www.python.org/dev/peps/pep-0345/#version-specifiers). Which in turn expects this to comply with PEP 440 (https://www.python.org/dev/peps/pep-0440/). While not an issue for those that directly use `pip`, this will cause issues for `poetry` users in the next release (if their current stance is maintained). Discussion of the issue and there stance can be found here: https://github.com/python-poetry/poetry/issues/4095. --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index c5adb55..6dd9ce8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,7 +46,7 @@ project_urls = [options] packages = find: -python_requires = >=3.5.* +python_requires = >=3.5 include_package_data = True install_requires = From 33ce0fa960cc8f1ad3274ce7c2bc4bee18270000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Tue, 3 Aug 2021 12:57:43 +0200 Subject: [PATCH 17/31] yamllint version 1.26.2 --- CHANGELOG.rst | 5 +++++ yamllint/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2249895..fb0e804 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ Changelog ========= +1.26.2 (2021-08-03) +------------------- + +- Fix ``python_requires`` to comply with PEP 345 and PEP 440 + 1.26.1 (2021-04-06) ------------------- diff --git a/yamllint/__init__.py b/yamllint/__init__.py index 1153277..35c2ee7 100644 --- a/yamllint/__init__.py +++ b/yamllint/__init__.py @@ -22,7 +22,7 @@ indentation, etc.""" APP_NAME = 'yamllint' -APP_VERSION = '1.26.1' +APP_VERSION = '1.26.2' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Vergé' From f47d5318cf4260646289e57722c8a243c32bd294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Sat, 21 Aug 2021 19:21:11 +0200 Subject: [PATCH 18/31] Restore setuptools requirement for Python < 3.8 This reverts commit 8f68248 "Remove runtime dep 'setuptools' for Python < 3.8". It looks like removing setuptools induces problems on some systems, see for example the linked discussion. Fixes https://github.com/adrienverge/yamllint/issues/380. --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 6dd9ce8..e405cae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -52,7 +52,7 @@ include_package_data = True install_requires = pathspec >= 0.5.3 pyyaml - setuptools; python_version < "3.8" + setuptools test_suite = tests From 058fef75598d1a9d9250487d91549abf379878e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Sat, 21 Aug 2021 19:26:15 +0200 Subject: [PATCH 19/31] yamllint version 1.26.3 --- CHANGELOG.rst | 5 +++++ yamllint/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fb0e804..876ccd3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ Changelog ========= +1.26.3 (2021-08-21) +------------------- + +- Restore runtime dependency ``setuptools`` for Python < 3.8 + 1.26.2 (2021-08-03) ------------------- diff --git a/yamllint/__init__.py b/yamllint/__init__.py index 35c2ee7..da49d9a 100644 --- a/yamllint/__init__.py +++ b/yamllint/__init__.py @@ -22,7 +22,7 @@ indentation, etc.""" APP_NAME = 'yamllint' -APP_VERSION = '1.26.2' +APP_VERSION = '1.26.3' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Vergé' From f2e2e0c3662fc90e976487568c221937003e5cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Wed, 20 Oct 2021 09:40:59 +0200 Subject: [PATCH 20/31] docs: Update CONTRIBUTING.rst Be more precise in contributing instructions. --- CONTRIBUTING.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f57ec5e..312c6d8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -42,5 +42,7 @@ Pull Request Process 6. Write a `good commit message `_. + If the pull request has multiple commits, each must be atomic (single + irreducible change that makes sense on its own). 7. Then, open a pull request. From 11e8d8ff378c72694fe832739eac8e6cfee045f2 Mon Sep 17 00:00:00 2001 From: Dmytro Bondar Date: Sat, 9 Oct 2021 14:26:28 +0300 Subject: [PATCH 21/31] Add support for Python 3.10, drop Python 3.5 - Add support for Python 3.10 released on 2021-10-04 - Drop support for Python 3.5 since it has reached end-of-life --- .github/workflows/ci.yaml | 2 +- setup.cfg | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 54fa582..59fd940 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -32,11 +32,11 @@ jobs: strategy: matrix: python-version: - - 3.5 - 3.6 - 3.7 - 3.8 - 3.9 + - 3.10 - nightly steps: - name: Checkout diff --git a/setup.cfg b/setup.cfg index e405cae..03ff8eb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,11 +27,11 @@ classifiers = Intended Audience :: Developers License :: OSI Approved :: GNU General Public License v3 (GPLv3) Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Topic :: Software Development Topic :: Software Development :: Debuggers Topic :: Software Development :: Quality Assurance @@ -46,7 +46,7 @@ project_urls = [options] packages = find: -python_requires = >=3.5 +python_requires = >=3.6 include_package_data = True install_requires = From 9e6dfacceb798efce9d3b0ddeab3e02e2997f5bd Mon Sep 17 00:00:00 2001 From: Dmytro Bondar Date: Wed, 27 Oct 2021 21:46:07 +0300 Subject: [PATCH 22/31] Fix github actions workflow - install correct python version - set `fail-fast: false` to run all jobs - remove hard-coded value for HOME directory --- .github/workflows/ci.yaml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 59fd940..26cea6c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,8 +17,6 @@ jobs: uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 - with: - python-version: 3.9 - run: python -m pip install flake8 flake8-import-order doc8 sphinx - run: python -m pip install . - run: flake8 . @@ -30,23 +28,23 @@ jobs: name: Tests runs-on: ubuntu-latest strategy: + fail-fast: false matrix: python-version: - - 3.6 - - 3.7 - - 3.8 - - 3.9 - - 3.10 - - nightly + - '3.6' + - '3.7' + - '3.8' + - '3.9' + - '3.10' steps: - name: Checkout uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.pyver }} + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: - python-version: ${{ matrix.pyver }} - - name: Fix GitHub Actions path - run: echo /home/runner/.local/bin >>$GITHUB_PATH + python-version: ${{ matrix.python-version }} + - name: Append GitHub Actions system path + run: echo "$HOME/.local/bin" >> $GITHUB_PATH - run: pip install coveralls - run: pip install . - run: coverage run --source=yamllint -m unittest discover From 7246a0c800bc60475eecbe394fc2d68c2a7b5ff9 Mon Sep 17 00:00:00 2001 From: Trevor Royer Date: Wed, 24 Nov 2021 07:38:26 -0600 Subject: [PATCH 23/31] cli: Separate --format=auto logic Moved the auto arg_format selection out of the main if block into a separate logic section to improve readability. No logic changes. --- yamllint/cli.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/yamllint/cli.py b/yamllint/cli.py index cb87350..3fbb8b8 100644 --- a/yamllint/cli.py +++ b/yamllint/cli.py @@ -103,18 +103,22 @@ def show_problems(problems, file, args_format, no_warn): max_level = 0 first = True + if args_format == 'auto': + if ('GITHUB_ACTIONS' in os.environ and + 'GITHUB_WORKFLOW' in os.environ): + args_format = 'github' + elif supports_color(): + args_format = 'colored' + for problem in problems: max_level = max(max_level, PROBLEM_LEVELS[problem.level]) if no_warn and (problem.level != 'error'): continue if args_format == 'parsable': print(Format.parsable(problem, file)) - elif args_format == 'github' or (args_format == 'auto' and - 'GITHUB_ACTIONS' in os.environ and - 'GITHUB_WORKFLOW' in os.environ): + elif args_format == 'github': print(Format.github(problem, file)) - elif args_format == 'colored' or \ - (args_format == 'auto' and supports_color()): + elif args_format == 'colored': if first: print('\033[4m%s\033[0m' % file) first = False From d0392b34ca15fb56061a4edc594ae2dd67b0cff9 Mon Sep 17 00:00:00 2001 From: Trevor Royer Date: Wed, 1 Dec 2021 01:52:59 -0600 Subject: [PATCH 24/31] github format: Update output to utilize groups Resolves #421 Update the github formatting to utilize groups in the output and provide the line/column number for the error in the output log. --- tests/test_cli.py | 16 ++++++++++------ yamllint/cli.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 79c4320..95e3fc7 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -553,11 +553,13 @@ class CommandLineTestCase(unittest.TestCase): with RunContext(self) as ctx: cli.run((path, '--format', 'github')) expected_out = ( - '::error file=%s,line=2,col=4::[trailing-spaces] trailing' + '::group::%s\n' + '::error file=%s,line=2,col=4::2:4 [trailing-spaces] trailing' ' spaces\n' - '::error file=%s,line=3,col=4::[new-line-at-end-of-file] no' + '::error file=%s,line=3,col=4::3:4 [new-line-at-end-of-file] no' ' new line character at the end of file\n' - % (path, path)) + '::endgroup::\n\n' + % (path, path, path)) self.assertEqual( (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) @@ -571,11 +573,13 @@ class CommandLineTestCase(unittest.TestCase): os.environ['GITHUB_WORKFLOW'] = 'something' cli.run((path, )) expected_out = ( - '::error file=%s,line=2,col=4::[trailing-spaces] trailing' + '::group::%s\n' + '::error file=%s,line=2,col=4::2:4 [trailing-spaces] trailing' ' spaces\n' - '::error file=%s,line=3,col=4::[new-line-at-end-of-file] no' + '::error file=%s,line=3,col=4::3:4 [new-line-at-end-of-file] no' ' new line character at the end of file\n' - % (path, path)) + '::endgroup::\n\n' + % (path, path, path)) self.assertEqual( (ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, '')) diff --git a/yamllint/cli.py b/yamllint/cli.py index 3fbb8b8..4d94342 100644 --- a/yamllint/cli.py +++ b/yamllint/cli.py @@ -93,6 +93,10 @@ class Format(object): line += 'line=' + format(problem.line) + ',' line += 'col=' + format(problem.column) line += '::' + line += format(problem.line) + line += ':' + line += format(problem.column) + line += ' ' if problem.rule: line += '[' + problem.rule + '] ' line += problem.desc @@ -117,6 +121,9 @@ def show_problems(problems, file, args_format, no_warn): if args_format == 'parsable': print(Format.parsable(problem, file)) elif args_format == 'github': + if first: + print('::group::%s' % file) + first = False print(Format.github(problem, file)) elif args_format == 'colored': if first: @@ -129,6 +136,9 @@ def show_problems(problems, file, args_format, no_warn): first = False print(Format.standard(problem, file)) + if not first and args_format == 'github': + print('::endgroup::') + if not first and args_format != 'parsable': print('') From bb567ba3953561436619bb4ca9466a64ecea236f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Alet?= <85658105+tamere-allo-peter@users.noreply.github.com> Date: Mon, 20 Dec 2021 08:02:56 +1100 Subject: [PATCH 25/31] comments: Allow whitespace after the shebang marker Basically, any character is now allowed after the shebang marker. Closes #428. Whitespace after the #! marker on shebang lines is authorized and optional, as explained on Wikipedia's entry for shebang line as can be seen from the extracts below : > White space after #! is optional and > It has been claimed[20] that some old versions of Unix expect the > normal shebang to be followed by a space and a slash (#! /), but this > appears to be untrue;[21] rather, blanks after the shebang have > traditionally been allowed, and sometimes documented with a space --- tests/rules/test_comments.py | 5 ++--- yamllint/rules/comments.py | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/rules/test_comments.py b/tests/rules/test_comments.py index 2c3f399..7a7bc8a 100644 --- a/tests/rules/test_comments.py +++ b/tests/rules/test_comments.py @@ -97,7 +97,7 @@ class CommentsTestCase(RuleTestCase): '#!/bin/env my-interpreter\n' '', conf, problem1=(1, 2), problem2=(3, 2), problem3=(4, 2)) - self.check('#! not a shebang\n', + self.check('#! is a valid shebang too\n', conf, problem1=(1, 2)) self.check('key: #!/not/a/shebang\n', conf, problem1=(1, 8)) @@ -117,8 +117,7 @@ class CommentsTestCase(RuleTestCase): '#comment\n' '#!/bin/env my-interpreter\n', conf, problem2=(3, 2), problem3=(4, 2)) - self.check('#! not a shebang\n', - conf, problem1=(1, 2)) + self.check('#! is a valid shebang too\n', conf) self.check('key: #!/not/a/shebang\n', conf, problem1=(1, 8)) diff --git a/yamllint/rules/comments.py b/yamllint/rules/comments.py index 70ae250..02eddad 100644 --- a/yamllint/rules/comments.py +++ b/yamllint/rules/comments.py @@ -74,8 +74,6 @@ Use this rule to control the position and formatting of comments. """ -import re - from yamllint.linter import LintProblem @@ -105,7 +103,7 @@ def check(conf, comment): if (conf['ignore-shebangs'] and comment.line_no == 1 and comment.column_no == 1 and - re.match(r'^!\S', comment.buffer[text_start:])): + comment.buffer[text_start] == '!'): return # We can test for both \r and \r\n just by checking first char # \r itself is a valid newline on some older OS. From 4f1bbc33dcb550b27a77e10c9831b9ff732bc5a8 Mon Sep 17 00:00:00 2001 From: Madison Swain-Bowden Date: Fri, 24 Dec 2021 00:34:15 -0800 Subject: [PATCH 26/31] docs: Fix link syntax on integration.rst --- docs/integration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integration.rst b/docs/integration.rst index 75a1f0c..29131ea 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -22,7 +22,7 @@ Integration with GitHub Actions ------------------------------- yamllint auto-detects when it's running inside of `GitHub -Actions` and automatically uses the suited +Actions `_ and automatically uses the suited output format to decorate code with linting errors automatically. You can also force the GitHub Actions output with ``yamllint --format github``. From c34c962691742e3e6a8a397e35aa1c4ae4a22f44 Mon Sep 17 00:00:00 2001 From: Andrew Imeson Date: Fri, 18 Mar 2022 18:45:01 -0400 Subject: [PATCH 27/31] Remove the repeated word "automatically" in GHA doc --- docs/integration.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/integration.rst b/docs/integration.rst index 29131ea..7b349ff 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -23,8 +23,8 @@ Integration with GitHub Actions yamllint auto-detects when it's running inside of `GitHub Actions `_ and automatically uses the suited -output format to decorate code with linting errors automatically. You can also -force the GitHub Actions output with ``yamllint --format github``. +output format to decorate code with linting errors. You can also force the +GitHub Actions output with ``yamllint --format github``. An example workflow using GitHub Actions: From 8a320aaf2ced24c832634c12e03d413879635836 Mon Sep 17 00:00:00 2001 From: Andrew Imeson Date: Sat, 19 Mar 2022 10:52:02 -0400 Subject: [PATCH 28/31] Make man page show up in apropos Set the 'description' attribute so that Sphinx builds the manpage with the 'NAME' section. This is necessary for `apropos` to be able to find yamllint Fixes part of #76 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index c651cf9..f5d317e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,7 @@ htmlhelp_basename = 'yamllintdoc' # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'yamllint', '', [u'Adrien Vergé'], 1) + ('index', 'yamllint', 'Linter for YAML files', [u'Adrien Vergé'], 1) ] # -- Build with sphinx automodule without needing to install third-party libs From 7974d518cd79446c00da293c6390a3b3d4c31c99 Mon Sep 17 00:00:00 2001 From: Andrew Imeson Date: Sat, 19 Mar 2022 11:08:15 -0400 Subject: [PATCH 29/31] Fix grammar in key_ordering docs to make Lintian happy Fixes part of #76 --- yamllint/rules/key_ordering.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yamllint/rules/key_ordering.py b/yamllint/rules/key_ordering.py index eca38ab..c5cb45a 100644 --- a/yamllint/rules/key_ordering.py +++ b/yamllint/rules/key_ordering.py @@ -18,8 +18,8 @@ Use this rule to enforce alphabetical ordering of keys in mappings. The sorting order uses the Unicode code point number as a default. As a result, the ordering is case-sensitive and not accent-friendly (see examples below). -This can be changed by setting the global ``locale`` option. This allows to -sort case and accents properly. +This can be changed by setting the global ``locale`` option. This allows one +to sort case and accents properly. .. rubric:: Examples From f58448cb21a5f75d5cb29aa2f93c8250f949554c Mon Sep 17 00:00:00 2001 From: Andrew Imeson Date: Sat, 19 Mar 2022 11:16:30 -0400 Subject: [PATCH 30/31] Fix spelling of "across" in test output --- tests/rules/test_line_length.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/rules/test_line_length.py b/tests/rules/test_line_length.py index 245fe4d..22a439e 100644 --- a/tests/rules/test_line_length.py +++ b/tests/rules/test_line_length.py @@ -181,13 +181,13 @@ class LineLengthTestCase(RuleTestCase): conf = 'line-length: {max: 53}' self.check('---\n' '# This is a test to check if “line-length” works nice\n' - 'with: “unicode characters” that span accross bytes! ↺\n', + 'with: “unicode characters” that span across bytes! ↺\n', conf) - conf = 'line-length: {max: 52}' + conf = 'line-length: {max: 51}' self.check('---\n' '# This is a test to check if “line-length” works nice\n' - 'with: “unicode characters” that span accross bytes! ↺\n', - conf, problem1=(2, 53), problem2=(3, 53)) + 'with: “unicode characters” that span across bytes! ↺\n', + conf, problem1=(2, 52), problem2=(3, 52)) def test_with_dos_newlines(self): conf = ('line-length: {max: 10}\n' From 2f423117c1f1e49d115169cd4a5e1722d68fabfe Mon Sep 17 00:00:00 2001 From: Andrew Imeson Date: Thu, 24 Mar 2022 05:23:39 -0400 Subject: [PATCH 31/31] docs: Attempt to clarify configuration file location Closes #96, Closes #212 --- docs/configuration.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index ba455c9..3c1e0c8 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -14,11 +14,11 @@ To use a custom configuration file, use the ``-c`` option: If ``-c`` is not provided, yamllint will look for a configuration file in the following locations (by order of preference): -- ``.yamllint``, ``.yamllint.yaml`` or ``.yamllint.yml`` in the current working - directory -- the file referenced by ``$YAMLLINT_CONFIG_FILE``, if set -- ``$XDG_CONFIG_HOME/yamllint/config`` -- ``~/.config/yamllint/config`` +- a file named ``.yamllint``, ``.yamllint.yaml``, or ``.yamllint.yml`` in the + current working directory +- a filename referenced by ``$YAMLLINT_CONFIG_FILE``, if set +- a file named ``$XDG_CONFIG_HOME/yamllint/config`` or + ``~/.config/yamllint/config``, if present Finally if no config file is found, the default configuration is applied.