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??

Reply via email to