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 2023-06-01 17:21:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-yamllint (Old) and /work/SRC/openSUSE:Factory/.python-yamllint.new.2531 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-yamllint" Thu Jun 1 17:21:13 2023 rev:17 rq:1090262 version:1.32.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-yamllint/python-yamllint.changes 2023-05-18 15:19:32.153931614 +0200 +++ /work/SRC/openSUSE:Factory/.python-yamllint.new.2531/python-yamllint.changes 2023-06-01 17:21:14.550772887 +0200 @@ -1,0 +2,7 @@ +Thu Jun 1 05:40:16 UTC 2023 - Johannes Kastl <ka...@b1-systems.de> + +- update to 1.32.0: + * Look for configuration file in parent directories + * Rule anchors: add new option forbid-unused-anchors + +------------------------------------------------------------------- Old: ---- yamllint-1.31.0.tar.gz New: ---- yamllint-1.32.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-yamllint.spec ++++++ --- /var/tmp/diff_new_pack.OGQ0os/_old 2023-06-01 17:21:15.030775734 +0200 +++ /var/tmp/diff_new_pack.OGQ0os/_new 2023-06-01 17:21:15.034775757 +0200 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-yamllint -Version: 1.31.0 +Version: 1.32.0 Release: 0 Summary: A linter for YAML files License: GPL-3.0-only ++++++ yamllint-1.31.0.tar.gz -> yamllint-1.32.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/CHANGELOG.rst new/yamllint-1.32.0/CHANGELOG.rst --- old/yamllint-1.31.0/CHANGELOG.rst 2023-04-21 14:23:30.000000000 +0200 +++ new/yamllint-1.32.0/CHANGELOG.rst 2023-05-22 18:01:32.000000000 +0200 @@ -1,6 +1,12 @@ Changelog ========= +1.32.0 (2023-05-22) +------------------- + +- Look for configuration file in parent directories +- Rule ``anchors``: add new option ``forbid-unused-anchors`` + 1.31.0 (2023-04-21) ------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/PKG-INFO new/yamllint-1.32.0/PKG-INFO --- old/yamllint-1.31.0/PKG-INFO 2023-04-21 16:34:42.861115000 +0200 +++ new/yamllint-1.32.0/PKG-INFO 2023-05-22 18:03:07.044988400 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: yamllint -Version: 1.31.0 +Version: 1.32.0 Summary: A linter for YAML files. Author: Adrien Vergé License: GPL-3.0-only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/docs/configuration.rst new/yamllint-1.32.0/docs/configuration.rst --- old/yamllint-1.31.0/docs/configuration.rst 2023-04-04 17:57:30.000000000 +0200 +++ new/yamllint-1.32.0/docs/configuration.rst 2023-05-22 18:00:04.000000000 +0200 @@ -15,7 +15,8 @@ following locations (by order of preference): - a file named ``.yamllint``, ``.yamllint.yaml``, or ``.yamllint.yml`` in the - current working directory + current working directory, or a parent directory (the search for this file is + terminated at the user's home or filesystem root) - a filename referenced by ``$YAMLLINT_CONFIG_FILE``, if set - a file named ``$XDG_CONFIG_HOME/yamllint/config`` or ``~/.config/yamllint/config``, if present diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/tests/rules/test_anchors.py new/yamllint-1.32.0/tests/rules/test_anchors.py --- old/yamllint-1.31.0/tests/rules/test_anchors.py 2023-04-11 18:31:32.000000000 +0200 +++ new/yamllint-1.32.0/tests/rules/test_anchors.py 2023-05-10 06:43:08.000000000 +0200 @@ -80,7 +80,8 @@ def test_forbid_undeclared_aliases(self): conf = ('anchors:\n' ' forbid-undeclared-aliases: true\n' - ' forbid-duplicated-anchors: false\n') + ' forbid-duplicated-anchors: false\n' + ' forbid-unused-anchors: false\n') self.check('---\n' '- &b true\n' '- &i 42\n' @@ -122,6 +123,7 @@ '- *f_m\n' '- *f_s\n' # declared after '- &f_s [1, 2]\n' + '...\n' '---\n' 'block mapping: &b_m\n' ' key: value\n' @@ -141,13 +143,14 @@ problem3=(11, 3), problem4=(12, 3), problem5=(13, 3), - problem6=(24, 7), - problem7=(27, 37)) + problem6=(25, 7), + problem7=(28, 37)) def test_forbid_duplicated_anchors(self): conf = ('anchors:\n' ' forbid-undeclared-aliases: false\n' - ' forbid-duplicated-anchors: true\n') + ' forbid-duplicated-anchors: true\n' + ' forbid-unused-anchors: false\n') self.check('---\n' '- &b true\n' '- &i 42\n' @@ -189,6 +192,7 @@ '- *f_m\n' '- *f_s\n' # declared after '- &f_s [1, 2]\n' + '...\n' '---\n' 'block mapping: &b_m\n' ' key: value\n' @@ -205,5 +209,73 @@ '...\n', conf, problem1=(5, 3), problem2=(6, 3), - problem3=(21, 18), - problem4=(27, 20)) + problem3=(22, 18), + problem4=(28, 20)) + + def test_forbid_unused_anchors(self): + conf = ('anchors:\n' + ' forbid-undeclared-aliases: false\n' + ' forbid-duplicated-anchors: false\n' + ' forbid-unused-anchors: true\n') + + self.check('---\n' + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- &f_m {k: v}\n' + '- &f_s [1, 2]\n' + '- *b\n' + '- *i\n' + '- *s\n' + '- *f_m\n' + '- *f_s\n' + '---\n' # redeclare anchors in a new document + '- &b true\n' + '- &i 42\n' + '- &s hello\n' + '- *b\n' + '- *i\n' + '- *s\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &y 3, *x : 4, e: *y}\n' + '...\n', conf) + self.check('---\n' + '- &i 42\n' + '---\n' + '- &b true\n' + '- &b true\n' + '- &b true\n' + '- &s hello\n' + '- *b\n' + '- *i\n' # declared in a previous document + '- *f_m\n' # never declared + '- *f_m\n' + '- *f_m\n' + '- *f_s\n' # declared after + '- &f_s [1, 2]\n' + '...\n' + '---\n' + 'block mapping: &b_m\n' + ' key: value\n' + '---\n' + 'block mapping 1: &b_m_bis\n' + ' key: value\n' + 'block mapping 2: &b_m_bis\n' + ' key: value\n' + 'extended:\n' + ' <<: *b_m\n' + ' foo: bar\n' + '---\n' + '{a: 1, &x b: 2, c: &x 3, *x : 4, e: *y}\n' + '...\n', conf, + problem1=(2, 3), + problem2=(7, 3), + problem3=(14, 3), + problem4=(17, 16), + problem5=(22, 18)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/tests/test_cli.py new/yamllint-1.32.0/tests/test_cli.py --- old/yamllint-1.31.0/tests/test_cli.py 2023-01-10 18:48:55.000000000 +0100 +++ new/yamllint-1.32.0/tests/test_cli.py 2023-05-22 18:00:04.000000000 +0200 @@ -734,3 +734,64 @@ self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', '')) + + def test_parent_config_file(self): + workspace = {'a/b/c/d/e/f/g/a.yml': 'hello: world\n'} + conf = ('---\n' + 'extends: relaxed\n') + + for conf_file in ('.yamllint', '.yamllint.yml', '.yamllint.yaml'): + with self.subTest(conf_file): + with temp_workspace(workspace): + with RunContext(self) as ctx: + os.chdir('a/b/c/d/e/f') + cli.run(('-f', 'parsable', '.')) + + self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), + (0, './g/a.yml:1:1: [warning] missing ' + 'document start "---" (document-start)\n', + '')) + + with temp_workspace({**workspace, **{conf_file: conf}}): + with RunContext(self) as ctx: + os.chdir('a/b/c/d/e/f') + cli.run(('-f', 'parsable', '.')) + + self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), + (0, '', '')) + + def test_multiple_parent_config_file(self): + workspace = {'a/b/c/3spaces.yml': 'array:\n' + ' - item\n', + 'a/b/c/4spaces.yml': 'array:\n' + ' - item\n', + 'a/.yamllint': '---\n' + 'extends: relaxed\n' + 'rules:\n' + ' indentation:\n' + ' spaces: 4\n', + } + + conf3 = ('---\n' + 'extends: relaxed\n' + 'rules:\n' + ' indentation:\n' + ' spaces: 3\n') + + with temp_workspace(workspace): + with RunContext(self) as ctx: + os.chdir('a/b/c') + cli.run(('-f', 'parsable', '.')) + + self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), + (0, './3spaces.yml:2:4: [warning] wrong indentation: ' + 'expected 4 but found 3 (indentation)\n', '')) + + with temp_workspace({**workspace, **{'a/b/.yamllint.yml': conf3}}): + with RunContext(self) as ctx: + os.chdir('a/b/c') + cli.run(('-f', 'parsable', '.')) + + self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), + (0, './4spaces.yml:2:5: [warning] wrong indentation: ' + 'expected 3 but found 4 (indentation)\n', '')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/yamllint/__init__.py new/yamllint-1.32.0/yamllint/__init__.py --- old/yamllint-1.31.0/yamllint/__init__.py 2023-04-21 14:18:35.000000000 +0200 +++ new/yamllint-1.32.0/yamllint/__init__.py 2023-05-22 18:00:15.000000000 +0200 @@ -21,7 +21,7 @@ APP_NAME = 'yamllint' -APP_VERSION = '1.31.0' +APP_VERSION = '1.32.0' APP_DESCRIPTION = __doc__ __author__ = 'Adrien Vergé' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/yamllint/cli.py new/yamllint-1.32.0/yamllint/cli.py --- old/yamllint-1.31.0/yamllint/cli.py 2023-01-10 18:48:55.000000000 +0100 +++ new/yamllint-1.32.0/yamllint/cli.py 2023-05-22 18:00:04.000000000 +0200 @@ -141,6 +141,19 @@ return max_level +def find_project_config_filepath(path='.'): + for filename in ('.yamllint', '.yamllint.yaml', '.yamllint.yml'): + filepath = os.path.join(path, filename) + if os.path.isfile(filepath): + return filepath + + if os.path.abspath(path) == os.path.abspath(os.path.expanduser('~')): + return None + if os.path.abspath(path) == os.path.abspath(os.path.join(path, '..')): + return None + return find_project_config_filepath(path=os.path.join(path, '..')) + + def run(argv=None): parser = argparse.ArgumentParser(prog=APP_NAME, description=APP_DESCRIPTION) @@ -185,6 +198,7 @@ else: user_global_config = os.path.expanduser('~/.config/yamllint/config') + project_config_filepath = find_project_config_filepath() try: if args.config_data is not None: if args.config_data != '' and ':' not in args.config_data: @@ -192,12 +206,8 @@ conf = YamlLintConfig(content=args.config_data) elif args.config_file is not None: conf = YamlLintConfig(file=args.config_file) - elif os.path.isfile('.yamllint'): - conf = YamlLintConfig(file='.yamllint') - elif os.path.isfile('.yamllint.yaml'): - conf = YamlLintConfig(file='.yamllint.yaml') - elif os.path.isfile('.yamllint.yml'): - conf = YamlLintConfig(file='.yamllint.yml') + elif project_config_filepath: + conf = YamlLintConfig(file=project_config_filepath) elif os.path.isfile(user_global_config): conf = YamlLintConfig(file=user_global_config) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/yamllint/rules/anchors.py new/yamllint-1.32.0/yamllint/rules/anchors.py --- old/yamllint-1.31.0/yamllint/rules/anchors.py 2023-04-14 11:33:23.000000000 +0200 +++ new/yamllint-1.32.0/yamllint/rules/anchors.py 2023-05-10 06:56:21.000000000 +0200 @@ -24,6 +24,8 @@ later in the document). * Set ``forbid-duplicated-anchors`` to ``true`` to avoid duplications of a same anchor. +* Set ``forbid-unused-anchors`` to ``true`` to avoid anchors being declared but + not used anywhere in the YAML document via alias. .. rubric:: Default values (when enabled) @@ -33,6 +35,7 @@ anchors: forbid-undeclared-aliases: true forbid-duplicated-anchors: false + forbid-unused-anchors: false .. rubric:: Examples @@ -78,6 +81,26 @@ --- - &anchor Foo Bar - &anchor [item 1, item 2] + +#. With ``anchors: {forbid-unused-anchors: true}`` + + the following code snippet would **PASS**: + :: + + --- + - &anchor + foo: bar + - *anchor + + the following code snippet would **FAIL**: + :: + + --- + - &anchor + foo: bar + - items: + - item1 + - item2 """ @@ -89,15 +112,22 @@ ID = 'anchors' TYPE = 'token' CONF = {'forbid-undeclared-aliases': bool, - 'forbid-duplicated-anchors': bool} + 'forbid-duplicated-anchors': bool, + 'forbid-unused-anchors': bool} DEFAULT = {'forbid-undeclared-aliases': True, - 'forbid-duplicated-anchors': False} + 'forbid-duplicated-anchors': False, + 'forbid-unused-anchors': False} def check(conf, token, prev, next, nextnext, context): - if conf['forbid-undeclared-aliases'] or conf['forbid-duplicated-anchors']: - if isinstance(token, (yaml.StreamStartToken, yaml.DocumentStartToken)): - context['anchors'] = set() + if (conf['forbid-undeclared-aliases'] or + conf['forbid-duplicated-anchors'] or + conf['forbid-unused-anchors']): + if isinstance(token, ( + yaml.StreamStartToken, + yaml.DocumentStartToken, + yaml.DocumentEndToken)): + context['anchors'] = {} if (conf['forbid-undeclared-aliases'] and isinstance(token, yaml.AliasToken) and @@ -113,6 +143,32 @@ token.start_mark.line + 1, token.start_mark.column + 1, f'found duplicated anchor "{token.value}"') - if conf['forbid-undeclared-aliases'] or conf['forbid-duplicated-anchors']: + if conf['forbid-unused-anchors']: + # Unused anchors can only be detected at the end of Document. + # End of document can be either + # - end of stream + # - end of document sign '...' + # - start of a new document sign '---' + # If next token indicates end of document, + # check if the anchors have been used or not. + # If they haven't been used, report problem on those anchors. + if isinstance(next, (yaml.StreamEndToken, + yaml.DocumentStartToken, + yaml.DocumentEndToken)): + for anchor, info in context['anchors'].items(): + if not info['used']: + yield LintProblem(info['line'] + 1, + info['column'] + 1, + f'found unused anchor "{anchor}"') + elif isinstance(token, yaml.AliasToken): + context['anchors'].get(token.value, {})['used'] = True + + if (conf['forbid-undeclared-aliases'] or + conf['forbid-duplicated-anchors'] or + conf['forbid-unused-anchors']): if isinstance(token, yaml.AnchorToken): - context['anchors'].add(token.value) + context['anchors'][token.value] = { + 'line': token.start_mark.line, + 'column': token.start_mark.column, + 'used': False + } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yamllint-1.31.0/yamllint.egg-info/PKG-INFO new/yamllint-1.32.0/yamllint.egg-info/PKG-INFO --- old/yamllint-1.31.0/yamllint.egg-info/PKG-INFO 2023-04-21 16:34:42.000000000 +0200 +++ new/yamllint-1.32.0/yamllint.egg-info/PKG-INFO 2023-05-22 18:03:06.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: yamllint -Version: 1.31.0 +Version: 1.32.0 Summary: A linter for YAML files. Author: Adrien Vergé License: GPL-3.0-only