Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ansible-lint for openSUSE:Factory checked in at 2023-01-20 17:39:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ansible-lint (Old) and /work/SRC/openSUSE:Factory/.ansible-lint.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-lint" Fri Jan 20 17:39:44 2023 rev:16 rq:1059953 version:6.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/ansible-lint/ansible-lint.changes 2023-01-06 17:06:20.956448770 +0100 +++ /work/SRC/openSUSE:Factory/.ansible-lint.new.32243/ansible-lint.changes 2023-01-20 17:39:59.660957343 +0100 @@ -1,0 +2,17 @@ +Fri Jan 20 10:04:42 UTC 2023 - Johannes Kastl <ka...@b1-systems.de> + +- update to 6.11.0: + * Minor Changes + - Remove opt-in and experimental tags from metadata rule (#2906) @ssbarnea + - Remove opt-in and experimental tags from galaxy rule (#2905) @ssbarnea + - Add galaxy[no-changelog] check to galaxy rule (#2832) @alisonlhart + * Bugfixes + - Fix typo in installing.md (#2901) @wgroenewold + - Fix 'location' attribute for CodeclimateJSONFormatter (#2897) @4ch1m + - Avoid dubious ownership errors with newer versions of git (#2890) @ssbarnea + - Clarify effects of --offline flag (#2896) @Andeye + - Fix infinite hang on schema refresh by adding timeout parameter (#2895) @Andeye + - schema: detect invalid space in meta runtime (#2873) @ssbarnea + - Docs: issue #2864 update urls (#2865) @oraNod + +------------------------------------------------------------------- Old: ---- ansible-lint-6.10.2.tar.gz New: ---- ansible-lint-6.11.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ansible-lint.spec ++++++ --- /var/tmp/diff_new_pack.DJIUJq/_old 2023-01-20 17:40:00.380961325 +0100 +++ /var/tmp/diff_new_pack.DJIUJq/_new 2023-01-20 17:40:00.384961347 +0100 @@ -31,7 +31,7 @@ %global lib_name ansiblelint %{?python_enable_dependency_generator} Name: ansible-lint -Version: 6.10.2 +Version: 6.11.0 Release: 0%{?dist} Summary: Best practices checker for Ansible License: MIT ++++++ ansible-lint-6.10.2.tar.gz -> ansible-lint-6.11.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/.ansible-lint new/ansible-lint-6.11.0/.ansible-lint --- old/ansible-lint-6.10.2/.ansible-lint 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/.ansible-lint 2023-01-17 20:57:11.000000000 +0100 @@ -75,7 +75,7 @@ # write_list: # - all -# Offline mode disables installation of requirements.yml +# Offline mode disables installation of requirements.yml and schema refreshing offline: true # Return success if number of violations compared with previous git diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/.config/requirements.txt new/ansible-lint-6.11.0/.config/requirements.txt --- old/ansible-lint-6.10.2/.config/requirements.txt 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/.config/requirements.txt 2023-01-17 20:57:11.000000000 +0100 @@ -2,24 +2,24 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --extra=docs --extra=lock --extra=test --no-annotate --output-file=.config/requirements.txt --resolver=backtracking --strip-extras --unsafe-package=ansible-core pyproject.toml +# pip-compile --extra=docs --extra=test --no-annotate --output-file=.config/requirements.txt --resolver=backtracking --strip-extras --unsafe-package=ansible-core pyproject.toml # -alabaster==0.7.12 +alabaster==0.7.13 ansible-compat==2.2.7 ansible-pygments==0.1.1 -astroid==2.12.13 +astroid==2.13.2 attrs==22.2.0 babel==2.11.0 black==22.12.0 bracex==2.3.post1 certifi==2022.12.7 cffi==1.15.1 -charset-normalizer==2.1.1 +charset-normalizer==3.0.1 click==8.1.3 commonmark==0.9.1 -coverage==7.0.1 +coverage==7.0.5 coverage-enable-subprocess==1.0 -cryptography==38.0.4 +cryptography==39.0.0 dill==0.3.6 docutils==0.17.1 exceptiongroup==1.1.0 @@ -29,12 +29,12 @@ flake8-future-annotations==1.0.0 idna==3.4 imagesize==1.4.1 -importlib-metadata==5.2.0 -iniconfig==1.1.1 +importlib-metadata==6.0.0 +iniconfig==2.0.0 isort==5.11.4 jinja2==3.1.2 jsonschema==4.17.3 -lazy-object-proxy==1.8.0 +lazy-object-proxy==1.9.0 markdown-it-py==2.1.0 markupsafe==2.1.1 mccabe==0.7.0 @@ -43,9 +43,9 @@ mypy==0.991 mypy-extensions==0.4.3 myst-parser==0.18.1 -packaging==22.0 +packaging==23.0 pathspec==0.10.3 -pbr==5.11.0 +pbr==5.11.1 pipdeptree==2.3.3 platformdirs==2.6.2 pluggy==1.0.0 @@ -53,27 +53,27 @@ pycodestyle==2.10.0 pycparser==2.21 pyflakes==3.0.1 -pygments==2.13.0 -pylint==2.15.9 +pygments==2.14.0 +pylint==2.15.10 pyrsistent==0.19.3 -pytest==7.2.0 +pytest==7.2.1 pytest-mock==3.10.0 pytest-plus==0.4.0 pytest-xdist==3.1.0 -pytz==2022.7 +pytz==2022.7.1 pyyaml==6.0 -requests==2.28.1 +requests==2.28.2 resolvelib==0.8.1 -rich==13.0.0 +rich==13.1.0 ruamel-yaml==0.17.21 ruamel-yaml-clib==0.2.7 -setuptools==65.6.3 +setuptools==66.0.0 snowballstemmer==2.2.0 sphinx==5.3.0 sphinx-ansible-theme==0.10.1 sphinx-rtd-theme==1.1.1 sphinxcontrib-apidoc==0.3.0 -sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-applehelp==1.0.3 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.0 sphinxcontrib-jsmath==1.0.1 @@ -84,10 +84,10 @@ tomli==2.0.1 tomlkit==0.11.6 typing-extensions==4.4.0 -urllib3==1.26.13 +urllib3==1.26.14 wcmatch==8.4.1 wrapt==1.14.1 -yamllint==1.28.0 +yamllint==1.29.0 zipp==3.11.0 # The following packages are considered to be unsafe in a requirements file: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/.git_archival.txt new/ansible-lint-6.11.0/.git_archival.txt --- old/ansible-lint-6.10.2/.git_archival.txt 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/.git_archival.txt 2023-01-17 20:57:11.000000000 +0100 @@ -1 +1 @@ -ref-names: HEAD -> main, tag: v6.10.2 +ref-names: tag: v6.11.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/.github/workflows/tox.yml new/ansible-lint-6.11.0/.github/workflows/tox.yml --- old/ansible-lint-6.10.2/.github/workflows/tox.yml 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/.github/workflows/tox.yml 2023-01-17 20:57:11.000000000 +0100 @@ -69,7 +69,7 @@ WSLENV: FORCE_COLOR:PYTEST_REQPASS:TOXENV:GITHUB_STEP_SUMMARY # Number of expected test passes, safety measure for accidental skip of # tests. Update value if you add/remove tests. - PYTEST_REQPASS: 743 + PYTEST_REQPASS: 749 steps: - name: Activate WSL1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/.pre-commit-config.yaml new/ansible-lint-6.11.0/.pre-commit-config.yaml --- old/ansible-lint-6.10.2/.pre-commit-config.yaml 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/.pre-commit-config.yaml 2023-01-17 20:57:11.000000000 +0100 @@ -63,7 +63,7 @@ args: [--relative, --no-progress, --no-summary] name: Spell check with cspell - repo: https://github.com/sirosen/check-jsonschema - rev: 0.19.2 + rev: 0.20.0 hooks: - id: check-github-workflows - repo: https://github.com/pre-commit/pre-commit-hooks.git @@ -112,7 +112,7 @@ hooks: - id: doc8 - repo: https://github.com/adrienverge/yamllint.git - rev: v1.28.0 + rev: v1.29.0 hooks: - id: yamllint exclude: > @@ -181,7 +181,7 @@ plugins/.* )$ - repo: https://github.com/pycqa/pylint - rev: v2.15.9 + rev: v2.16.0b0 hooks: - id: pylint args: @@ -217,7 +217,7 @@ - pip>=22.3.1 - id: pip-compile name: deps - entry: pip-compile --resolver=backtracking -q --no-annotate --output-file=.config/requirements.txt pyproject.toml --extra docs --extra test --extra lock --strip-extras --unsafe-package ansible-core + entry: pip-compile --resolver=backtracking -q --no-annotate --output-file=.config/requirements.txt pyproject.toml --extra docs --extra test --strip-extras --unsafe-package ansible-core language: python files: ^.config\/requirements.*$ alias: deps diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/.vscode/extensions.json new/ansible-lint-6.11.0/.vscode/extensions.json --- old/ansible-lint-6.10.2/.vscode/extensions.json 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/.vscode/extensions.json 2023-01-17 20:57:11.000000000 +0100 @@ -10,6 +10,7 @@ "ms-vscode.live-server", "redhat.ansible", "redhat.vscode-yaml", + "ryanluker.vscode-coverage-gutters", "shardulm94.trailing-spaces", "tamasfe.even-better-toml", "timonwong.shellcheck", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/conftest.py new/ansible-lint-6.11.0/conftest.py --- old/ansible-lint-6.10.2/conftest.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/conftest.py 2023-01-17 20:57:11.000000000 +0100 @@ -4,6 +4,10 @@ import subprocess import sys +# Ensure we always run from the root of the repository +if os.getcwd() != os.path.dirname(__file__): + os.chdir(os.path.dirname(__file__)) + # checking if user is running pytest without installing test dependencies: missing = [] for module in ["ansible", "black", "flake8", "mypy", "pylint"]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/docs/installing.md new/ansible-lint-6.11.0/docs/installing.md --- old/ansible-lint-6.10.2/docs/installing.md 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/docs/installing.md 2023-01-17 20:57:11.000000000 +0100 @@ -13,7 +13,7 @@ ``` For a container image, we recommend using [creator-ee](https://github.com/ansible/creator-ee/), which includes Ansible-lint. -If you have a use case that the `creator-ee` container does satisfy, please contact the team through the [discussions](https://github.com/ansible/ansible-lint/discussions) forum. +If you have a use case that the `creator-ee` container doesn't satisfy, please contact the team through the [discussions](https://github.com/ansible/ansible-lint/discussions) forum. You can also run Ansible-lint on your source code with the [Ansible-lint GitHub action](https://github.com/marketplace/actions/ansible-lint) instead of installing it directly. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/examples/meta/changelogs/changelog.yaml new/ansible-lint-6.11.0/examples/meta/changelogs/changelog.yaml --- old/ansible-lint-6.10.2/examples/meta/changelogs/changelog.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-lint-6.11.0/examples/meta/changelogs/changelog.yaml 2023-01-17 20:57:11.000000000 +0100 @@ -0,0 +1,2 @@ +--- +releases: {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/examples/no_changelog/galaxy.yml new/ansible-lint-6.11.0/examples/no_changelog/galaxy.yml --- old/ansible-lint-6.10.2/examples/no_changelog/galaxy.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-lint-6.11.0/examples/no_changelog/galaxy.yml 2023-01-17 20:57:11.000000000 +0100 @@ -0,0 +1,16 @@ +--- +name: foo +namespace: bar +version: 0.0.0 # noqa: galaxy[version-incorrect] +authors: + - John +readme: ../README.md +description: "..." +dependencies: + other_namespace.collection1: ">=1.0.0" + other_namespace.collection2: ">=2.0.0,<3.0.0" + anderson55.my_collection: "*" # note: "*" selects the highest version available +license: + - GPL # <-- invalid license values based on galaxy schema + - Apache +repository: some-url diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/examples/playbooks/collections/requirements.yml new/ansible-lint-6.11.0/examples/playbooks/collections/requirements.yml --- old/ansible-lint-6.10.2/examples/playbooks/collections/requirements.yml 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/examples/playbooks/collections/requirements.yml 2023-01-17 20:57:11.000000000 +0100 @@ -3,5 +3,5 @@ version: 0.1.0 - name: ansible-posix-1.4.0.tar.gz version: 1.4.0 -- name: community-general-6.1.0.tar.gz - version: 6.1.0 +- name: community-general-6.2.0.tar.gz + version: 6.2.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/examples/playbooks/play-without-extension new/ansible-lint-6.11.0/examples/playbooks/play-without-extension --- old/ansible-lint-6.10.2/examples/playbooks/play-without-extension 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-lint-6.11.0/examples/playbooks/play-without-extension 2023-01-17 20:57:11.000000000 +0100 @@ -0,0 +1,2 @@ +- name: A playbook without expected yml or yaml extension + hosts: localhost diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/plugins/modules/fake_module.py new/ansible-lint-6.11.0/plugins/modules/fake_module.py --- old/ansible-lint-6.10.2/plugins/modules/fake_module.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/plugins/modules/fake_module.py 2023-01-17 20:57:11.000000000 +0100 @@ -8,9 +8,9 @@ def main() -> None: """Return the module instance.""" return AnsibleModule( - argument_spec=dict( - data=dict(default=None), - path=dict(default=None, type=str), - file=dict(default=None, type=str), - ) + argument_spec={ + "data": {"default": None}, + "path": {"default": None}, + "file": {"default": None}, + } ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/pyproject.toml new/ansible-lint-6.11.0/pyproject.toml --- old/ansible-lint-6.10.2/pyproject.toml 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/pyproject.toml 2023-01-17 20:57:11.000000000 +0100 @@ -62,17 +62,22 @@ branch = true parallel = true concurrency = ["multiprocessing", "thread"] -data_file = ".tox/.coverage" +# Keep this default because xml/report do not know to use load it from config file: +# data_file = ".coverage" [tool.coverage.paths] source = ["src", ".tox/*/site-packages"] [tool.coverage.report] exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"] omit = ["*/src/ansible_compat/*", "test/*"] +# Increase it just so it would pass on any single-python run fail_under = 88 skip_covered = true skip_empty = true +# During development we might remove code (files) with coverage data, and we dont want to fail: +ignore_errors = true +show_missing = true [tool.isort] profile = "black" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/__main__.py new/ansible-lint-6.11.0/src/ansiblelint/__main__.py --- old/ansible-lint-6.10.2/src/ansiblelint/__main__.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/__main__.py 2023-01-17 20:57:11.000000000 +0100 @@ -48,7 +48,7 @@ render_yaml, ) from ansiblelint.config import get_version_warning, options -from ansiblelint.constants import EXIT_CONTROL_C_RC, LOCK_TIMEOUT_RC +from ansiblelint.constants import EXIT_CONTROL_C_RC, GIT_CMD, LOCK_TIMEOUT_RC from ansiblelint.file_utils import abspath, cwd, normpath from ansiblelint.skip_utils import normalize_tag from ansiblelint.version import __version__ @@ -113,7 +113,7 @@ os.makedirs(options.cache_dir, exist_ok=True) options.cache_dir_lock = None - if not options.offline: + if not options.offline: # pragma: no cover options.cache_dir_lock = FileLock(f"{options.cache_dir}/.lock") try: options.cache_dir_lock.acquire(timeout=180) @@ -178,7 +178,7 @@ def support_banner() -> None: """Display support banner when running on unsupported platform.""" - if sys.version_info < (3, 9, 0): + if sys.version_info < (3, 9, 0): # pragma: no cover prefix = "::warning::" if "GITHUB_ACTION" in os.environ else "WARNING: " console_stderr.print( f"{prefix}ansible-lint is no longer tested under Python {sys.version_info.major}.{sys.version_info.minor} and will soon require 3.9. Do not report bugs for this version.", @@ -192,7 +192,7 @@ # alter PATH if needed (venv support) path_inject() - if argv is None: + if argv is None: # pragma: no cover argv = sys.argv initialize_options(argv[1:]) @@ -238,7 +238,7 @@ app = get_app() if isinstance(options.tags, str): - options.tags = options.tags.split(",") + options.tags = options.tags.split(",") # pragma: no cover result = _get_matches(rules, options) if options.write_list: @@ -304,7 +304,7 @@ rel_exclude_paths = [normpath(p) for p in options.exclude_paths] options.exclude_paths = [abspath(p, worktree_dir) for p in rel_exclude_paths] revision = subprocess.run( - ["git", "rev-parse", "HEAD^1"], + [*GIT_CMD, "rev-parse", "HEAD^1"], check=True, text=True, stdout=subprocess.PIPE, @@ -318,14 +318,14 @@ # Run check will fail if worktree_dir already exists # pylint: disable=subprocess-run-check subprocess.run( - ["git", "worktree", "add", "-f", worktree_dir], + [*GIT_CMD, "worktree", "add", "-f", worktree_dir], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) try: with cwd(worktree_dir): subprocess.run( - ["git", "checkout", revision], + [*GIT_CMD, "checkout", revision], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True, @@ -365,10 +365,10 @@ # Expand ~ in PATH as it known to break many tools expanded = False for idx, path in enumerate(paths): - if "~" in path: + if "~" in path: # pragma: no cover paths[idx] = os.path.expanduser(path) expanded = True - if expanded: + if expanded: # pragma: no cover print( "WARNING: PATH altered to expand ~ in it. Read https://stackoverflow.com/a/44704799/99834 and correct your system configuration.", file=sys.stderr, @@ -403,7 +403,7 @@ # Based on Ansible implementation -def to_bool(value: Any) -> bool: +def to_bool(value: Any) -> bool: # pragma: no cover """Return a bool for the arg.""" if value is None or isinstance(value, bool): return bool(value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/_internal/rules.py new/ansible-lint-6.11.0/src/ansiblelint/_internal/rules.py --- old/ansible-lint-6.10.2/src/ansiblelint/_internal/rules.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/_internal/rules.py 2023-01-17 20:57:11.000000000 +0100 @@ -69,7 +69,7 @@ def url(self) -> str: """Return rule documentation url.""" url = self.link - if not url: + if not url: # pragma: no cover url = RULE_DOC_URL if self.id: url += self.id + "/" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/cli.py new/ansible-lint-6.11.0/src/ansiblelint/cli.py --- old/ansible-lint-6.10.2/src/ansiblelint/cli.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/cli.py 2023-01-17 20:57:11.000000000 +0100 @@ -415,7 +415,7 @@ dest="offline", action="store_const", const=True, - help="Disable installation of requirements.yml", + help="Disable installation of requirements.yml and schema refreshing", ) parser.add_argument( "--version", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/color.py new/ansible-lint-6.11.0/src/ansiblelint/color.py --- old/ansible-lint-6.10.2/src/ansiblelint/color.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/color.py 2023-01-17 20:57:11.000000000 +0100 @@ -103,7 +103,7 @@ self: rich.markdown.CodeBlock, console: Console, options: rich.console.ConsoleOptions, -) -> rich.console.RenderResult: +) -> rich.console.RenderResult: # pragma: no cover code = str(self.text).rstrip() syntax = Syntax( code, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/constants.py new/ansible-lint-6.11.0/src/ansiblelint/constants.py --- old/ansible-lint-6.10.2/src/ansiblelint/constants.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/constants.py 2023-01-17 20:57:11.000000000 +0100 @@ -145,3 +145,10 @@ "import_role", "include_role", } + +# Newer versions of git might fail to run when different file ownership is +# found of repo. One example is on GHA runners executing containerized +# reusable actions, where the mounted volume might have different owner. +# +# https://github.com/ansible/ansible-lint-action/issues/138 +GIT_CMD = ["git", "-c", f"safe.directory={os.getcwd()}"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/file_utils.py new/ansible-lint-6.11.0/src/ansiblelint/file_utils.py --- old/ansible-lint-6.10.2/src/ansiblelint/file_utils.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/file_utils.py 2023-01-17 20:57:11.000000000 +0100 @@ -19,7 +19,7 @@ from wcmatch.wcmatch import RECURSIVE, WcMatch from ansiblelint.config import BASE_KINDS, options -from ansiblelint.constants import FileType +from ansiblelint.constants import GIT_CMD, FileType if TYPE_CHECKING: # https://github.com/PyCQA/pylint/issues/3979 @@ -368,14 +368,14 @@ """ # git is preferred as it also considers .gitignore git_command_present = [ - "git", + *GIT_CMD, "ls-files", "--cached", "--others", "--exclude-standard", "-z", ] - git_command_absent = ["git", "ls-files", "--deleted", "-z"] + git_command_absent = [*GIT_CMD, "ls-files", "--deleted", "-z"] out = None try: @@ -437,7 +437,7 @@ if path is None: try: result = subprocess.run( - ["git", "rev-parse", "--show-toplevel"], + [*GIT_CMD, "rev-parse", "--show-toplevel"], capture_output=True, text=True, check=True, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/formatters/__init__.py new/ansible-lint-6.11.0/src/ansiblelint/formatters/__init__.py --- old/ansible-lint-6.10.2/src/ansiblelint/formatters/__init__.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/formatters/__init__.py 2023-01-17 20:57:11.000000000 +0100 @@ -162,12 +162,13 @@ ).hexdigest() issue["location"] = {} issue["location"]["path"] = self._format_path(match.filename or "") - issue["location"]["lines"] = {} if match.column: - issue["location"]["lines"]["begin"] = {} - issue["location"]["lines"]["begin"]["line"] = match.linenumber - issue["location"]["lines"]["begin"]["column"] = match.column + issue["location"]["positions"] = {} + issue["location"]["positions"]["begin"] = {} + issue["location"]["positions"]["begin"]["line"] = match.linenumber + issue["location"]["positions"]["begin"]["column"] = match.column else: + issue["location"]["lines"] = {} issue["location"]["lines"]["begin"] = match.linenumber if match.details: issue["content"] = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/galaxy.md new/ansible-lint-6.11.0/src/ansiblelint/rules/galaxy.md --- old/ansible-lint-6.10.2/src/ansiblelint/rules/galaxy.md 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/galaxy.md 2023-01-17 20:57:11.000000000 +0100 @@ -2,10 +2,13 @@ This rule identifies if the collection version mentioned in galaxy.yml is ideal in terms of the version number being greater than or equal to `1.0.0`. +This rule also looks for a changelog file in expected locations, detailed below in the Changelog Details section. + This rule can produce messages such: - `galaxy[version-missing]` - `galaxy.yaml` should have version tag. - `galaxy[version-incorrect]` - collection version should be greater than or equal to `1.0.0` +- `galaxy[no-changelog]` - collection is missing a changelog file in expected locations. If you want to ignore some of the messages above, you can add any of them to the `ignore_list`. @@ -37,3 +40,16 @@ readme: ../README.md description: "..." ``` + +# Changelog Details + +This rule expects a `CHANGELOG.md` or `.rst` file in the collection root or a `changelogs/changelog.yaml` file. + +If a `changelogs/changelog.yaml` file exists, the schema will be checked. + +# Minimum required changelog.yaml file + +```yaml +# changelog.yaml +--- +releases: {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/galaxy.py new/ansible-lint-6.11.0/src/ansiblelint/rules/galaxy.py --- old/ansible-lint-6.10.2/src/ansiblelint/rules/galaxy.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/galaxy.py 2023-01-17 20:57:11.000000000 +0100 @@ -1,6 +1,7 @@ """Implementation of GalaxyRule.""" from __future__ import annotations +import os import sys from functools import total_ordering from typing import TYPE_CHECKING, Any @@ -14,30 +15,33 @@ class GalaxyRule(AnsibleLintRule): - """Rule for checking collection version is greater than 1.0.0.""" + """Rule for checking collection version is greater than 1.0.0 and checking for changelog.""" id = "galaxy" - description = "Confirm via galaxy.yml file if collection version is greater than or equal to 1.0.0" + description = "Confirm via galaxy.yml file if collection version is greater than or equal to 1.0.0 and check for changelog." severity = "MEDIUM" - tags = ["metadata", "opt-in", "experimental"] - version_added = "v6.6.0 (last update)" + tags = ["metadata"] + version_added = "v6.11.0 (last update)" def matchplay(self, file: Lintable, data: dict[str, Any]) -> list[MatchError]: """Return matches found for a specific play (entry in playbook).""" if file.kind != "galaxy": # type: ignore return [] + + results = [] + if "version" not in data: - return [ + results.append( self.create_matcherror( message="galaxy.yaml should have version tag.", linenumber=data[LINE_NUMBER_KEY], tag="galaxy[version-missing]", filename=file, ) - ] + ) version = data.get("version") if Version(version) < Version("1.0.0"): - return [ + results.append( self.create_matcherror( message="collection version should be greater than or equal to 1.0.0", # pylint: disable=protected-access @@ -45,8 +49,33 @@ tag="galaxy[version-incorrect]", filename=file, ) - ] - return [] + ) + + # Changelog Check - building off Galaxy rule as there is no current way to check + # for a nonexistent file + + base_path = os.path.split(str(file.abspath))[0] + changelog_found = 0 + changelog_paths = [ + os.path.join(base_path, "changelogs", "changelog.yaml"), + os.path.join(base_path, "CHANGELOG.rst"), + os.path.join(base_path, "CHANGELOG.md"), + ] + + for path in changelog_paths: + if os.path.isfile(path): + changelog_found = 1 + + if not changelog_found: + results.append( + self.create_matcherror( + message="No changelog found. Please add a changelog file. Refer to the galaxy.md file for more info.", + tag="galaxy[no-changelog]", + filename=file, + ) + ) + + return results @total_ordering @@ -105,3 +134,18 @@ bad_runner = Runner(failure, rules=collection) errs = bad_runner.run() assert len(errs) == 1 + + def test_changelog_present() -> None: + """Positive test for finding a changelog.""" + collection = RulesCollection() + collection.register(GalaxyRule()) + good_runner = Runner("examples/collection/galaxy.yml", rules=collection) + assert [] == good_runner.run() + + def test_changelog_missing() -> None: + """Negative test for finding a changelog.""" + collection = RulesCollection() + collection.register(GalaxyRule()) + bad_runner = Runner("examples/no_changelog/galaxy.yml", rules=collection) + errs = bad_runner.run() + assert len(errs) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/loop_var_prefix.py new/ansible-lint-6.11.0/src/ansiblelint/rules/loop_var_prefix.py --- old/ansible-lint-6.10.2/src/ansiblelint/rules/loop_var_prefix.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/loop_var_prefix.py 2023-01-17 20:57:11.000000000 +0100 @@ -18,7 +18,7 @@ id = "loop-var-prefix" link = ( - "https://docs.ansible.com/ansible/latest/user_guide/" + "https://docs.ansible.com/ansible/latest/playbook_guide/" "playbooks_loops.html#defining-inner-and-outer-variable-names-with-loop-var" ) description = """\ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/meta_unsupported_ansible.py new/ansible-lint-6.11.0/src/ansiblelint/rules/meta_unsupported_ansible.py --- old/ansible-lint-6.10.2/src/ansiblelint/rules/meta_unsupported_ansible.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/meta_unsupported_ansible.py 2023-01-17 20:57:11.000000000 +0100 @@ -31,8 +31,8 @@ "a supported platform version of ansible-core." ) severity = "VERY_HIGH" - tags = ["metadata", "opt-in", "experimental"] - version_added = "v6.8.6 (last update)" + tags = ["metadata"] + version_added = "v6.11.0 (last update)" supported_ansible = ["2.9.10", "2.11", "2.12", "2.13", "2.14"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/no_handler.md new/ansible-lint-6.11.0/src/ansiblelint/rules/no_handler.md --- old/ansible-lint-6.10.2/src/ansiblelint/rules/no_handler.md 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/no_handler.md 2023-01-17 20:57:11.000000000 +0100 @@ -3,7 +3,7 @@ This rule checks for the correct handling of changes to results or conditions. If a task has a `when: result.changed` condition, it effectively acts as a -[handler](https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html). +[handler](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#handlers). The recommended approach is to use `notify` and move tasks to `handlers`. If necessary you can silence the rule by add a `# noqa: no-handler` comment at the end of the line. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/no_handler.py new/ansible-lint-6.11.0/src/ansiblelint/rules/no_handler.py --- old/ansible-lint-6.10.2/src/ansiblelint/rules/no_handler.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/no_handler.py 2023-01-17 20:57:11.000000000 +0100 @@ -56,7 +56,7 @@ "acting as a handler. You could use ``notify`` and move that task to " "``handlers``." ) - link = "https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html" + link = "https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#handlers" severity = "MEDIUM" tags = ["idiom"] version_added = "historic" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/playbook_extension.py new/ansible-lint-6.11.0/src/ansiblelint/rules/playbook_extension.py --- old/ansible-lint-6.10.2/src/ansiblelint/rules/playbook_extension.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/playbook_extension.py 2023-01-17 20:57:11.000000000 +0100 @@ -4,13 +4,15 @@ from __future__ import annotations import os +import sys from ansiblelint.errors import MatchError from ansiblelint.file_utils import Lintable from ansiblelint.rules import AnsibleLintRule +from ansiblelint.runner import Runner -class PlaybookExtension(AnsibleLintRule): +class PlaybookExtensionRule(AnsibleLintRule): """Use ".yml" or ".yaml" playbook extension.""" id = "playbook-extension" @@ -30,3 +32,22 @@ self.done.append(path) result.append(self.create_matcherror(filename=file)) return result + + +if "pytest" in sys.modules: # noqa: C901 + import pytest + + from ansiblelint.rules import RulesCollection # pylint: disable=ungrouped-imports + + @pytest.mark.parametrize( + ("file", "expected"), + (pytest.param("examples/playbooks/play-without-extension", 1, id="fail"),), + ) + def test_playbook_extension(file: str, expected: int) -> None: + """The ini_file module does not accept preserve mode.""" + rules = RulesCollection() + rules.register(PlaybookExtensionRule()) + results = Runner(Lintable(file, kind="playbook"), rules=rules).run() + assert len(results) == expected + for result in results: + assert result.tag == "playbook-extension" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/rules/risky_octal.py new/ansible-lint-6.11.0/src/ansiblelint/rules/risky_octal.py --- old/ansible-lint-6.10.2/src/ansiblelint/rules/risky_octal.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/rules/risky_octal.py 2023-01-17 20:57:11.000000000 +0100 @@ -171,6 +171,7 @@ collection = RulesCollection() collection.register(OctalPermissionsRule()) results = Runner(file, rules=collection).run() + assert len(results) == failures for result in results: assert result.rule.id == "risky-octal" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/schemas/__store__.json new/ansible-lint-6.11.0/src/ansiblelint/schemas/__store__.json --- old/ansible-lint-6.10.2/src/ansiblelint/schemas/__store__.json 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/schemas/__store__.json 2023-01-17 20:57:11.000000000 +0100 @@ -28,11 +28,11 @@ "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json" }, "meta": { - "etag": "12af007a9165999f589464911ed2f0497bdf6e591c401cafa864f3b481988653", + "etag": "1f128994877dd4f9d0712ed36930d6f14d7cd9d601b459d9f19fa7104e626f51", "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json" }, "meta-runtime": { - "etag": "a7391f9074aa150c1d635acd9a3b813df50ba7a71432fa58d8c8964520263977", + "etag": "c1633dcafd016a44e2aba7574136983fef3da2bbb74eeb61785424081e8a82a8", "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta-runtime.json" }, "molecule": { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/schemas/main.py new/ansible-lint-6.11.0/src/ansiblelint/schemas/main.py --- old/ansible-lint-6.10.2/src/ansiblelint/schemas/main.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/schemas/main.py 2023-01-17 20:57:11.000000000 +0100 @@ -104,7 +104,7 @@ if etag: request.add_header("If-None-Match", f'"{data.get("etag")}"') try: - with urllib.request.urlopen(request) as response: + with urllib.request.urlopen(request, timeout=10) as response: if response.status == 200: content = response.read().decode("utf-8").rstrip() etag = response.headers["etag"].strip('"') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/schemas/meta-runtime.json new/ansible-lint-6.11.0/src/ansiblelint/schemas/meta-runtime.json --- old/ansible-lint-6.10.2/src/ansiblelint/schemas/meta-runtime.json 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/schemas/meta-runtime.json 2023-01-17 20:57:11.000000000 +0100 @@ -72,6 +72,7 @@ }, "requires_ansible": { "examples": [">=2.10,<2.11"], + "pattern": "^[^\\s]*$", "title": "The version of Ansible Core (ansible-core) required to use the collection. Multiple versions can be separated with a comma.", "type": "string" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/testing/__init__.py new/ansible-lint-6.11.0/src/ansiblelint/testing/__init__.py --- old/ansible-lint-6.10.2/src/ansiblelint/testing/__init__.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/testing/__init__.py 2023-01-17 20:57:11.000000000 +0100 @@ -32,7 +32,7 @@ """Initialize a RunFromText instance with rules collection.""" # Emulate command line execution initialization as without it Ansible module # would be loaded with incomplete module/role/collection list. - if not self.app: + if not self.app: # pragma: no cover self.app = get_app() self.collection = collection @@ -101,7 +101,7 @@ ) -> CompletedProcess: """Run ansible-lint on a given path and returns its output.""" args = [*argv] - if offline: + if offline: # pragma: no cover args.insert(0, "--offline") if not executable: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/testing/fixtures.py new/ansible-lint-6.11.0/src/ansiblelint/testing/fixtures.py --- old/ansible-lint-6.10.2/src/ansiblelint/testing/fixtures.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/testing/fixtures.py 2023-01-17 20:57:11.000000000 +0100 @@ -10,7 +10,6 @@ import copy import os from argparse import Namespace -from pathlib import Path from typing import Iterator import pytest @@ -18,27 +17,10 @@ from ansiblelint.config import options # noqa: F401 from ansiblelint.constants import DEFAULT_RULESDIR -from ansiblelint.file_utils import Lintable from ansiblelint.rules import RulesCollection -from ansiblelint.runner import Runner from ansiblelint.testing import RunFromText -@pytest.fixture(name="play_file_path") -def fixture_play_file_path(tmp_path: Path) -> str: - """Fixture to return a playbook path.""" - path = tmp_path / "playbook.yml" - return str(path) - - -@pytest.fixture -def runner( - play_file_path: Lintable | str, default_rules_collection: RulesCollection -) -> Runner: - """Fixture to return a Runner() instance.""" - return Runner(play_file_path, rules=default_rules_collection) - - @pytest.fixture(name="default_rules_collection") def fixture_default_rules_collection() -> RulesCollection: """Return default rule collection.""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/utils.py new/ansible-lint-6.11.0/src/ansiblelint/utils.py --- old/ansible-lint-6.10.2/src/ansiblelint/utils.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/utils.py 2023-01-17 20:57:11.000000000 +0100 @@ -300,7 +300,7 @@ v = template( os.path.abspath(basedir), v, - dict(playbook_dir=PLAYBOOK_DIR or os.path.abspath(basedir)), + {"playbook_dir": PLAYBOOK_DIR or os.path.abspath(basedir)}, fail_on_undefined=False, ) return delegate_map[k](basedir, k, v, parent_type) @@ -523,7 +523,7 @@ def _kv_to_dict(v: str) -> dict[str, Any]: (command, args, kwargs) = tokenize(v) - return dict(__ansible_module__=command, __ansible_arguments__=args, **kwargs) + return {"__ansible_module__": command, "__ansible_arguments__": args, **kwargs} def _sanitize_task(task: dict[str, Any]) -> dict[str, Any]: @@ -564,10 +564,10 @@ if is_nested_task(task): _extract_ansible_parsed_keys_from_task(result, task, ansible_parsed_keys) # Add dummy action for block/always/rescue statements - result["action"] = dict( - __ansible_module__="block/always/rescue", - __ansible_module_original__="block/always/rescue", - ) + result["action"] = { + "__ansible_module__": "block/always/rescue", + "__ansible_module_original__": "block/always/rescue", + } return result @@ -604,9 +604,10 @@ # the opposite. Mainly we currently consider normalized the module listing # used by `ansible-doc -t module -l 2>/dev/null` action = removeprefix(action, "ansible.builtin.") - result["action"] = dict( - __ansible_module__=action, __ansible_module_original__=action_unnormalized - ) + result["action"] = { + "__ansible_module__": action, + "__ansible_module_original__": action_unnormalized, + } if "_raw_params" in arguments: # Doing a split here is really bad as it would break jinja2 templating diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/src/ansiblelint/version.py new/ansible-lint-6.11.0/src/ansiblelint/version.py --- old/ansible-lint-6.10.2/src/ansiblelint/version.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/src/ansiblelint/version.py 2023-01-17 20:57:11.000000000 +0100 @@ -1,7 +1,7 @@ """Ansible-lint version information.""" try: from ._version import version as __version__ -except ImportError: # pragma: no branch +except ImportError: # pragma: no cover try: import pkg_resources diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/schemas/negative_test/meta/runtime.yml new/ansible-lint-6.11.0/test/schemas/negative_test/meta/runtime.yml --- old/ansible-lint-6.10.2/test/schemas/negative_test/meta/runtime.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-lint-6.11.0/test/schemas/negative_test/meta/runtime.yml 2023-01-17 20:57:11.000000000 +0100 @@ -0,0 +1 @@ +requires_ansible: ">= 2.12" # invalid as space is not allowed! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/schemas/negative_test/meta/runtime.yml.md new/ansible-lint-6.11.0/test/schemas/negative_test/meta/runtime.yml.md --- old/ansible-lint-6.10.2/test/schemas/negative_test/meta/runtime.yml.md 1970-01-01 01:00:00.000000000 +0100 +++ new/ansible-lint-6.11.0/test/schemas/negative_test/meta/runtime.yml.md 2023-01-17 20:57:11.000000000 +0100 @@ -0,0 +1,34 @@ +# ajv errors + +```json +[ + { + "instancePath": "/requires_ansible", + "keyword": "pattern", + "message": "must match pattern \"^[^\\s]*$\"", + "params": { + "pattern": "^[^\\s]*$" + }, + "schemaPath": "#/properties/requires_ansible/pattern" + } +] +``` + +# check-jsonschema + +stdout: + +```json +{ + "status": "fail", + "errors": [ + { + "filename": "negative_test/meta/runtime.yml", + "path": "$.requires_ansible", + "message": "'>= 2.12' does not match '^[^\\\\s]*$'", + "has_sub_errors": false + } + ], + "parse_errors": [] +} +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_ansiblelintrule.py new/ansible-lint-6.11.0/test/test_ansiblelintrule.py --- old/ansible-lint-6.10.2/test/test_ansiblelintrule.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_ansiblelintrule.py 2023-01-17 20:57:11.000000000 +0100 @@ -17,7 +17,7 @@ assert AnsibleLintRule.unjinja(text) == output -@pytest.mark.parametrize("rule_config", ({}, dict(foo=True, bar=1))) +@pytest.mark.parametrize("rule_config", ({}, {"foo": True, "bar": 1})) def test_rule_config(rule_config: dict[str, Any], monkeypatch: MonkeyPatch) -> None: """Check that a rule config is inherited from options.""" rule_id = "rule-0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_formatter_json.py new/ansible-lint-6.11.0/test/test_formatter_json.py --- old/ansible-lint-6.10.2/test/test_formatter_json.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_formatter_json.py 2023-01-17 20:57:11.000000000 +0100 @@ -90,6 +90,28 @@ assert single_match["location"]["path"] == self.matches[0].filename assert "lines" in single_match["location"] assert single_match["location"]["lines"]["begin"] == self.matches[0].linenumber + assert "positions" not in single_match["location"] + + def test_validate_codeclimate_schema_with_positions(self) -> None: + """Test if the returned JSON is a valid codeclimate report (containing 'positions' instead of 'lines').""" + assert isinstance(self.formatter, CodeclimateJSONFormatter) + result = json.loads( + self.formatter.format_result( + [ + MatchError( + message="message", + linenumber=1, + column=42, + details="hello", + filename=Lintable("filename.yml"), + rule=self.rule, + ) + ] + ) + ) + assert result[0]["location"]["positions"]["begin"]["line"] == 1 + assert result[0]["location"]["positions"]["begin"]["column"] == 42 + assert "lines" not in result[0]["location"] def test_code_climate_parsable_ignored() -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_matcherrror.py new/ansible-lint-6.11.0/test/test_matcherrror.py --- old/ansible-lint-6.10.2/test/test_matcherrror.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_matcherrror.py 2023-01-17 20:57:11.000000000 +0100 @@ -67,7 +67,7 @@ r"^MatchError\(\) missing a required argument: one of 'message' or 'rule'$" ) with pytest.raises(TypeError, match=expected_err): - MatchError() + raise MatchError() @pytest.mark.parametrize( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_progressive.py new/ansible-lint-6.11.0/test/test_progressive.py --- old/ansible-lint-6.10.2/test/test_progressive.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_progressive.py 2023-01-17 20:57:11.000000000 +0100 @@ -6,6 +6,7 @@ import sys from pathlib import Path +from ansiblelint.constants import GIT_CMD from ansiblelint.file_utils import cwd FAULTY_PLAYBOOK = """--- @@ -29,16 +30,16 @@ def git_init() -> None: """Init temporary git repository.""" - subprocess.run(["git", "init", "--initial-branch=main"], check=True) - subprocess.run(["git", "config", "user.email", "t...@example.com"], check=True) - subprocess.run(["git", "config", "user.name", "test"], check=True) + subprocess.run([*GIT_CMD, "init", "--initial-branch=main"], check=True) + subprocess.run([*GIT_CMD, "config", "user.email", "t...@example.com"], check=True) + subprocess.run([*GIT_CMD, "config", "user.name", "test"], check=True) def git_commit(filename: Path, content: str) -> None: """Create and commit a file.""" filename.write_text(content) - subprocess.run(["git", "add", filename], check=True) - subprocess.run(["git", "commit", "-a", "-m", f"Commit {filename}"], check=True) + subprocess.run([*GIT_CMD, "add", filename], check=True) + subprocess.run([*GIT_CMD, "commit", "-a", "-m", f"Commit {filename}"], check=True) def run_lint(cmd: list[str]) -> subprocess.CompletedProcess[str]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_schemas.py new/ansible-lint-6.11.0/test/test_schemas.py --- old/ansible-lint-6.10.2/test/test_schemas.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_schemas.py 2023-01-17 20:57:11.000000000 +0100 @@ -1,5 +1,9 @@ """Test schemas modules.""" +import logging +import urllib from time import sleep +from typing import Any +from unittest.mock import DEFAULT, MagicMock, patch import pytest @@ -42,3 +46,32 @@ assert len(matches) == len(expected_tags) for i, match in enumerate(matches): assert match.tag == expected_tags[i] + + +def urlopen_side_effect(*_args: Any, **kwargs: Any) -> DEFAULT: + """Actual test that timeout parameter is defined.""" + assert "timeout" in kwargs + assert kwargs["timeout"] > 0 + return DEFAULT + + +@patch("urllib.request") +def test_requests_uses_timeout(mock_request: MagicMock) -> None: + """Test that schema refresh uses timeout.""" + mock_request.urlopen.side_effect = urlopen_side_effect + refresh_schemas(min_age_seconds=0) + mock_request.urlopen.assert_called() + + +@patch("urllib.request") +def test_request_timeouterror_handling( + mock_request: MagicMock, caplog: pytest.LogCaptureFixture +) -> None: + """Test that schema refresh can handle time out errors.""" + error_msg = "Simulating handshake operation time out." + mock_request.urlopen.side_effect = urllib.error.URLError(TimeoutError(error_msg)) + with caplog.at_level(logging.DEBUG): + assert refresh_schemas(min_age_seconds=0) == 1 + mock_request.urlopen.assert_called() + assert "Skipped schema refresh due to unexpected exception: " in caplog.text + assert error_msg in caplog.text diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_skiputils.py new/ansible-lint-6.11.0/test/test_skiputils.py --- old/ansible-lint-6.10.2/test/test_skiputils.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_skiputils.py 2023-01-17 20:57:11.000000000 +0100 @@ -189,31 +189,31 @@ ("task", "expected"), ( pytest.param( - dict( - name="ensure apache is at the latest version", - yum={"name": "httpd", "state": "latest"}, - ), + { + "name": "ensure apache is at the latest version", + "yum": {"name": "httpd", "state": "latest"}, + }, False, ), pytest.param( - dict( - name="Attempt and graceful roll back", - block=[ + { + "name": "Attempt and graceful roll back", + "block": [ {"name": "Force a failure", "ansible.builtin.command": "/bin/false"} ], - rescue=[ + "rescue": [ { "name": "Force a failure in middle of recovery!", "ansible.builtin.command": "/bin/false", } ], - always=[ + "always": [ { "name": "Always do this", "ansible.builtin.debug": {"msg": "This always executes"}, } ], - ), + }, True, ), ), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/test/test_utils.py new/ansible-lint-6.11.0/test/test_utils.py --- old/ansible-lint-6.10.2/test/test_utils.py 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/test/test_utils.py 2023-01-17 20:57:11.000000000 +0100 @@ -83,8 +83,8 @@ ("reference_form", "alternate_forms"), ( pytest.param( - dict(name="hello", action="command chdir=abc echo hello world"), - (dict(name="hello", command="chdir=abc echo hello world"),), + {"name": "hello", "action": "command chdir=abc echo hello world"}, + ({"name": "hello", "command": "chdir=abc echo hello world"},), id="simple_command", ), pytest.param( @@ -113,12 +113,13 @@ def test_normalize_complex_command() -> None: """Test that tasks specified differently are normalized same way.""" - task1 = dict( - name="hello", action={"module": "pip", "name": "df", "editable": "false"} - ) - task2 = dict(name="hello", pip={"name": "df", "editable": "false"}) - task3 = dict(name="hello", pip="name=df editable=false") - task4 = dict(name="hello", action="pip name=df editable=false") + task1 = { + "name": "hello", + "action": {"module": "pip", "name": "df", "editable": "false"}, + } + task2 = {"name": "hello", "pip": {"name": "df", "editable": "false"}} + task3 = {"name": "hello", "pip": "name=df editable=false"} + task4 = {"name": "hello", "action": "pip name=df editable=false"} assert utils.normalize_task(task1, "tasks.yml") == utils.normalize_task( task2, "tasks.yml" ) @@ -134,47 +135,47 @@ ("task", "expected_form"), ( pytest.param( - dict( - name="ensure apache is at the latest version", - yum={"name": "httpd", "state": "latest"}, - ), - dict( - delegate_to=Sentinel, - name="ensure apache is at the latest version", - action={ + { + "name": "ensure apache is at the latest version", + "yum": {"name": "httpd", "state": "latest"}, + }, + { + "delegate_to": Sentinel, + "name": "ensure apache is at the latest version", + "action": { "__ansible_module__": "yum", "__ansible_module_original__": "yum", "__ansible_arguments__": [], "name": "httpd", "state": "latest", }, - ), + }, ), pytest.param( - dict( - name="Attempt and graceful roll back", - block=[ + { + "name": "Attempt and graceful roll back", + "block": [ { "name": "Install httpd and memcached", "ansible.builtin.yum": ["httpd", "memcached"], "state": "present", } ], - ), - dict( - name="Attempt and graceful roll back", - block=[ + }, + { + "name": "Attempt and graceful roll back", + "block": [ { "name": "Install httpd and memcached", "ansible.builtin.yum": ["httpd", "memcached"], "state": "present", } ], - action={ + "action": { "__ansible_module__": "block/always/rescue", "__ansible_module_original__": "block/always/rescue", }, - ), + }, ), ), ) @@ -241,7 +242,7 @@ result = utils.template( basedir="/base/dir", value=template, - variables=dict(playbook_dir="/a/b/c"), + variables={"playbook_dir": "/a/b/c"}, fail_on_error=False, ) assert result == output @@ -249,7 +250,7 @@ def test_task_to_str_unicode() -> None: """Ensure that extracting messages from tasks preserves Unicode.""" - task = dict(fail=dict(msg="unicode é ô à ")) + task = {"fail": {"msg": "unicode é ô à "}} result = utils.task_to_str(utils.normalize_task(task, "filename.yml")) assert result == "fail msg=unicode é ô à " @@ -288,11 +289,8 @@ out, err = capfd.readouterr() # Confirmation that it runs in auto-detect mode - assert ( - "Discovered files to lint using: git ls-files --cached --others --exclude-standard -z" - in err - ) - assert "Excluded removed files using: git ls-files --deleted -z" in err + assert "Discovered files to lint using: git" in err + assert "Excluded removed files using: git" in err # An expected rule match from our examples assert ( "examples/playbooks/empty_playbook.yml:1:1: " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/tools/install-reqs.sh new/ansible-lint-6.11.0/tools/install-reqs.sh --- old/ansible-lint-6.10.2/tools/install-reqs.sh 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/tools/install-reqs.sh 2023-01-17 20:57:11.000000000 +0100 @@ -1,22 +1,26 @@ #!/bin/bash set -euo pipefail -pushd examples/playbooks/collections +pushd examples/playbooks/collections >/dev/null MISSING=() +export ANSIBLE_COLLECTIONS_PATH=. for COLLECTION in ansible.posix community.general community.molecule; do - FILE=${COLLECTION//\./-} - if test -n "$(find . -maxdepth 1 -name '$FILE*' -print -quit)" + COL_NAME=${COLLECTION//\./-} + FILENAME=$(find . -maxdepth 1 -name "$COL_NAME*" -print -quit) + if test -n "$FILENAME" then - echo "Already cached $FILE" + echo "Already cached $COL_NAME as $FILENAME" else MISSING+=("${COLLECTION}") fi if [ ${#MISSING[@]} -ne 0 ]; then ansible-galaxy collection download -p . -v "${MISSING[@]}" + # Downloader will break our requirements.yml on download + git checkout -- requirements.yml fi done echo "Install requirements.yml ..." cat requirements.yml ansible-galaxy collection install -r requirements.yml -p . -popd +popd >/dev/null diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ansible-lint-6.10.2/tox.ini new/ansible-lint-6.11.0/tox.ini --- old/ansible-lint-6.10.2/tox.ini 2023-01-01 17:48:52.000000000 +0100 +++ new/ansible-lint-6.11.0/tox.ini 2023-01-17 20:57:11.000000000 +0100 @@ -31,6 +31,8 @@ --durations=10 \ -m "not eco" \ } + sh -c "coverage combine -a -q --data-file=.coverage .tox/.coverage.*" + passenv = CURL_CA_BUNDLE # https proxies, https://github.com/tox-dev/tox/issues/1437 FORCE_COLOR @@ -44,6 +46,7 @@ REQUESTS_CA_BUNDLE # https proxies SETUPTOOLS_SCM_DEBUG SSL_CERT_FILE # https proxies + SSH_AUTH_SOCK # may be needed by git when running with progressive LANG LC_* # recreate = True @@ -221,11 +224,15 @@ [testenv:coverage] description = Combines and displays coverage results +skip_install = true +usedevelop = false +setenv = + COVERAGE_PROCESS_START={toxinidir}/pyproject.toml commands = - sh -c "coverage combine -q .tox/.coverage.*" - # needed by codecov github actions: - coverage xml + python -m coverage --version + # needed by codecov github actions, also ignored result to reach report one. + python -m coverage xml --fail-under=0 # just for humans running it: coverage report deps = - coverage[toml] + coverage[toml]>=7.0.5