Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-yamllint for openSUSE:Factory checked in at 2022-10-14 15:41:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-yamllint (Old) and /work/SRC/openSUSE:Factory/.python-yamllint.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-yamllint" Fri Oct 14 15:41:03 2022 rev:14 rq:1010327 version:1.28.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-yamllint/python-yamllint.changes 2022-07-19 17:19:38.264388703 +0200 +++ /work/SRC/openSUSE:Factory/.python-yamllint.new.2275/python-yamllint.changes 2022-10-14 15:41:38.907829146 +0200 @@ -1,0 +2,14 @@ +Wed Oct 12 18:25:20 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to version 1.28.0 + * Better compress PNG image in documentation + * Remove __future__ imports specific to Python 2 + * Remove inheritance from object specific to Python 2 + * Simplify GitHub Actions example in documentation + * Update ALE vim plugin link in documentation + * Update license to latest version of GPLv3 + * Pre-compile disable/enable rules regexes + * Rule quoted-strings: add allow-quoted-quotes option + * Add option ignore-from-file in config + +------------------------------------------------------------------- Old: ---- yamllint-1.27.1.tar.gz New: ---- yamllint-1.28.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-yamllint.spec ++++++ --- /var/tmp/diff_new_pack.uI4pTy/_old 2022-10-14 15:41:39.423830008 +0200 +++ /var/tmp/diff_new_pack.uI4pTy/_new 2022-10-14 15:41:39.443830041 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python3-%{**}} %define skip_python2 1 Name: python-yamllint -Version: 1.27.1 +Version: 1.28.0 Release: 0 Summary: A linter for YAML files License: GPL-3.0-only ++++++ yamllint-1.27.1.tar.gz -> yamllint-1.28.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/LICENSE new/yamllint-1.28.0/LICENSE --- old/yamllint-1.27.1/LICENSE 2016-01-13 22:08:00.000000000 +0100 +++ new/yamllint-1.28.0/LICENSE 2022-09-12 14:32:16.000000000 +0200 @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -645,7 +645,7 @@ GNU General Public License for more details. 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 <https://www.gnu.org/licenses/>. Also add information on how to contact you by electronic and paper mail. @@ -664,11 +664,11 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. +<https://www.gnu.org/licenses/>. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/PKG-INFO new/yamllint-1.28.0/PKG-INFO --- old/yamllint-1.27.1/PKG-INFO 2022-07-08 18:07:24.878478500 +0200 +++ new/yamllint-1.28.0/PKG-INFO 2022-09-12 14:38:24.848200600 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: yamllint -Version: 1.27.1 +Version: 1.28.0 Summary: A linter for YAML files. Home-page: https://github.com/adrienverge/yamllint Author: Adrien Verg?? diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/docs/configuration.rst new/yamllint-1.28.0/docs/configuration.rst --- old/yamllint-1.27.1/docs/configuration.rst 2022-06-10 11:20:06.000000000 +0200 +++ new/yamllint-1.28.0/docs/configuration.rst 2022-09-12 14:32:16.000000000 +0200 @@ -190,6 +190,20 @@ *.ignore-trailing-spaces.yaml ascii-art/* +You can also use the ``.gitignore`` file (or any list of files) through: + +.. code-block:: yaml + + ignore-from-file: .gitignore + +or: + +.. code-block:: yaml + + ignore-from-file: [.gitignore, .yamlignore] + +.. note:: However, this is mutually exclusive with the ``ignore`` key. + Setting the locale ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/docs/integration.rst new/yamllint-1.28.0/docs/integration.rst --- old/yamllint-1.27.1/docs/integration.rst 2022-06-10 11:20:06.000000000 +0200 +++ new/yamllint-1.28.0/docs/integration.rst 2022-09-12 14:32:16.000000000 +0200 @@ -22,29 +22,22 @@ ------------------------------- yamllint auto-detects when it's running inside of `GitHub -Actions <https://github.com/features/actions>`_ and automatically uses the suited -output format to decorate code with linting errors. You can also force the -GitHub Actions output with ``yamllint --format github``. +Actions <https://github.com/features/actions>`_ and automatically uses the +suited 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: +An minimal example workflow using GitHub Actions: .. code:: yaml --- - name: yamllint test - - on: push + on: push # yamllint disable-line rule:truthy jobs: - test: + lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: 3.8 + - uses: actions/checkout@v3 - name: Install yamllint run: pip install yamllint Binary files old/yamllint-1.27.1/docs/screenshot.png and new/yamllint-1.28.0/docs/screenshot.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/docs/text_editors.rst new/yamllint-1.28.0/docs/text_editors.rst --- old/yamllint-1.27.1/docs/text_editors.rst 2022-07-08 16:20:11.000000000 +0200 +++ new/yamllint-1.28.0/docs/text_editors.rst 2022-09-12 14:32:16.000000000 +0200 @@ -9,7 +9,7 @@ Vim --- -Assuming that the `ALE <https://github.com/w0rp/ale>`_ plugin is +Assuming that the `ALE <https://github.com/dense-analysis/ale>`_ plugin is installed, yamllint is supported by default. It is automatically enabled when editing YAML files. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/tests/rules/test_quoted_strings.py new/yamllint-1.28.0/tests/rules/test_quoted_strings.py --- old/yamllint-1.27.1/tests/rules/test_quoted_strings.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/tests/rules/test_quoted_strings.py 2022-09-12 14:32:16.000000000 +0200 @@ -453,3 +453,106 @@ '- "0o800"\n', conf, problem1=(9, 3), problem2=(10, 3)) + + def test_allow_quoted_quotes(self): + conf = ('quoted-strings: {quote-type: single,\n' + ' required: false,\n' + ' allow-quoted-quotes: false}\n') + self.check('---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', # fails + conf, problem1=(2, 7), problem2=(3, 7)) + + conf = ('quoted-strings: {quote-type: single,\n' + ' required: false,\n' + ' allow-quoted-quotes: true}\n') + self.check('---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', + conf, problem1=(2, 7)) + + conf = ('quoted-strings: {quote-type: single,\n' + ' required: true,\n' + ' allow-quoted-quotes: false}\n') + self.check('---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', # fails + conf, problem1=(2, 7), problem2=(3, 7)) + + conf = ('quoted-strings: {quote-type: single,\n' + ' required: true,\n' + ' allow-quoted-quotes: true}\n') + self.check('---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', + conf, problem1=(2, 7)) + + conf = ('quoted-strings: {quote-type: single,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: false}\n') + self.check('---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', # fails + conf, problem1=(2, 7), problem2=(3, 7)) + + conf = ('quoted-strings: {quote-type: single,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: true}\n') + self.check('---\n' + 'foo1: "[barbaz]"\n' # fails + 'foo2: "[bar\'baz]"\n', + conf, problem1=(2, 7)) + + conf = ('quoted-strings: {quote-type: double,\n' + ' required: false,\n' + ' allow-quoted-quotes: false}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", # fails + conf, problem1=(2, 7), problem2=(3, 7)) + + conf = ('quoted-strings: {quote-type: double,\n' + ' required: false,\n' + ' allow-quoted-quotes: true}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", + conf, problem1=(2, 7)) + + conf = ('quoted-strings: {quote-type: double,\n' + ' required: true,\n' + ' allow-quoted-quotes: false}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", # fails + conf, problem1=(2, 7), problem2=(3, 7)) + + conf = ('quoted-strings: {quote-type: double,\n' + ' required: true,\n' + ' allow-quoted-quotes: true}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", + conf, problem1=(2, 7)) + + conf = ('quoted-strings: {quote-type: double,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: false}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", # fails + conf, problem1=(2, 7), problem2=(3, 7)) + + conf = ('quoted-strings: {quote-type: double,\n' + ' required: only-when-needed,\n' + ' allow-quoted-quotes: true}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" # fails + "foo2: '[bar\"baz]'\n", + conf, problem1=(2, 7)) + + conf = ('quoted-strings: {quote-type: any}\n') + self.check("---\n" + "foo1: '[barbaz]'\n" + "foo2: '[bar\"baz]'\n", + conf) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/tests/test_cli.py new/yamllint-1.28.0/tests/test_cli.py --- old/yamllint-1.27.1/tests/test_cli.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/tests/test_cli.py 2022-09-12 14:32:16.000000000 +0200 @@ -29,7 +29,7 @@ from yamllint import config -class RunContext(object): +class RunContext: """Context manager for ``cli.run()`` to capture exit code and streams.""" def __init__(self, case): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/tests/test_config.py new/yamllint-1.28.0/tests/test_config.py --- old/yamllint-1.27.1/tests/test_config.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/tests/test_config.py 2022-09-12 14:32:16.000000000 +0200 @@ -22,6 +22,7 @@ from tests.common import build_temp_workspace +from yamllint.config import YamlLintConfigError from yamllint import cli from yamllint import config @@ -121,7 +122,7 @@ self.assertEqual(c.rules['hyphens'], False) def test_validate_rule_conf(self): - class Rule(object): + class Rule: ID = 'fake' self.assertFalse(config.validate_rule_conf(Rule, False)) @@ -429,10 +430,10 @@ self.assertEqual(new.rules['empty-lines']['max-end'], 0) -class IgnorePathConfigTestCase(unittest.TestCase): +class IgnoreConfigTestCase(unittest.TestCase): @classmethod def setUpClass(cls): - super(IgnorePathConfigTestCase, cls).setUpClass() + super().setUpClass() bad_yaml = ('---\n' '- key: val1\n' @@ -452,22 +453,6 @@ 's/s/ign-trail/file.yaml': bad_yaml, 's/s/ign-trail/s/s/file.yaml': bad_yaml, 's/s/ign-trail/s/s/file2.lint-me-anyway.yaml': bad_yaml, - - '.yamllint': 'ignore: |\n' - ' *.dont-lint-me.yaml\n' - ' /bin/\n' - ' !/bin/*.lint-me-anyway.yaml\n' - '\n' - 'extends: default\n' - '\n' - 'rules:\n' - ' key-duplicates:\n' - ' ignore: |\n' - ' /ign-dup\n' - ' trailing-spaces:\n' - ' ignore: |\n' - ' ign-trail\n' - ' !*.lint-me-anyway.yaml\n', }) cls.backup_wd = os.getcwd() @@ -475,13 +460,201 @@ @classmethod def tearDownClass(cls): - super(IgnorePathConfigTestCase, cls).tearDownClass() + super().tearDownClass() os.chdir(cls.backup_wd) shutil.rmtree(cls.wd) - def test_run_with_ignored_path(self): + def test_mutually_exclusive_ignore_keys(self): + self.assertRaises( + YamlLintConfigError, + config.YamlLintConfig, 'extends: default\n' + 'ignore-from-file: .gitignore\n' + 'ignore: |\n' + ' *.dont-lint-me.yaml\n' + ' /bin/\n') + + def test_ignore_from_file_not_exist(self): + self.assertRaises( + FileNotFoundError, + config.YamlLintConfig, 'extends: default\n' + 'ignore-from-file: not_found_file\n') + + def test_ignore_from_file_incorrect_type(self): + self.assertRaises( + YamlLintConfigError, + config.YamlLintConfig, 'extends: default\n' + 'ignore-from-file: 0\n') + self.assertRaises( + YamlLintConfigError, + config.YamlLintConfig, 'extends: default\n' + 'ignore-from-file: [0]\n') + + def test_no_ignore(self): + sys.stdout = StringIO() + with self.assertRaises(SystemExit): + cli.run(('-f', 'parsable', '.')) + + out = sys.stdout.getvalue() + out = '\n'.join(sorted(out.splitlines())) + + keydup = '[error] duplication of key "key" in mapping (key-duplicates)' + trailing = '[error] trailing spaces (trailing-spaces)' + hyphen = '[error] too many spaces after hyphen (hyphens)' + + self.assertEqual(out, '\n'.join(( + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './bin/file.yaml:3:3: ' + keydup, + './bin/file.yaml:4:17: ' + trailing, + './bin/file.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './file.dont-lint-me.yaml:3:3: ' + keydup, + './file.dont-lint-me.yaml:4:17: ' + trailing, + './file.dont-lint-me.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:3:3: ' + keydup, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:4:17: ' + trailing, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ))) + + def test_run_with_ignore(self): + with open(os.path.join(self.wd, '.yamllint'), 'w') as f: + f.write('extends: default\n' + 'ignore: |\n' + ' *.dont-lint-me.yaml\n' + ' /bin/\n' + ' !/bin/*.lint-me-anyway.yaml\n' + 'rules:\n' + ' key-duplicates:\n' + ' ignore: |\n' + ' /ign-dup\n' + ' trailing-spaces:\n' + ' ignore: |\n' + ' ign-trail\n' + ' !*.lint-me-anyway.yaml\n') + + sys.stdout = StringIO() + with self.assertRaises(SystemExit): + cli.run(('-f', 'parsable', '.')) + + out = sys.stdout.getvalue() + out = '\n'.join(sorted(out.splitlines())) + + docstart = '[warning] missing document start "---" (document-start)' + keydup = '[error] duplication of key "key" in mapping (key-duplicates)' + trailing = '[error] trailing spaces (trailing-spaces)' + hyphen = '[error] too many spaces after hyphen (hyphens)' + + self.assertEqual(out, '\n'.join(( + './.yamllint:1:1: ' + docstart, + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ))) + + def test_run_with_ignore_from_file(self): + with open(os.path.join(self.wd, '.yamllint'), 'w') as f: + f.write('extends: default\n' + 'ignore-from-file: .gitignore\n') + with open(os.path.join(self.wd, '.gitignore'), 'w') as f: + f.write('*.dont-lint-me.yaml\n' + '/bin/\n' + '!/bin/*.lint-me-anyway.yaml\n') + + sys.stdout = StringIO() + with self.assertRaises(SystemExit): + cli.run(('-f', 'parsable', '.')) + + out = sys.stdout.getvalue() + out = '\n'.join(sorted(out.splitlines())) + + docstart = '[warning] missing document start "---" (document-start)' + keydup = '[error] duplication of key "key" in mapping (key-duplicates)' + trailing = '[error] trailing spaces (trailing-spaces)' + hyphen = '[error] too many spaces after hyphen (hyphens)' + + self.assertEqual(out, '\n'.join(( + './.yamllint:1:1: ' + docstart, + './bin/file.lint-me-anyway.yaml:3:3: ' + keydup, + './bin/file.lint-me-anyway.yaml:4:17: ' + trailing, + './bin/file.lint-me-anyway.yaml:5:5: ' + hyphen, + './file-at-root.yaml:3:3: ' + keydup, + './file-at-root.yaml:4:17: ' + trailing, + './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:3:3: ' + keydup, + './ign-dup/file.yaml:4:17: ' + trailing, + './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:4:17: ' + trailing, + './ign-trail/file.yaml:5:5: ' + hyphen, + './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, + './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, + './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, + './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:5:5: ' + hyphen, + ))) + + def test_run_with_ignored_from_file(self): + with open(os.path.join(self.wd, '.yamllint'), 'w') as f: + f.write('ignore-from-file: [.gitignore, .yamlignore]\n' + 'extends: default\n') + with open(os.path.join(self.wd, '.gitignore'), 'w') as f: + f.write('*.dont-lint-me.yaml\n' + '/bin/\n') + with open(os.path.join(self.wd, '.yamlignore'), 'w') as f: + f.write('!/bin/*.lint-me-anyway.yaml\n') + sys.stdout = StringIO() with self.assertRaises(SystemExit): cli.run(('-f', 'parsable', '.')) @@ -502,18 +675,23 @@ './file-at-root.yaml:3:3: ' + keydup, './file-at-root.yaml:4:17: ' + trailing, './file-at-root.yaml:5:5: ' + hyphen, + './ign-dup/file.yaml:3:3: ' + keydup, './ign-dup/file.yaml:4:17: ' + trailing, './ign-dup/file.yaml:5:5: ' + hyphen, + './ign-dup/sub/dir/file.yaml:3:3: ' + keydup, './ign-dup/sub/dir/file.yaml:4:17: ' + trailing, './ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, './ign-trail/file.yaml:3:3: ' + keydup, + './ign-trail/file.yaml:4:17: ' + trailing, './ign-trail/file.yaml:5:5: ' + hyphen, './include/ign-dup/sub/dir/file.yaml:3:3: ' + keydup, './include/ign-dup/sub/dir/file.yaml:4:17: ' + trailing, './include/ign-dup/sub/dir/file.yaml:5:5: ' + hyphen, './s/s/ign-trail/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/file.yaml:4:17: ' + trailing, './s/s/ign-trail/file.yaml:5:5: ' + hyphen, './s/s/ign-trail/s/s/file.yaml:3:3: ' + keydup, + './s/s/ign-trail/s/s/file.yaml:4:17: ' + trailing, './s/s/ign-trail/s/s/file.yaml:5:5: ' + hyphen, './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:3:3: ' + keydup, './s/s/ign-trail/s/s/file2.lint-me-anyway.yaml:4:17: ' + trailing, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/__init__.py new/yamllint-1.28.0/yamllint/__init__.py --- old/yamllint-1.27.1/yamllint/__init__.py 2022-07-08 18:05:47.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/__init__.py 2022-09-12 14:33:37.000000000 +0200 @@ -21,7 +21,7 @@ APP_NAME = 'yamllint' -APP_VERSION = '1.27.1' +APP_VERSION = '1.28.0' APP_DESCRIPTION = __doc__ __author__ = u'Adrien Verg??' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/cli.py new/yamllint-1.28.0/yamllint/cli.py --- old/yamllint-1.27.1/yamllint/cli.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/cli.py 2022-09-12 14:32:16.000000000 +0200 @@ -13,8 +13,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from __future__ import print_function - import argparse import io import locale diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/config.py new/yamllint-1.28.0/yamllint/config.py --- old/yamllint-1.27.1/yamllint/config.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/config.py 2022-09-12 14:32:16.000000000 +0200 @@ -13,6 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +import fileinput import os.path import pathspec @@ -25,7 +26,7 @@ pass -class YamlLintConfig(object): +class YamlLintConfig: def __init__(self, content=None, file=None): assert (content is None) ^ (file is None) @@ -96,7 +97,21 @@ except Exception as e: raise YamlLintConfigError('invalid config: %s' % e) - if 'ignore' in conf: + if 'ignore' in conf and 'ignore-from-file' in conf: + raise YamlLintConfigError( + 'invalid config: ignore and ignore-from-file keys cannot be ' + 'used together') + elif 'ignore-from-file' in conf: + if isinstance(conf['ignore-from-file'], str): + conf['ignore-from-file'] = [conf['ignore-from-file']] + if not (isinstance(conf['ignore-from-file'], list) and all( + isinstance(ln, str) for ln in conf['ignore-from-file'])): + raise YamlLintConfigError( + 'invalid config: ignore-from-file should contain ' + 'filename(s), either as a list or string') + with fileinput.input(conf['ignore-from-file']) as f: + self.ignore = pathspec.PathSpec.from_lines('gitwildmatch', f) + elif 'ignore' in conf: if not isinstance(conf['ignore'], str): raise YamlLintConfigError( 'invalid config: ignore should contain file patterns') @@ -150,7 +165,7 @@ options = getattr(rule, 'CONF', {}) options_default = getattr(rule, 'DEFAULT', {}) for optkey in conf: - if optkey in ('ignore', 'level'): + if optkey in ('ignore', 'ignore-from-file', 'level'): continue if optkey not in options: raise YamlLintConfigError( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/linter.py new/yamllint-1.28.0/yamllint/linter.py --- old/yamllint-1.27.1/yamllint/linter.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/linter.py 2022-09-12 14:32:16.000000000 +0200 @@ -29,6 +29,9 @@ 'error': 2, } +DISABLE_RULE_PATTERN = re.compile(r'^# yamllint disable( rule:\S+)*\s*$') +ENABLE_RULE_PATTERN = re.compile(r'^# yamllint enable( rule:\S+)*\s*$') + class LintProblem(object): """Represents a linting problem found by yamllint.""" @@ -82,7 +85,7 @@ def process_comment(self, comment): comment = str(comment) - if re.match(r'^# yamllint disable( rule:\S+)*\s*$', comment): + if DISABLE_RULE_PATTERN.match(comment): items = comment[18:].rstrip().split(' ') rules = [item[5:] for item in items][1:] if len(rules) == 0: @@ -92,7 +95,7 @@ if id in self.all_rules: self.rules.add(id) - elif re.match(r'^# yamllint enable( rule:\S+)*\s*$', comment): + elif ENABLE_RULE_PATTERN.match(comment): items = comment[17:].rstrip().split(' ') rules = [item[5:] for item in items][1:] if len(rules) == 0: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/parser.py new/yamllint-1.28.0/yamllint/parser.py --- old/yamllint-1.27.1/yamllint/parser.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/parser.py 2022-09-12 14:32:16.000000000 +0200 @@ -16,7 +16,7 @@ import yaml -class Line(object): +class Line: def __init__(self, line_no, buffer, start, end): self.line_no = line_no self.start = start @@ -28,7 +28,7 @@ return self.buffer[self.start:self.end] -class Token(object): +class Token: def __init__(self, line_no, curr, prev, next, nextnext): self.line_no = line_no self.curr = curr @@ -37,7 +37,7 @@ self.nextnext = nextnext -class Comment(object): +class Comment: def __init__(self, line_no, column_no, buffer, pointer, token_before=None, token_after=None, comment_before=None): self.line_no = line_no diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/rules/indentation.py new/yamllint-1.28.0/yamllint/rules/indentation.py --- old/yamllint-1.27.1/yamllint/rules/indentation.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/rules/indentation.py 2022-09-12 14:32:16.000000000 +0200 @@ -218,7 +218,7 @@ labels = ('ROOT', 'B_MAP', 'F_MAP', 'B_SEQ', 'F_SEQ', 'B_ENT', 'KEY', 'VAL') -class Parent(object): +class Parent: def __init__(self, type, indent, line_indent=None): self.type = type self.indent = indent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/rules/key_duplicates.py new/yamllint-1.28.0/yamllint/rules/key_duplicates.py --- old/yamllint-1.27.1/yamllint/rules/key_duplicates.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/rules/key_duplicates.py 2022-09-12 14:32:16.000000000 +0200 @@ -64,7 +64,7 @@ MAP, SEQ = range(2) -class Parent(object): +class Parent: def __init__(self, type): self.type = type self.keys = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/rules/octal_values.py new/yamllint-1.28.0/yamllint/rules/octal_values.py --- old/yamllint-1.27.1/yamllint/rules/octal_values.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/rules/octal_values.py 2022-09-12 14:32:16.000000000 +0200 @@ -96,7 +96,7 @@ if not token.style: val = token.value if (val.isdigit() and len(val) > 1 and val[0] == '0' and - IS_OCTAL_NUMBER_PATTERN.match(val[1:]) is not None): + IS_OCTAL_NUMBER_PATTERN.match(val[1:])): yield LintProblem( token.start_mark.line + 1, token.end_mark.column + 1, 'forbidden implicit octal value "%s"' % @@ -107,7 +107,7 @@ if not token.style: val = token.value if (len(val) > 2 and val[:2] == '0o' and - IS_OCTAL_NUMBER_PATTERN.match(val[2:]) is not None): + IS_OCTAL_NUMBER_PATTERN.match(val[2:])): yield LintProblem( token.start_mark.line + 1, token.end_mark.column + 1, 'forbidden explicit octal value "%s"' % diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint/rules/quoted_strings.py new/yamllint-1.28.0/yamllint/rules/quoted_strings.py --- old/yamllint-1.27.1/yamllint/rules/quoted_strings.py 2022-06-20 18:34:21.000000000 +0200 +++ new/yamllint-1.28.0/yamllint/rules/quoted_strings.py 2022-09-12 14:32:16.000000000 +0200 @@ -30,6 +30,8 @@ ``required: false`` and ``required: only-when-needed``. * ``extra-allowed`` is a list of PCRE regexes to allow quoted string values, even if ``required: only-when-needed`` is set. +* ``allow-quoted-quotes`` allows (``true``) using disallowed quotes for strings + with allowed quotes inside. Default ``false``. **Note**: Multi-line strings (with ``|`` or ``>``) will not be checked. @@ -43,6 +45,7 @@ required: true extra-required: [] extra-allowed: [] + allow-quoted-quotes: false .. rubric:: Examples @@ -112,6 +115,26 @@ - "localhost" - this is a string that needs to be QUOTED + +#. With ``quoted-strings: {quote-type: double, allow-quoted-quotes: false}`` + + the following code snippet would **PASS**: + :: + + foo: "bar\\"baz" + + the following code snippet would **FAIL**: + :: + + foo: 'bar"baz' + +#. With ``quoted-strings: {quote-type: double, allow-quoted-quotes: true}`` + + the following code snippet would **PASS**: + :: + + foo: 'bar"baz' + """ import re @@ -125,11 +148,13 @@ CONF = {'quote-type': ('any', 'single', 'double'), 'required': (True, False, 'only-when-needed'), 'extra-required': [str], - 'extra-allowed': [str]} + 'extra-allowed': [str], + 'allow-quoted-quotes': bool} DEFAULT = {'quote-type': 'any', 'required': True, 'extra-required': [], - 'extra-allowed': []} + 'extra-allowed': [], + 'allow-quoted-quotes': False} def VALIDATE(conf): @@ -177,6 +202,12 @@ return True +def _has_quoted_quotes(token): + return ((not token.plain) and + ((token.style == "'" and '"' in token.value) or + (token.style == '"' and "'" in token.value))) + + def check(conf, token, prev, next, nextnext, context): if not (isinstance(token, yaml.tokens.ScalarToken) and isinstance(prev, (yaml.BlockEntryToken, yaml.FlowEntryToken, @@ -206,13 +237,18 @@ if conf['required'] is True: # 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) or + (conf['allow-quoted-quotes'] and _has_quoted_quotes(token)))): msg = "string value is not quoted with %s quotes" % quote_type elif conf['required'] is False: # 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) and + not (conf['allow-quoted-quotes'] and + _has_quoted_quotes(token))): msg = "string value is not quoted with %s quotes" % quote_type elif not token.style: @@ -235,7 +271,9 @@ quote_type) # 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) and + not (conf['allow-quoted-quotes'] and _has_quoted_quotes(token))): msg = "string value is not quoted with %s quotes" % quote_type elif not token.style: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.27.1/yamllint.egg-info/PKG-INFO new/yamllint-1.28.0/yamllint.egg-info/PKG-INFO --- old/yamllint-1.27.1/yamllint.egg-info/PKG-INFO 2022-07-08 18:07:24.000000000 +0200 +++ new/yamllint-1.28.0/yamllint.egg-info/PKG-INFO 2022-09-12 14:38:24.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: yamllint -Version: 1.27.1 +Version: 1.28.0 Summary: A linter for YAML files. Home-page: https://github.com/adrienverge/yamllint Author: Adrien Verg??