Bug#1109741: unblock: ansible-lint/25.6.1-1
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: ansible-lint@packages.debian.org, debian@rocketjump.eu
Control: affects -1 + src:ansible-lint
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package ansible-lint
[ Reason ]
This package fixes the autopkgtests when running against ansible-core >=
2.19.0~rc2-1, as the latter added a handful of deprecation warnings which are
fatal in the test suite.
Unfortunately Gregory did not coordinate this upload with me, which bumps the
upstream version from 25.2.1 to 25.6.1 (upstream does not follow semantic
versioning, those are mostly bugfixes). I would have preferred a more targeted
fix.
A large part (> 80%) of the debdiff are upstream bumps of the package
requirements (irrelevant to Debian), and renaming of playbook tasks to make them
unique in the testsuite.
If you believe the changes are too large this late in the freeze, I'm willing to
provide a more targeted fix via t-p-u.
[ Impact ]
This unblock is needed to make the autopkgtests pass when run against
ansible-core >= 2.19.0~rc2-1.
[ Tests ]
There is good autopkgtest coverage for this package.
[ Risks ]
It's a bump to a later upstream, which has good test coverage. ansible-lint is
also a leaf package, so no other packages are directly affected.
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
[ Other info ]
%
unblock ansible-lint/25.6.1-1
diff -Nru ansible-lint-25.2.1/collections/ansible_collections/local/testcollection/playbooks/playbook_bug4452.yml ansible-lint-25.6.1/collections/ansible_collections/local/testcollection/playbooks/playbook_bug4452.yml
--- ansible-lint-25.2.1/collections/ansible_collections/local/testcollection/playbooks/playbook_bug4452.yml 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/collections/ansible_collections/local/testcollection/playbooks/playbook_bug4452.yml 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,12 @@
+---
+- name: Role for 4452
+ hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: Import role in subdir
+ ansible.builtin.import_role:
+ name: local.testcollection.subdirectory.bug4452
+
+ - name: Import role in 3rd level subdir
+ ansible.builtin.import_role:
+ name: local.testcollection.level1.level2.role_level3
diff -Nru ansible-lint-25.2.1/collections/ansible_collections/local/testcollection/roles/level1/level2/role_level3/tasks/main.yml ansible-lint-25.6.1/collections/ansible_collections/local/testcollection/roles/level1/level2/role_level3/tasks/main.yml
--- ansible-lint-25.2.1/collections/ansible_collections/local/testcollection/roles/level1/level2/role_level3/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/collections/ansible_collections/local/testcollection/roles/level1/level2/role_level3/tasks/main.yml 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,4 @@
+---
+- name: Debug
+ ansible.builtin.debug:
+ msg: "Role in l3 subdir"
diff -Nru ansible-lint-25.2.1/collections/ansible_collections/local/testcollection/roles/subdirectory/bug4452/tasks/main.yml ansible-lint-25.6.1/collections/ansible_collections/local/testcollection/roles/subdirectory/bug4452/tasks/main.yml
--- ansible-lint-25.2.1/collections/ansible_collections/local/testcollection/roles/subdirectory/bug4452/tasks/main.yml 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/collections/ansible_collections/local/testcollection/roles/subdirectory/bug4452/tasks/main.yml 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,4 @@
+---
+- name: Debug
+ ansible.builtin.debug:
+ msg: "Role in subdir"
diff -Nru ansible-lint-25.2.1/.config/constraints.txt ansible-lint-25.6.1/.config/constraints.txt
--- ansible-lint-25.2.1/.config/constraints.txt 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.config/constraints.txt 2025-06-19 09:30:13.000000000 +0200
@@ -1,33 +1,33 @@
# This file was autogenerated by uv via the following command:
# tox run -e deps
-ansible-compat==25.1.5 # via ansible-lint (pyproject.toml)
-astroid==3.3.9 # via pylint
+ansible-compat==25.5.0 # via ansible-lint (pyproject.toml)
+astroid==3.3.10 # via pylint
asttokens==3.0.0 # via stack-data
attrs==25.3.0 # via jsonschema, referencing
babel==2.17.0 # via mkdocs-material
backrefs==5.8 # via mkdocs-material
-beautifulsoup4==4.13.3 # via linkchecker, mkdocs-htmlproofer-plugin
+beautifulsoup4==4.13.4 # via linkchecker, mkdocs-htmlproofer-plugin
bindep==2.13.0 # via tox-extra
black==25.1.0 # via ansible-lint (pyproject.toml)
-boolean-py==4.0 # via license-expression
+boolean-py==5.0 # via license-expression
bracex==2.5.post1 # via wcmatch
-cachetools==5.5.2 # via tox
+cachetools==6.0.0 # via tox
cairocffi==1.7.1 # via cairosvg
cairosvg==2.7.1 # via mkdocs-ansible
-certifi==2025.1.31 # via requests
+certifi==2025.6.15 # via requests
cffi==1.17.1 # via cairocffi, cryptography
chardet==5.2.0 # via tox
-charset-normalizer==3.4.1 # via requests
-click==8.1.8 # via black, mkdocs
+charset-normalizer==3.4.2 # via requests
+click==8.2.1 # via black, mkdocs
colorama==0.4.6 # via griffe, mkdocs-material, tox
-coverage==7.7.1 # via coverage-enable-subprocess, ansible-lint (pyproject.toml)
+coverage==7.9.1 # via coverage-enable-subprocess, ansible-lint (pyproject.toml)
coverage-enable-subprocess==1.0 # via ansible-lint (pyproject.toml)
-cryptography==44.0.2 # via ansible-core
+cryptography==45.0.4 # via ansible-core
csscompressor==0.9.5 # via mkdocs-minify-plugin
cssselect2==0.8.0 # via cairosvg
decorator==5.2.1 # via ipdb, ipython
defusedxml==0.7.1 # via cairosvg
-dill==0.3.9 # via pylint
+dill==0.4.0 # via pylint
distlib==0.3.9 # via virtualenv
distro==1.9.0 # via bindep
dnspython==2.7.0 # via linkchecker
@@ -37,105 +37,102 @@
ghp-import==2.1.0 # via mkdocs
gitdb==4.0.12 # via gitpython
gitpython==3.1.44 # via tox-extra
-griffe==1.7.1 # via mkdocstrings-python
+griffe==1.7.3 # via mkdocstrings-python
hjson==3.1.0 # via mkdocs-macros-plugin, super-collections
htmlmin2==0.1.13 # via mkdocs-minify-plugin
idna==3.10 # via requests
-importlib-metadata==8.6.1 # via ansible-lint (pyproject.toml)
+importlib-metadata==8.7.0 # via ansible-lint (pyproject.toml)
iniconfig==2.1.0 # via pytest
ipdb==0.13.13 # via ansible-lint (pyproject.toml)
-ipython==8.34.0 # via ipdb, ansible-lint (pyproject.toml)
+ipython==8.36.0 # via ipdb, ansible-lint (pyproject.toml)
isort==6.0.1 # via pylint
jedi==0.19.2 # via ipython
jinja2==3.1.6 # via ansible-core, mkdocs, mkdocs-macros-plugin, mkdocs-material, mkdocstrings
jmespath==1.0.1 # via ansible-lint (pyproject.toml)
jsmin==3.0.1 # via mkdocs-minify-plugin
-jsonschema==4.23.0 # via ansible-compat, ansible-lint (pyproject.toml)
-jsonschema-specifications==2024.10.1 # via jsonschema
+jsonschema==4.24.0 # via ansible-compat, ansible-lint (pyproject.toml)
+jsonschema-specifications==2025.4.1 # via jsonschema
license-expression==30.4.1 # via ansible-lint (pyproject.toml)
linkchecker==10.5.0 # via mkdocs-ansible
-markdown==3.7 # via markdown-include, mkdocs, mkdocs-autorefs, mkdocs-htmlproofer-plugin, mkdocs-material, mkdocstrings, pymdown-extensions
+markdown==3.8 # via markdown-include, mkdocs, mkdocs-autorefs, mkdocs-htmlproofer-plugin, mkdocs-material, mkdocstrings, pymdown-extensions
markdown-exec==1.10.3 # via mkdocs-ansible
markdown-include==0.8.1 # via mkdocs-ansible
markupsafe==3.0.2 # via jinja2, mkdocs, mkdocs-autorefs, mkdocstrings
matplotlib-inline==0.1.7 # via ipython
mccabe==0.7.0 # via pylint
mergedeep==1.3.4 # via mkdocs, mkdocs-get-deps
-mkdocs==1.6.1 # via mkdocs-ansible, mkdocs-autorefs, mkdocs-gen-files, mkdocs-htmlproofer-plugin, mkdocs-macros-plugin, mkdocs-material, mkdocs-minify-plugin, mkdocs-monorepo-plugin, mkdocstrings
-mkdocs-ansible==25.2.0 # via ansible-lint (pyproject.toml)
-mkdocs-autorefs==1.4.1 # via mkdocstrings, mkdocstrings-python
+mkdocs==1.6.1 # via mkdocs-ansible, mkdocs-autorefs, mkdocs-gen-files, mkdocs-htmlproofer-plugin, mkdocs-macros-plugin, mkdocs-material, mkdocs-minify-plugin, mkdocstrings
+mkdocs-ansible==25.5.0 # via ansible-lint (pyproject.toml)
+mkdocs-autorefs==1.4.2 # via mkdocstrings, mkdocstrings-python
mkdocs-gen-files==0.5.0 # via mkdocs-ansible
mkdocs-get-deps==0.2.0 # via mkdocs
mkdocs-htmlproofer-plugin==1.3.0 # via mkdocs-ansible
mkdocs-macros-plugin==1.3.7 # via mkdocs-ansible
-mkdocs-material==9.6.9 # via mkdocs-ansible
+mkdocs-material==9.6.14 # via mkdocs-ansible
mkdocs-material-extensions==1.3.1 # via mkdocs-ansible, mkdocs-material
mkdocs-minify-plugin==0.8.0 # via mkdocs-ansible
-mkdocs-monorepo-plugin==1.1.0 # via mkdocs-ansible
-mkdocstrings==0.29.0 # via mkdocs-ansible, mkdocstrings-python
-mkdocstrings-python==1.16.8 # via mkdocs-ansible
-mypy==1.15.0 # via ansible-lint (pyproject.toml)
-mypy-extensions==1.0.0 # via black, mypy
+mkdocstrings==0.29.1 # via mkdocs-ansible, mkdocstrings-python
+mkdocstrings-python==1.16.12 # via mkdocs-ansible
+mypy==1.16.0 # via ansible-lint (pyproject.toml)
+mypy-extensions==1.1.0 # via black, mypy
netaddr==1.3.0 # via ansible-lint (pyproject.toml)
-packaging==24.2 # via ansible-compat, ansible-core, bindep, black, mkdocs, mkdocs-macros-plugin, pyproject-api, pytest, pytest-sugar, tox, tox-extra, tox-uv, ansible-lint (pyproject.toml)
+packaging==25.0 # via ansible-compat, ansible-core, bindep, black, mkdocs, mkdocs-macros-plugin, pyproject-api, pytest, pytest-sugar, tox, tox-extra, tox-uv, ansible-lint (pyproject.toml)
paginate==0.5.7 # via mkdocs-material
parsley==1.3 # via bindep
parso==0.8.4 # via jedi
-pathspec==0.12.1 # via black, mkdocs, mkdocs-macros-plugin, yamllint, ansible-lint (pyproject.toml)
+pathspec==0.12.1 # via black, mkdocs, mkdocs-macros-plugin, mypy, yamllint, ansible-lint (pyproject.toml)
pbr==6.1.1 # via bindep
pexpect==4.9.0 # via ipython
-pillow==11.1.0 # via cairosvg, mkdocs-ansible
-platformdirs==4.3.7 # via black, mkdocs-get-deps, pylint, tox, virtualenv
-pluggy==1.5.0 # via pytest, tox
-prompt-toolkit==3.0.50 # via ipython
+pillow==11.2.1 # via cairosvg, mkdocs-ansible
+platformdirs==4.3.8 # via black, mkdocs-get-deps, pylint, tox, virtualenv
+pluggy==1.6.0 # via pytest, tox
+prompt-toolkit==3.0.51 # via ipython
psutil==7.0.0 # via pytest-xdist, ansible-lint (pyproject.toml)
ptyprocess==0.7.0 # via pexpect
pure-eval==0.2.3 # via stack-data
pycparser==2.22 # via cffi
-pygments==2.19.1 # via ipython, mkdocs-material
-pylint==3.3.6 # via ansible-lint (pyproject.toml)
-pymdown-extensions==10.14.3 # via markdown-exec, mkdocs-ansible, mkdocs-material, mkdocstrings
-pyproject-api==1.9.0 # via tox
-pytest==8.3.5 # via pytest-instafail, pytest-mock, pytest-plus, pytest-sugar, pytest-xdist, ansible-lint (pyproject.toml)
+pygments==2.19.1 # via ipython, mkdocs-material, pytest
+pylint==3.3.7 # via ansible-lint (pyproject.toml)
+pymdown-extensions==10.15 # via markdown-exec, mkdocs-ansible, mkdocs-material, mkdocstrings
+pyproject-api==1.9.1 # via tox
+pytest==8.4.0 # via pytest-instafail, pytest-mock, pytest-plus, pytest-sugar, pytest-xdist, ansible-lint (pyproject.toml)
pytest-instafail==0.5.0 # via ansible-lint (pyproject.toml)
-pytest-mock==3.14.0 # via ansible-lint (pyproject.toml)
+pytest-mock==3.14.1 # via ansible-lint (pyproject.toml)
pytest-plus==0.8.1 # via ansible-lint (pyproject.toml)
pytest-sugar==1.0.0 # via ansible-lint (pyproject.toml)
-pytest-xdist==3.6.1 # via ansible-lint (pyproject.toml)
+pytest-xdist==3.7.0 # via ansible-lint (pyproject.toml)
python-dateutil==2.9.0.post0 # via ghp-import, mkdocs-macros-plugin
-python-slugify==8.0.4 # via mkdocs-monorepo-plugin
pyyaml==6.0.2 # via ansible-compat, ansible-core, mkdocs, mkdocs-get-deps, mkdocs-macros-plugin, pymdown-extensions, pyyaml-env-tag, yamllint, ansible-lint (pyproject.toml)
-pyyaml-env-tag==0.1 # via mkdocs
+pyyaml-env-tag==1.1 # via mkdocs
referencing==0.36.2 # via jsonschema, jsonschema-specifications, types-jsonschema, ansible-lint (pyproject.toml)
-requests==2.32.3 # via linkchecker, mkdocs-htmlproofer-plugin, mkdocs-material
-rpds-py==0.24.0 # via jsonschema, referencing
-ruamel-yaml==0.18.10 # via ansible-lint (pyproject.toml)
-setproctitle==1.3.5 # via pytest-xdist
-setuptools==78.1.0 # via pbr
+requests==2.32.4 # via linkchecker, mkdocs-htmlproofer-plugin, mkdocs-material
+rpds-py==0.25.1 # via jsonschema, referencing
+ruamel-yaml==0.18.11 # via ansible-lint (pyproject.toml)
+setproctitle==1.3.6 # via pytest-xdist
+setuptools==80.9.0 # via pbr
six==1.17.0 # via python-dateutil
smmap==5.0.2 # via gitdb
-soupsieve==2.6 # via beautifulsoup4
+soupsieve==2.7 # via beautifulsoup4
stack-data==0.6.3 # via ipython
subprocess-tee==0.4.2 # via ansible-compat, ansible-lint (pyproject.toml)
super-collections==0.5.3 # via mkdocs-macros-plugin
-termcolor==2.5.0 # via mkdocs-macros-plugin, pytest-sugar
-text-unidecode==1.3 # via python-slugify
+termcolor==3.1.0 # via mkdocs-macros-plugin, pytest-sugar
tinycss2==1.4.0 # via cairosvg, cssselect2
-tomlkit==0.13.2 # via pylint
-tox==4.25.0 # via tox-extra, tox-uv, ansible-lint (pyproject.toml)
+tomlkit==0.13.3 # via pylint
+tox==4.26.0 # via tox-extra, tox-uv, ansible-lint (pyproject.toml)
tox-extra==2.1.0 # via ansible-lint (pyproject.toml)
-tox-uv==1.25.0 # via tox-extra, ansible-lint (pyproject.toml)
+tox-uv==1.26.0 # via tox-extra, ansible-lint (pyproject.toml)
traitlets==5.14.3 # via ipython, matplotlib-inline
-types-jsonschema==4.23.0.20241208 # via ansible-lint (pyproject.toml)
-types-pyyaml==6.0.12.20250326 # via ansible-lint (pyproject.toml)
-urllib3==2.3.0 # via requests
-virtualenv==20.29.3 # via tox
+types-jsonschema==4.24.0.20250528 # via ansible-lint (pyproject.toml)
+types-pyyaml==6.0.12.20250516 # via ansible-lint (pyproject.toml)
+urllib3==2.4.0 # via requests
+virtualenv==20.31.2 # via tox
watchdog==6.0.0 # via mkdocs
wcmatch==10.0 # via ansible-lint (pyproject.toml)
wcwidth==0.2.13 # via prompt-toolkit
webencodings==0.5.1 # via cssselect2, tinycss2
-yamllint==1.37.0 # via ansible-lint (pyproject.toml)
-zipp==3.21.0 # via importlib-metadata
+yamllint==1.37.1 # via ansible-lint (pyproject.toml)
+zipp==3.23.0 # via importlib-metadata
# The following packages were excluded from the output:
# ansible-core
diff -Nru ansible-lint-25.2.1/.config/dictionary.txt ansible-lint-25.6.1/.config/dictionary.txt
--- ansible-lint-25.2.1/.config/dictionary.txt 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.config/dictionary.txt 2025-06-19 09:30:13.000000000 +0200
@@ -17,7 +17,6 @@
PYTHONBREAKPOINT
PYTHONIOENCODING
PYTHONPYCACHEPREFIX
-REQPASS
RULEDIRS
RUNLEVEL
Renderable
diff -Nru ansible-lint-25.2.1/.config/requirements-docs.in ansible-lint-25.6.1/.config/requirements-docs.in
--- ansible-lint-25.2.1/.config/requirements-docs.in 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.config/requirements-docs.in 2025-06-19 09:30:13.000000000 +0200
@@ -1 +1 @@
-mkdocs-ansible>=24.12.0 # do not use lock extra because it would break dependabot updates
+mkdocs-ansible>=25.5.0 # do not use lock extra because it would break dependabot updates
diff -Nru ansible-lint-25.2.1/.config/requirements.in ansible-lint-25.6.1/.config/requirements.in
--- ansible-lint-25.2.1/.config/requirements.in 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.config/requirements.in 2025-06-19 09:30:13.000000000 +0200
@@ -9,7 +9,7 @@
packaging>=22.0 # Apache-2.0,BSD-2-Clause
pathspec>=0.10.3 # Mozilla Public License 2.0 (MPL 2.0)
pyyaml>=6.0.2 # MIT (compilation probles with older versions)
-ruamel.yaml>=0.18.5,!=0.18.7,!=0.18.8 # MIT
+ruamel.yaml>=0.18.11 # MIT (https://sourceforge.net/p/ruamel-yaml/tickets/545/)
referencing>=0.36.2 # MIT, https://github.com/python-jsonschema/referencing/issues/216
subprocess-tee>=0.4.1 # MIT, used by ansible-compat
yamllint >= 1.34.0 # GPLv3
diff -Nru ansible-lint-25.2.1/.config/requirements-lock.txt ansible-lint-25.6.1/.config/requirements-lock.txt
--- ansible-lint-25.2.1/.config/requirements-lock.txt 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.config/requirements-lock.txt 2025-06-19 09:30:13.000000000 +0200
@@ -1,31 +1,31 @@
# This file was autogenerated by uv via the following command:
# tox run -e deps
-ansible-compat==25.1.5 # via ansible-lint (pyproject.toml)
+ansible-compat==25.5.0 # via ansible-lint (pyproject.toml)
attrs==25.3.0 # via jsonschema, referencing
black==25.1.0 # via ansible-lint (pyproject.toml)
bracex==2.5.post1 # via wcmatch
cffi==1.17.1 # via cryptography
-click==8.1.8 # via black
-cryptography==44.0.2 # via ansible-core
+click==8.2.1 # via black
+cryptography==45.0.4 # via ansible-core
filelock==3.18.0 # via ansible-lint (pyproject.toml)
-importlib-metadata==8.6.1 # via ansible-lint (pyproject.toml)
+importlib-metadata==8.7.0 # via ansible-lint (pyproject.toml)
jinja2==3.1.6 # via ansible-core
-jsonschema==4.23.0 # via ansible-compat, ansible-lint (pyproject.toml)
-jsonschema-specifications==2024.10.1 # via jsonschema
+jsonschema==4.24.0 # via ansible-compat, ansible-lint (pyproject.toml)
+jsonschema-specifications==2025.4.1 # via jsonschema
markupsafe==3.0.2 # via jinja2
-mypy-extensions==1.0.0 # via black
-packaging==24.2 # via ansible-compat, ansible-core, black, ansible-lint (pyproject.toml)
+mypy-extensions==1.1.0 # via black
+packaging==25.0 # via ansible-compat, ansible-core, black, ansible-lint (pyproject.toml)
pathspec==0.12.1 # via black, yamllint, ansible-lint (pyproject.toml)
-platformdirs==4.3.7 # via black
+platformdirs==4.3.8 # via black
pycparser==2.22 # via cffi
pyyaml==6.0.2 # via ansible-compat, ansible-core, yamllint, ansible-lint (pyproject.toml)
referencing==0.36.2 # via jsonschema, jsonschema-specifications, ansible-lint (pyproject.toml)
-rpds-py==0.24.0 # via jsonschema, referencing
-ruamel-yaml==0.18.10 # via ansible-lint (pyproject.toml)
+rpds-py==0.25.1 # via jsonschema, referencing
+ruamel-yaml==0.18.11 # via ansible-lint (pyproject.toml)
subprocess-tee==0.4.2 # via ansible-compat, ansible-lint (pyproject.toml)
wcmatch==10.0 # via ansible-lint (pyproject.toml)
-yamllint==1.37.0 # via ansible-lint (pyproject.toml)
-zipp==3.21.0 # via importlib-metadata
+yamllint==1.37.1 # via ansible-lint (pyproject.toml)
+zipp==3.23.0 # via importlib-metadata
# The following packages were excluded from the output:
# ansible-core
diff -Nru ansible-lint-25.2.1/.config/requirements-test.in ansible-lint-25.6.1/.config/requirements-test.in
--- ansible-lint-25.2.1/.config/requirements-test.in 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.config/requirements-test.in 2025-06-19 09:30:13.000000000 +0200
@@ -13,11 +13,11 @@
pytest >= 7.2.2
pytest-instafail >= 0.5.0 # only for local development, via PYTEST_ADDOPTS=-edit
pytest-mock
-pytest-plus >= 0.6 # for PYTEST_REQPASS
+pytest-plus >= 0.6
pytest-sugar # shows failures immediately, even with xdist
pytest-xdist[psutil,setproctitle] >= 2.1.0
ruamel-yaml-clib # needed for mypy
-ruamel.yaml>=0.17.31
+ruamel.yaml>=0.18.11
tox >= 4.0.0
tox-extra>=2.1
tox-uv>=1.25
diff -Nru ansible-lint-25.2.1/conftest.py ansible-lint-25.6.1/conftest.py
--- ansible-lint-25.2.1/conftest.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/conftest.py 2025-06-19 09:30:13.000000000 +0200
@@ -39,7 +39,7 @@
# we need to be sure that we have the requirements installed as some tests
# might depend on these. This approach is compatible with GHA caching.
try:
- subprocess.check_output( # noqa: S603
+ subprocess.check_output(
["./tools/install-reqs.sh"],
stderr=subprocess.PIPE,
text=True,
diff -Nru ansible-lint-25.2.1/debian/changelog ansible-lint-25.6.1/debian/changelog
--- ansible-lint-25.2.1/debian/changelog 2025-05-10 21:04:00.000000000 +0200
+++ ansible-lint-25.6.1/debian/changelog 2025-07-11 10:31:16.000000000 +0200
@@ -1,3 +1,14 @@
+ansible-lint (25.6.1-1) unstable; urgency=medium
+
+ * New upstream version 25.6.1
+ * Minor patch in deb-testing.patch
+ * Fix remove_importlib_metadata.patch
+ * Add disable-test_ro_venv.patch
+ * Add partially-disable-test_normalize_complex_command.patch
+ because Ansible 2.19 emits a deprecated warning
+
+ -- Gregory Colpart <reg@debian.org> Fri, 11 Jul 2025 10:31:16 +0200
+
ansible-lint (25.2.1-3) unstable; urgency=medium
* Team upload.
diff -Nru ansible-lint-25.2.1/debian/patches/deb-testing.patch ansible-lint-25.6.1/debian/patches/deb-testing.patch
--- ansible-lint-25.2.1/debian/patches/deb-testing.patch 2025-05-10 21:04:00.000000000 +0200
+++ ansible-lint-25.6.1/debian/patches/deb-testing.patch 2025-07-11 10:31:16.000000000 +0200
@@ -35,7 +35,7 @@
- # we need to be sure that we have the requirements installed as some tests
- # might depend on these. This approach is compatible with GHA caching.
- try:
-- subprocess.check_output( # noqa: S603
+- subprocess.check_output(
- ["./tools/install-reqs.sh"],
- stderr=subprocess.PIPE,
- text=True,
diff -Nru ansible-lint-25.2.1/debian/patches/disable-test_ro_venv.patch ansible-lint-25.6.1/debian/patches/disable-test_ro_venv.patch
--- ansible-lint-25.2.1/debian/patches/disable-test_ro_venv.patch 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/debian/patches/disable-test_ro_venv.patch 2025-07-11 10:31:16.000000000 +0200
@@ -0,0 +1,66 @@
+From: Gregory Colpart <reg@debian.org>
+Date: Sat, 12 Jul 2025 21:37:13 +0200
+Subject: avoid "/bin/sh: 1: python: not found" when building
+
+---
+ test/test_main.py | 50 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 25 insertions(+), 25 deletions(-)
+
+diff --git a/test/test_main.py b/test/test_main.py
+index 9e0dcd7..cec9c7a 100644
+--- a/test/test_main.py
++++ b/test/test_main.py
+@@ -183,28 +183,28 @@ def test_list_tags() -> None:
+ assert isinstance(item, str)
+
+
+-def test_ro_venv() -> None:
+- """Tests behavior when the virtual environment is read-only."""
+- tox_work_dir = os.environ.get("TOX_WORK_DIR", ".tox")
+- venv_path = f"{tox_work_dir}/ro"
+- commands = [
+- f"mkdir -p {venv_path}",
+- f"chmod -R a+w {venv_path}",
+- f"rm -rf {venv_path}",
+- f"python -m venv --symlinks {venv_path}",
+- f"{venv_path}/bin/python -m pip install -q -e .",
+- f"chmod -R a-w {venv_path}",
+- # running with a ro venv and default cwd
+- f"{venv_path}/bin/ansible-lint --version",
+- # running from a read-only cwd:
+- f"cd / && {abspath(venv_path)}/bin/ansible-lint --version", # noqa: PTH100
+- # running with a ro venv and a custom project path in forced non-online mode, so it will need to install requirements
+- f"{venv_path}/bin/ansible-lint -vv --no-offline --project-dir ./examples/reqs_v2/ ./examples/reqs_v2/",
+- ]
+- for cmd in commands:
+- result = subprocess.run(
+- cmd, capture_output=True, shell=True, text=True, check=False
+- )
+- assert result.returncode == 0, (
+- f"Got {result.returncode} running {cmd}\n\tstderr: {result.stderr}\n\tstdout: {result.stdout}"
+- )
++#def test_ro_venv() -> None:
++# """Tests behavior when the virtual environment is read-only."""
++# tox_work_dir = os.environ.get("TOX_WORK_DIR", ".tox")
++# venv_path = f"{tox_work_dir}/ro"
++# commands = [
++# f"mkdir -p {venv_path}",
++# f"chmod -R a+w {venv_path}",
++# f"rm -rf {venv_path}",
++# f"python3 -m venv --symlinks {venv_path}",
++# f"{venv_path}/bin/python -m pip install -q -e .",
++# f"chmod -R a-w {venv_path}",
++# # running with a ro venv and default cwd
++# f"{venv_path}/bin/ansible-lint --version",
++# # running from a read-only cwd:
++# f"cd / && {abspath(venv_path)}/bin/ansible-lint --version", # noqa: PTH100
++# # running with a ro venv and a custom project path in forced non-online mode, so it will need to install requirements
++# f"{venv_path}/bin/ansible-lint -vv --no-offline --project-dir ./examples/reqs_v2/ ./examples/reqs_v2/",
++# ]
++# for cmd in commands:
++# result = subprocess.run(
++# cmd, capture_output=True, shell=True, text=True, check=False
++# )
++# assert result.returncode == 0, (
++# f"Got {result.returncode} running {cmd}\n\tstderr: {result.stderr}\n\tstdout: {result.stdout}"
++# )
diff -Nru ansible-lint-25.2.1/debian/patches/partially-disable-test_normalize_complex_command.patch ansible-lint-25.6.1/debian/patches/partially-disable-test_normalize_complex_command.patch
--- ansible-lint-25.2.1/debian/patches/partially-disable-test_normalize_complex_command.patch 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/debian/patches/partially-disable-test_normalize_complex_command.patch 2025-07-11 10:31:16.000000000 +0200
@@ -0,0 +1,42 @@
+From: Gregory Colpart <gcolpart+git@evolix.fr>
+Date: Sat, 12 Jul 2025 22:54:32 +0200
+Subject: partially disable test_normalize_complex_command
+
+---
+ test/test_utils.py | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/test/test_utils.py b/test/test_utils.py
+index 0dc0bbe..b227dd0 100644
+--- a/test/test_utils.py
++++ b/test/test_utils.py
+@@ -132,13 +132,13 @@ def test_normalize(
+
+ def test_normalize_complex_command() -> None:
+ """Test that tasks specified differently are normalized same way."""
+- task1 = utils.Task(
+- {
+- "name": "hello",
+- "action": {"module": "pip", "name": "df", "editable": "false"},
+- },
+- filename="tasks.yml",
+- )
++ #task1 = utils.Task(
++ # {
++ # "name": "hello",
++ # "action": {"module": "pip", "name": "df", "editable": "false"},
++ # },
++ # filename="tasks.yml",
++ #)
+ task2 = utils.Task(
+ {"name": "hello", "pip": {"name": "df", "editable": "false"}},
+ filename="tasks.yml",
+@@ -151,7 +151,7 @@ def test_normalize_complex_command() -> None:
+ {"name": "hello", "action": "pip name=df editable=false"},
+ filename="tasks.yml",
+ )
+- assert task1._normalize_task() == task2._normalize_task() # noqa: SLF001
++ #assert task1._normalize_task() == task2._normalize_task() # noqa: SLF001
+ assert task2._normalize_task() == task3._normalize_task() # noqa: SLF001
+ assert task3._normalize_task() == task4._normalize_task() # noqa: SLF001
+
diff -Nru ansible-lint-25.2.1/debian/patches/remove_importlib_metadata.patch ansible-lint-25.6.1/debian/patches/remove_importlib_metadata.patch
--- ansible-lint-25.2.1/debian/patches/remove_importlib_metadata.patch 2025-05-10 21:04:00.000000000 +0200
+++ ansible-lint-25.6.1/debian/patches/remove_importlib_metadata.patch 2025-07-11 10:31:16.000000000 +0200
@@ -4,20 +4,20 @@
hjson==3.1.0 # via mkdocs-macros-plugin, super-collections
htmlmin2==0.1.13 # via mkdocs-minify-plugin
idna==3.10 # via requests
--importlib-metadata==8.6.1 # via ansible-lint (pyproject.toml)
+-importlib-metadata==8.7.0 # via ansible-lint (pyproject.toml)
iniconfig==2.1.0 # via pytest
ipdb==0.13.13 # via ansible-lint (pyproject.toml)
- ipython==8.34.0 # via ipdb, ansible-lint (pyproject.toml)
+ ipython==8.36.0 # via ipdb, ansible-lint (pyproject.toml)
--- a/.config/requirements-lock.txt
+++ b/.config/requirements-lock.txt
@@ -8,7 +8,6 @@
- click==8.1.8 # via black
- cryptography==44.0.2 # via ansible-core
+ click==8.2.1 # via black
+ cryptography==45.0.4 # via ansible-core
filelock==3.18.0 # via ansible-lint (pyproject.toml)
--importlib-metadata==8.6.1 # via ansible-lint (pyproject.toml)
+-importlib-metadata==8.7.0 # via ansible-lint (pyproject.toml)
jinja2==3.1.6 # via ansible-core
- jsonschema==4.23.0 # via ansible-compat, ansible-lint (pyproject.toml)
- jsonschema-specifications==2024.10.1 # via jsonschema
+ jsonschema==4.24.0 # via ansible-compat, ansible-lint (pyproject.toml)
+ jsonschema-specifications==2025.4.1 # via jsonschema
--- a/.config/requirements.in
+++ b/.config/requirements.in
@@ -4,7 +4,6 @@
@@ -30,7 +30,7 @@
pathspec>=0.10.3 # Mozilla Public License 2.0 (MPL 2.0)
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
-@@ -165,7 +165,6 @@
+@@ -163,7 +163,6 @@
- black>=22.10.0
- cryptography>=39.0.1
- filelock>=3.12.2
@@ -52,8 +52,8 @@
def __init__(self, name: str = "ansible-lint") -> None:
"""Load linter metadata requirements."""
-- for req_str in importlib_metadata.metadata(name).json["requires_dist"]:
-+ for req_str in importlib.metadata.metadata(name).json["requires_dist"]:
- req = Requirement(req_str)
- if req.name:
- self[req.name] = req.specifier
+- metadata = importlib_metadata.metadata(name)
++ metadata = importlib.metadata.metadata(name)
+ if metadata:
+ for req_str in metadata.json["requires_dist"]:
+ req = Requirement(req_str)
diff -Nru ansible-lint-25.2.1/debian/patches/series ansible-lint-25.6.1/debian/patches/series
--- ansible-lint-25.2.1/debian/patches/series 2025-05-10 21:04:00.000000000 +0200
+++ ansible-lint-25.6.1/debian/patches/series 2025-07-11 10:31:16.000000000 +0200
@@ -2,3 +2,5 @@
deb-testing.patch
remove_disable_lookups_from_templating.patch
remove_importlib_metadata.patch
+disable-test_ro_venv.patch
+partially-disable-test_normalize_complex_command.patch
diff -Nru ansible-lint-25.2.1/docs/configuring.md ansible-lint-25.6.1/docs/configuring.md
--- ansible-lint-25.2.1/docs/configuring.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/docs/configuring.md 2025-06-19 09:30:13.000000000 +0200
@@ -42,7 +42,7 @@
## Ignoring rules for entire files
-Ansible-lint will load skip rules from an `.ansible-lint-ignore` or
+Ansible-lint will load ignore rules from an `.ansible-lint-ignore` or
`.config/ansible-lint-ignore.txt` file that should reside adjacent to the config
file. The file format is very simple, containing the filename and the rule to be
ignored. It also supports comments starting with `#`.
@@ -56,6 +56,15 @@
The file can also be created by adding `--generate-ignore` to the command line.
Keep in mind that this will override any existing file content.
+By default, rules ignored here will raise a non-fatal warning in the
+output. If you add `skip` to the line, the test will be skipped
+(see `skip_list`) and not raise any warning.
+
+```yaml title=".ansible-lint-ignore"
+playbook.yml role-name # raises warning
+playbook2.yml role-name skip # no warning
+```
+
## Pre-commit setup
To use Ansible-lint with the [pre-commit] tool, add the following to the
diff -Nru ansible-lint-25.2.1/docs/installing.md ansible-lint-25.6.1/docs/installing.md
--- ansible-lint-25.2.1/docs/installing.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/docs/installing.md 2025-06-19 09:30:13.000000000 +0200
@@ -35,10 +35,10 @@
related to the installation will be closed and locked.
For a container image, we recommend using
-[creator-ee](https://github.com/ansible/creator-ee/) which includes
-`ansible-dev-tools` (it combines critical Ansible development packages into a
-unified Python package). If you have a use case that the `creator-ee` container
-doesn't satisfy, please contact the team through the
+[community-ansible-dev-tools](https://ansible.readthedocs.io/projects/dev-tools/container/)
+which includes `ansible-dev-tools` (it combines critical Ansible development packages into
+a unified Python package). If you have a use case that the `community-ansible-dev-tools`
+container doesn't satisfy, please contact the team through the
[discussion](https://github.com/ansible/ansible-lint/discussions) forum.
You can also run Ansible-lint on your source code with the
diff -Nru ansible-lint-25.2.1/docs/rules/args.md ansible-lint-25.6.1/docs/rules/args.md
--- ansible-lint-25.2.1/docs/rules/args.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/docs/rules/args.md 2025-06-19 09:30:13.000000000 +0200
@@ -40,6 +40,13 @@
- my_param <= 100
- my_param >= 0
quiet: invalid # <- Value for option `quiet` is invalid.
+
+ - name: Do not use mutually exclusive arguments together
+ ansible.builtin.command:
+ cmd: /bin/echo # <- cmd and argv are mutually exclusive options
+ argv:
+ - Hello
+ when_changed: false
```
## Correct Code
@@ -69,6 +76,18 @@
- my_param <= 100
- my_param >= 0
quiet: True # <- Has correct type value for option `quiet` which is boolean.
+
+ - name: Do not use mutually exclusive arguments together
+ ansible.builtin.command:
+ cmd: "/bin/echo Hello" # <- Does not use `cmd` and `argv`
+ when_changed: false
+
+ - name: Do not use mutually exclusive arguments together alternative
+ ansible.builtin.command:
+ argv: # <- Does not use `cmd` and `argv`
+ - /bin/echo
+ - Hello
+ when_changed: false
```
## Special cases
diff -Nru ansible-lint-25.2.1/docs/rules/name.md ansible-lint-25.6.1/docs/rules/name.md
--- ansible-lint-25.2.1/docs/rules/name.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/docs/rules/name.md 2025-06-19 09:30:13.000000000 +0200
@@ -15,10 +15,15 @@
helps with the identification of tasks inside the source code when they fail.
The use of templating inside `name` keys is discouraged as there are multiple
cases where the rendering of the name template is not possible.
+- `name[unique]` - All task names within a single play should be unique.
If you want to ignore some of the messages above, you can add any of them to the
`skip_list`.
+## name[unique]
+
+This check ensures that every task name is unique within the same play. This includes tasks defined in the `pre_tasks`, `tasks`, `post_tasks`, and `handlers` sections. Having unique names is crucial for reliably using features like `--start-at-task` and makes playbook execution easier to follow and debug.
+
## name[prefix]
This rule applies only to included task files that are not named `main.yml` or
diff -Nru ansible-lint-25.2.1/docs/rules/no-log-password.md ansible-lint-25.6.1/docs/rules/no-log-password.md
--- ansible-lint-25.2.1/docs/rules/no-log-password.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/docs/rules/no-log-password.md 2025-06-19 09:30:13.000000000 +0200
@@ -6,6 +6,14 @@
While most Ansible modules mask sensitive data, using secrets inside a loop can result in those secrets being logged.
Explicitly adding `no_log: true` prevents accidentally exposing secrets.
+This is an opt-in rule.
+You must enable it in your Ansible-lint configuration as follows:
+
+```yaml
+enable_list:
+ - no-log-password
+```
+
## Problematic Code
```yaml
diff -Nru ansible-lint-25.2.1/docs/rules/package-latest.md ansible-lint-25.6.1/docs/rules/package-latest.md
--- ansible-lint-25.2.1/docs/rules/package-latest.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/docs/rules/package-latest.md 2025-06-19 09:30:13.000000000 +0200
@@ -2,7 +2,7 @@
This rule checks that package managers install software in a controlled, safe manner.
-Package manager modules, such as `ansible.builtin.yum`, include a `state` parameter that configures how Ansible installs software.
+Package manager modules, such as `ansible.builtin.dnf`, include a `state` parameter that configures how Ansible installs software.
In production environments, you should set `state` to `present` and specify a target version to ensure that packages are installed to a planned and tested version.
Setting `state` to `latest` not only installs software, it performs an update and installs additional packages.
@@ -17,7 +17,7 @@
hosts: localhost
tasks:
- name: Install Ansible
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: ansible
state: latest # <- Installs the latest package.
@@ -33,7 +33,7 @@
state: latest # <- Installs the latest package.
- name: Install sudo with update_only to false
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: sudo
state: latest
update_only: false # <- Updates and installs packages.
@@ -53,9 +53,9 @@
hosts: localhost
tasks:
- name: Install Ansible
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: ansible-2.12.7.0
- state: present # <- Pins the version to install with yum.
+ state: present # <- Pins the version to install with dnf.
- name: Install Ansible-lint
ansible.builtin.pip:
@@ -70,7 +70,7 @@
state: present # <- Ensures the package is installed.
- name: Update sudo with update_only to true
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: sudo
state: latest
update_only: true # <- Updates but does not install additional packages.
diff -Nru ansible-lint-25.2.1/examples/broken/load-failure-invalid.yml ansible-lint-25.6.1/examples/broken/load-failure-invalid.yml
--- ansible-lint-25.2.1/examples/broken/load-failure-invalid.yml 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/examples/broken/load-failure-invalid.yml 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,5 @@
+---
+- aaa: 1
+ bbb: 2
+ c: 3
+foo: bar
diff -Nru ansible-lint-25.2.1/examples/playbooks/import_role_fqcn.yml ansible-lint-25.6.1/examples/playbooks/import_role_fqcn.yml
--- ansible-lint-25.2.1/examples/playbooks/import_role_fqcn.yml 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/examples/playbooks/import_role_fqcn.yml 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,9 @@
+---
+- name: Roles
+ hosts: localhost
+ roles:
+ - name: local.testcollection.bug4095
+ - name: local.testcollection.subdirectory.bug4452
+
+- name: Import a playbook with role in a subdirectory
+ ansible.builtin.import_playbook: local.testcollection.playbook_bug4452
diff -Nru ansible-lint-25.2.1/examples/playbooks/lots_of_warnings.yml ansible-lint-25.6.1/examples/playbooks/lots_of_warnings.yml
--- ansible-lint-25.2.1/examples/playbooks/lots_of_warnings.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/lots_of_warnings.yml 2025-06-19 09:30:13.000000000 +0200
@@ -6,995 +6,995 @@
- name: Fixture
hosts: webservers
tasks:
- - name: Executing git through command
+ - name: Executing git through command 1
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 2
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 3
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 4
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 5
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 6
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 7
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 8
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 9
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 10
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 11
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 12
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 13
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 14
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 15
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 16
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 17
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 18
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 19
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 20
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 21
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 22
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 23
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 24
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 25
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 26
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 27
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 28
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 29
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 30
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 31
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 32
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 33
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 34
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 35
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 36
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 37
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 38
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 39
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 40
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 41
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 42
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 43
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 44
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 45
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 46
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 47
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 48
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 49
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 50
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 51
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 52
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 53
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 54
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 55
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 56
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 57
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 58
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 59
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 60
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 61
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 62
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 63
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 64
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 65
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 66
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 67
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 68
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 69
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 70
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 71
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 72
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 73
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 74
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 75
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 76
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 77
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 78
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 79
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 80
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 81
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 82
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 83
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 84
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 85
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 86
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 87
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 88
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 89
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 90
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 91
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 92
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 93
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 94
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 95
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 96
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 97
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 98
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 99
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 100
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 101
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 102
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 103
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 104
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 105
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 106
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 107
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 108
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 109
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 110
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 111
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 112
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 113
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 114
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 115
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 116
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 117
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 118
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 119
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 120
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 121
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 122
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 123
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 124
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 125
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 126
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 127
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 128
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 129
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 130
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 131
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 132
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 133
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 134
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 135
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 136
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 137
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 138
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 139
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 140
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 141
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 142
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 143
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 144
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 145
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 146
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 147
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 148
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 149
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 150
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 151
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 152
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 153
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 154
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 155
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 156
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 157
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 158
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 159
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 160
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 161
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 162
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 163
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 164
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 165
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 166
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 167
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 168
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 169
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 170
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 171
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 172
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 173
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 174
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 175
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 176
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 177
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 178
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 179
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 180
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 181
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 182
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 183
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 184
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 185
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 186
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 187
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 188
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 189
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 190
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 191
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 192
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 193
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 194
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 195
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 196
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 197
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 198
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 199
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 200
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 201
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 202
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 203
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 204
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 205
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 206
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 207
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 208
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 209
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 210
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 211
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 212
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 213
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 214
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 215
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 216
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 217
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 218
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 219
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 220
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 221
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 222
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 223
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 224
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 225
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 226
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 227
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 228
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 229
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 230
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 231
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 232
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 233
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 234
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 235
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 236
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 237
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 238
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 239
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 240
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 241
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 242
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 243
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 244
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 245
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 246
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 247
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 248
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 249
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 250
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 251
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 252
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 253
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 254
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 255
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 256
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 257
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 258
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 259
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 260
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 261
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 262
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 263
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 264
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 265
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 266
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 267
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 268
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 269
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 270
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 271
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 272
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 273
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 274
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 275
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 276
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 277
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 278
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 279
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 280
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 281
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 282
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 283
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 284
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 285
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 286
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 287
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 288
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 289
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 290
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 291
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 292
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 293
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 294
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 295
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 296
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 297
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 298
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 299
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 300
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 301
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 302
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 303
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 304
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 305
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 306
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 307
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 308
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 309
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 310
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 311
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 312
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 313
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 314
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 315
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 316
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 317
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 318
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 319
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 320
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 321
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 322
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 323
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 324
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 325
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 326
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 327
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 328
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 329
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 330
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 331
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 332
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 333
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 334
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 335
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 336
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 337
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 338
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 339
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 340
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 341
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 342
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 343
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 344
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 345
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 346
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 347
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 348
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 349
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 350
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 351
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 352
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 353
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 354
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 355
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 356
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 357
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 358
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 359
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 360
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 361
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 362
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 363
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 364
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 365
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 366
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 367
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 368
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 369
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 370
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 371
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 372
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 373
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 374
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 375
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 376
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 377
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 378
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 379
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 380
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 381
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 382
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 383
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 384
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 385
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 386
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 387
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 388
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 389
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 390
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 391
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 392
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 393
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 394
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 395
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 396
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 397
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 398
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 399
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 400
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 401
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 402
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 403
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 404
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 405
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 406
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 407
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 408
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 409
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 410
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 411
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 412
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 413
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 414
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 415
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 416
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 417
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 418
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 419
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 420
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 421
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 422
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 423
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 424
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 425
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 426
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 427
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 428
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 429
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 430
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 431
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 432
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 433
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 434
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 435
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 436
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 437
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 438
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 439
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 440
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 441
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 442
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 443
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 444
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 445
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 446
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 447
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 448
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 449
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 450
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 451
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 452
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 453
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 454
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 455
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 456
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 457
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 458
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 459
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 460
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 461
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 462
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 463
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 464
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 465
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 466
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 467
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 468
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 469
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 470
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 471
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 472
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 473
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 474
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 475
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 476
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 477
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 478
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 479
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 480
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 481
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 482
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 483
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 484
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 485
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 486
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 487
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 488
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 489
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 490
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 491
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 492
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 493
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 494
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 495
action: ansible.builtin.command git clone blah
- - name: Executing git through command
+ - name: Executing git through command 496
action: ansible.builtin.command git clone blah
diff -Nru ansible-lint-25.2.1/examples/playbooks/rule-args-module-fail.yml ansible-lint-25.6.1/examples/playbooks/rule-args-module-fail.yml
--- ansible-lint-25.2.1/examples/playbooks/rule-args-module-fail.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/rule-args-module-fail.yml 2025-06-19 09:30:13.000000000 +0200
@@ -16,7 +16,7 @@
enabled: true
masked: false
- - name: Enable service httpd and ensure it is not masked
+ - name: Enable service httpd and ensure it is not masked 2
# module should produce: 'Unsupported parameters for ansible.builtin.systemd module"
ansible.builtin.systemd:
foo: true
@@ -35,3 +35,11 @@
path: /opt/software/deployment
state: away
mode: "0600"
+
+ - name: Mutually exclusive cmd and argv
+ # module should produce: 'arguments {"cmd", "argv"} are mutually exclusive'
+ ansible.builtin.command:
+ cmd: /bin/echo
+ argv:
+ - Hello
+ changed_when: false
diff -Nru ansible-lint-25.2.1/examples/playbooks/rule-command-instead-of-module-pass.yml ansible-lint-25.6.1/examples/playbooks/rule-command-instead-of-module-pass.yml
--- ansible-lint-25.2.1/examples/playbooks/rule-command-instead-of-module-pass.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/rule-command-instead-of-module-pass.yml 2025-06-19 09:30:13.000000000 +0200
@@ -46,7 +46,7 @@
ansible.builtin.command: yum clean all
changed_when: false
- - name: Clear yum cache
+ - name: Clear yum cache (Empty command)
ansible.builtin.command: ""
changed_when: false
diff -Nru ansible-lint-25.2.1/examples/playbooks/rule_literal_compare_fail.yml ansible-lint-25.6.1/examples/playbooks/rule_literal_compare_fail.yml
--- ansible-lint-25.2.1/examples/playbooks/rule_literal_compare_fail.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/rule_literal_compare_fail.yml 2025-06-19 09:30:13.000000000 +0200
@@ -2,12 +2,12 @@
- name: Fixture for literal-compare
hosts: localhost
tasks:
- - name: Example task # <-- 1st
+ - name: Example task 1 # <-- 1st
ansible.builtin.debug:
msg: test
when: my_var == True
- - name: Example task # <-- 2nd
+ - name: Example task 2 # <-- 2nd
ansible.builtin.debug:
msg: test
when: my_var == false
diff -Nru ansible-lint-25.2.1/examples/playbooks/rule_literal_compare_pass.yml ansible-lint-25.6.1/examples/playbooks/rule_literal_compare_pass.yml
--- ansible-lint-25.2.1/examples/playbooks/rule_literal_compare_pass.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/rule_literal_compare_pass.yml 2025-06-19 09:30:13.000000000 +0200
@@ -2,7 +2,7 @@
- name: Fixture for literal-compare
hosts: localhost
tasks:
- - name: Example task
+ - name: Example task 1
ansible.builtin.debug:
msg: test
when: my_var
@@ -14,12 +14,12 @@
- 1 + 1 == 2
- true
- - name: Example task
+ - name: Example task 2
ansible.builtin.debug:
msg: test
when: not my_var
- - name: Example task
+ - name: Example task 3
ansible.builtin.debug:
msg: test
when: my_var not None
diff -Nru ansible-lint-25.2.1/examples/playbooks/rule-no-tabs.yml ansible-lint-25.6.1/examples/playbooks/rule-no-tabs.yml
--- ansible-lint-25.2.1/examples/playbooks/rule-no-tabs.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/rule-no-tabs.yml 2025-06-19 09:30:13.000000000 +0200
@@ -2,7 +2,7 @@
- name: Fixture for no-tabs rule
hosts: localhost
tasks:
- - name: Should not trigger no-tabs rules
+ - name: Should not trigger no-tabs rules 1
ansible.builtin.lineinfile:
path: some.txt
regexp: ^\t$
@@ -13,7 +13,7 @@
- name: Key has a tab
ansible.builtin.debug:
"ms\tg": "The associated key has \t and should trigger no-tabs here."
- - name: Should not trigger no-tabs rules # noqa fqcn
+ - name: Should not trigger no-tabs rules 2 # noqa fqcn
lineinfile:
path: some.txt
regexp: "^\t$"
@@ -24,7 +24,7 @@
# path: some.txt
# regexp: "^\t$"
# line: string with \t inside
- - name: Should not trigger no-tabs rules
+ - name: Should not trigger no-tabs rules 3
community.windows.win_lineinfile:
path: some.txt
regexp: "^\t$"
diff -Nru ansible-lint-25.2.1/examples/playbooks/rule-risky-shell-pipe-pass.yml ansible-lint-25.6.1/examples/playbooks/rule-risky-shell-pipe-pass.yml
--- ansible-lint-25.2.1/examples/playbooks/rule-risky-shell-pipe-pass.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/rule-risky-shell-pipe-pass.yml 2025-06-19 09:30:13.000000000 +0200
@@ -13,19 +13,19 @@
false | cat
changed_when: false
- - name: Pipeline with pipefail, complex set
+ - name: Pipeline with pipefail, complex set - 1
ansible.builtin.shell: |
set -e -x -o pipefail
false | cat
changed_when: false
- - name: Pipeline with pipefail, complex set
+ - name: Pipeline with pipefail, complex set - 2
ansible.builtin.shell: |
set -e -x -o pipefail
false | cat
changed_when: false
- - name: Pipeline with pipefail, complex set
+ - name: Pipeline with pipefail, complex set - 3
ansible.builtin.shell: |
set -eo pipefail
false | cat
diff -Nru ansible-lint-25.2.1/examples/playbooks/transform-jinja.transformed.yml ansible-lint-25.6.1/examples/playbooks/transform-jinja.transformed.yml
--- ansible-lint-25.2.1/examples/playbooks/transform-jinja.transformed.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/transform-jinja.transformed.yml 2025-06-19 09:30:13.000000000 +0200
@@ -13,7 +13,7 @@
foo: "{{ 1 }}" # <-- jinja2[spacing]
msg: "{{ 'a' b }}" # <-- jinja2[invalid]
- - name: A block used to check that we do not identify error at correct level
+ - name: Another block used to check that we do not identify error at correct level
block:
- name: Foo # <-- this is valid jinja2
ansible.builtin.debug:
diff -Nru ansible-lint-25.2.1/examples/playbooks/transform-jinja.yml ansible-lint-25.6.1/examples/playbooks/transform-jinja.yml
--- ansible-lint-25.2.1/examples/playbooks/transform-jinja.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/transform-jinja.yml 2025-06-19 09:30:13.000000000 +0200
@@ -13,7 +13,7 @@
foo: "{{ 1 }}" # <-- jinja2[spacing]
msg: "{{ 'a' b }}" # <-- jinja2[invalid]
- - name: A block used to check that we do not identify error at correct level
+ - name: Another block used to check that we do not identify error at correct level
block:
- name: Foo # <-- this is valid jinja2
ansible.builtin.debug:
diff -Nru ansible-lint-25.2.1/examples/playbooks/transform-no-free-form.transformed.yml ansible-lint-25.6.1/examples/playbooks/transform-no-free-form.transformed.yml
--- ansible-lint-25.2.1/examples/playbooks/transform-no-free-form.transformed.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/transform-no-free-form.transformed.yml 2025-06-19 09:30:13.000000000 +0200
@@ -8,7 +8,7 @@
cmd: touch foo
changed_when: false
- - name: Create a placefolder file
+ - name: Create a placefolder file 2
ansible.builtin.command: # <-- command can also go first
chdir: /tmp
cmd: touch bar
diff -Nru ansible-lint-25.2.1/examples/playbooks/transform-no-free-form.yml ansible-lint-25.6.1/examples/playbooks/transform-no-free-form.yml
--- ansible-lint-25.2.1/examples/playbooks/transform-no-free-form.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/transform-no-free-form.yml 2025-06-19 09:30:13.000000000 +0200
@@ -6,7 +6,7 @@
ansible.builtin.command: chdir=/tmp touch foo # <-- don't use shorthand
changed_when: false
- - name: Create a placefolder file
+ - name: Create a placefolder file 2
ansible.builtin.command: touch bar chdir=/tmp # <-- command can also go first
changed_when: false
diff -Nru ansible-lint-25.2.1/examples/playbooks/vars/noqa_multiline.yml ansible-lint-25.6.1/examples/playbooks/vars/noqa_multiline.yml
--- ansible-lint-25.2.1/examples/playbooks/vars/noqa_multiline.yml 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/examples/playbooks/vars/noqa_multiline.yml 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,26 @@
+---
+# noqa: jinja[spacing]
+foo_postgresql_grafana_password_encoded: >-
+ {% if '!' in foo_postgresql_grafana_password or '#' in foo_postgresql_grafana_password %}
+ {{- ('\"\"\"' + foo_postgresql_grafana_password + '\"\"\"') | b64encode -}}
+ {% else %}
+ {{- foo_postgresql_grafana_password | b64encode -}}
+ {% endif %}
+
+# noqa: jinja[spacing]
+
+foo_postgresql_grafana_password_encoded_2: >-
+ {% if '!' in foo_postgresql_grafana_password or '#' in foo_postgresql_grafana_password %}
+ {{- ('\"\"\"' + foo_postgresql_grafana_password + '\"\"\"') | b64encode -}}
+ {% else %}
+ {{- foo_postgresql_grafana_password | b64encode -}}
+ {% endif %}
+
+inner:
+ # noqa: jinja[spacing]
+ foo_postgresql_grafana_password_encoded: >-
+ {% if '!' in foo_postgresql_grafana_password or '#' in foo_postgresql_grafana_password %}
+ {{- ('\"\"\"' + foo_postgresql_grafana_password + '\"\"\"') | b64encode -}}
+ {% else %}
+ {{- foo_postgresql_grafana_password | b64encode -}}
+ {% endif %}
diff -Nru ansible-lint-25.2.1/examples/playbooks/vars/strings.transformed.yml ansible-lint-25.6.1/examples/playbooks/vars/strings.transformed.yml
--- ansible-lint-25.2.1/examples/playbooks/vars/strings.transformed.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/examples/playbooks/vars/strings.transformed.yml 2025-06-19 09:30:13.000000000 +0200
@@ -5,13 +5,13 @@
single: "single" # this is a comment
single_with_double: '"single" quoted' # this is a comment
-single_multiline_with_octothorpe: "single over 160 char line to force wrapping. over 160 char line to force wrapping. over 160 char line to force wrapping. over 160\n
+single_multiline_with_octothorpe: "single over 160 char line to force wrapping. over 160 char line to force wrapping. over 160 char line to force wrapping. over 160\n\
# this is not a comment"
double: "double" # this is a comment
double_with_single: "'double' quoted" # this is a comment
-double_multiline_with_octothorpe: "double over 160 char line to force wrapping. over 160 char line to force wrapping. over 160 char line to force wrapping. over 160\n
+double_multiline_with_octothorpe: "double over 160 char line to force wrapping. over 160 char line to force wrapping. over 160 char line to force wrapping. over 160\n\
# this is not a comment"
# this is a comment
diff -Nru ansible-lint-25.2.1/.git_archival.txt ansible-lint-25.6.1/.git_archival.txt
--- ansible-lint-25.2.1/.git_archival.txt 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.git_archival.txt 2025-06-19 09:30:13.000000000 +0200
@@ -1,4 +1,4 @@
-node: c16f018b1bdfdea6717f4b5b1b141a78b86021cd
-node-date: 2025-04-03T11:56:32Z
+node: 06f616d6e86e9ce4c74393318d1cbb2d016af413
+node-date: 2025-06-19T08:30:13+01:00
describe-name: v25
-ref-names: HEAD -> main, tag: v25.2.1, tag: v25
+ref-names: tag: v25.6.1, tag: v25
diff -Nru ansible-lint-25.2.1/.github/lower-constraints.txt ansible-lint-25.6.1/.github/lower-constraints.txt
--- ansible-lint-25.2.1/.github/lower-constraints.txt 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.github/lower-constraints.txt 2025-06-19 09:30:13.000000000 +0200
@@ -9,7 +9,7 @@
packaging==24.2 # Due to tox-uv
pathspec==0.10.3
pyyaml==6.0.2
-ruamel.yaml==0.18.5 # MIT
+ruamel.yaml==0.18.11 # MIT
subprocess-tee==0.4.1 # MIT, used by ansible-compat
# https://packages.ubuntu.com/noble/python3-wcmatch
# https://packages.fedoraproject.org/pkgs/python-wcmatch/python3-wcmatch/
diff -Nru ansible-lint-25.2.1/.github/workflows/ack.yml ansible-lint-25.6.1/.github/workflows/ack.yml
--- ansible-lint-25.2.1/.github/workflows/ack.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.github/workflows/ack.yml 2025-06-19 09:30:13.000000000 +0200
@@ -1,7 +1,8 @@
---
# See https://github.com/ansible/devtools/blob/main/.github/workflows/ack.yml
name: ack
-"on":
+on:
+ merge_group:
pull_request_target:
types: [opened, labeled, unlabeled, synchronize]
diff -Nru ansible-lint-25.2.1/.github/workflows/tox.yml ansible-lint-25.6.1/.github/workflows/tox.yml
--- ansible-lint-25.2.1/.github/workflows/tox.yml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.github/workflows/tox.yml 2025-06-19 09:30:13.000000000 +0200
@@ -2,6 +2,7 @@
name: tox
on:
+ merge_group:
push:
branches:
- "main"
@@ -155,12 +156,12 @@
if: ${{ matrix.command5 }}
- name: Archive logs
- uses: actions/upload-artifact@v4
+ uses: coactions/upload-artifact@v4
with:
name: logs-${{ matrix.name }}.zip
include-hidden-files: true
+ if-no-files-found: ignore
path: |
- .tox/**/log/
.tox/**/.coverage*
.tox/**/coverage.xml
@@ -259,7 +260,7 @@
fi
- name: Upload coverage data
- uses: codecov/codecov-action@v5.4.0
+ uses: codecov/codecov-action@v5.4.3
with:
name: ${{ matrix.name }}
# verbose: true # optional (default = false)
diff -Nru ansible-lint-25.2.1/.gitignore ansible-lint-25.6.1/.gitignore
--- ansible-lint-25.2.1/.gitignore 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.gitignore 2025-06-19 09:30:13.000000000 +0200
@@ -28,6 +28,7 @@
# Unit test / coverage reports
.tox
+junit.xml
# Needed for CLI tests
.sandbox
diff -Nru ansible-lint-25.2.1/.pre-commit-config.yaml ansible-lint-25.6.1/.pre-commit-config.yaml
--- ansible-lint-25.2.1/.pre-commit-config.yaml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.pre-commit-config.yaml 2025-06-19 09:30:13.000000000 +0200
@@ -17,6 +17,7 @@
examples/broken/encoding.yml|
examples/broken/encoding.j2|
examples/broken/yaml-with-tabs/invalid-due-tabs.yaml|
+ examples/broken/load-failure-invalid.yml|
examples/playbooks/collections/.*|
examples/playbooks/vars/empty.transformed.yml|
examples/playbooks/vars/empty.yml|
@@ -60,14 +61,14 @@
- prettier@3.2.4
- prettier-plugin-sort-json@3.1.0
- repo: https://github.com/streetsidesoftware/cspell-cli
- rev: v8.17.3
+ rev: v9.0.1
hooks:
- id: cspell
# entry: codespell --relative
args: [--relative, --no-progress, --no-summary]
name: Spell check with cspell
- repo: https://github.com/python-jsonschema/check-jsonschema
- rev: 0.31.3
+ rev: 0.33.0
hooks:
- id: check-github-workflows
- repo: https://github.com/pre-commit/pre-commit-hooks.git
@@ -117,7 +118,7 @@
additional_dependencies:
- tomli
- repo: https://github.com/adrienverge/yamllint.git
- rev: v1.36.2
+ rev: v1.37.1
hooks:
- id: yamllint
exclude: >
@@ -144,17 +145,14 @@
- id: tox-ini-fmt
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.11.0
+ rev: v0.11.13
hooks:
- - id: ruff
- args:
- - --fix
- - --exit-non-zero-on-fix
- types_or: [python, pyi]
- # - id: ruff-format # must be after ruff
- # types_or: [python, pyi]
+ - id: ruff-format
+ alias: ruff
+ - id: ruff-check
+ alias: ruff
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.15.0
+ rev: v1.16.1
hooks:
- id: mypy
# "." and pass_files are used to make pre-commit mypy behave the same as standalone mypy
@@ -180,12 +178,12 @@
- wcmatch
- yamllint>=1.34.0
- repo: https://github.com/RobertCraigie/pyright-python
- rev: v1.1.398
+ rev: v1.1.402
hooks:
- id: pyright
additional_dependencies: *deps
- repo: https://github.com/pycqa/pylint
- rev: v3.3.6
+ rev: v3.3.7
hooks:
- id: pylint
args:
diff -Nru ansible-lint-25.2.1/.prettierignore ansible-lint-25.6.1/.prettierignore
--- ansible-lint-25.2.1/.prettierignore 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/.prettierignore 2025-06-19 09:30:13.000000000 +0200
@@ -28,6 +28,7 @@
# Unit test / coverage reports
.tox
+junit.xml
# Needed for CLI tests
.sandbox
diff -Nru ansible-lint-25.2.1/pyproject.toml ansible-lint-25.6.1/pyproject.toml
--- ansible-lint-25.2.1/pyproject.toml 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/pyproject.toml 2025-06-19 09:30:13.000000000 +0200
@@ -15,10 +15,8 @@
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Intended Audience :: System Administrators",
- "License :: OSI Approved :: MIT License",
"Operating System :: MacOS",
"Operating System :: POSIX",
- "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
@@ -34,7 +32,7 @@
description = "Checks playbooks for practices and behavior that could potentially be improved"
dynamic = ["version", "dependencies", "optional-dependencies"]
keywords = ["ansible", "lint"]
-license = {text = "GPLv3+"}
+license = "GPL-3.0-or-later"
maintainers = [{"email" = "info@ansible.com", "name" = "Ansible by Red Hat"}]
name = "ansible-lint"
readme = "README.md"
@@ -63,7 +61,7 @@
[tool.coverage.report]
exclude_also = ["pragma: no cover", "if TYPE_CHECKING:"]
# Increase it just so it would pass on any single-python run
-fail_under = 95
+fail_under = 93
# During development we might remove code (files) with coverage data, and we dont want to fail:
ignore_errors = true
omit = ["test/*"]
@@ -73,10 +71,9 @@
skip_empty = true
[tool.coverage.run]
+# branch is more reliable than lines, protects against false positives
+branch = true
concurrency = ["multiprocessing", "thread"]
-# Do not use branch until bug is fixes:
-# https://github.com/nedbat/coveragepy/issues/605
-# branch = true
parallel = true
source = ["src"]
@@ -411,11 +408,7 @@
# https://github.com/ansible/ansible/pull/80968
"ignore:Attribute s is deprecated and will be removed in Python 3.14; use value instead:DeprecationWarning"
]
-junit_duration_report = "call"
-junit_family = "xunit1"
-# Our github annotation parser from .github/workflows/tox.yml requires xunit1 format. Ref:
-# https://github.com/shyim/junit-report-annotations-action/issues/3#issuecomment-663241378
-junit_suite_name = "ansible_lint_test_suite"
+junit_family = "legacy"
minversion = "4.6.6"
# https://code.visualstudio.com/docs/python/testing
# coverage is re-enabled in `tox.ini`. That approach is safer than
@@ -501,6 +494,7 @@
"FURB110",
"FURB113",
"FURB118",
+ "PLC0207", # maxsplit with [-1] preview rule
"PLC0415",
"PLC2701",
"PLW1641",
diff -Nru ansible-lint-25.2.1/src/ansiblelint/cli.py ansible-lint-25.6.1/src/ansiblelint/cli.py
--- ansible-lint-25.2.1/src/ansiblelint/cli.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/cli.py 2025-06-19 09:30:13.000000000 +0200
@@ -61,7 +61,9 @@
config[paths_var] = normalized_paths
-def load_config(config_file: str | None) -> tuple[dict[Any, Any], str | None]:
+def load_config(
+ config_file: str | None = None, project_path: str | None = None
+) -> tuple[dict[Any, Any], str | None]:
"""Load configuration from disk."""
config_path = None
@@ -74,7 +76,7 @@
if not os.path.exists(config_path):
_logger.error("Config file not found '%s'", config_path)
sys.exit(RC.INVALID_CONFIG)
- config_path = config_path or get_config_path()
+ config_path = config_path or get_config_path(None, project_path=project_path)
if not config_path or not os.path.exists(config_path):
# a missing default config file should not trigger an error
return {}, None
@@ -100,7 +102,9 @@
return config, config_path
-def get_config_path(config_file: str | None = None) -> str | None:
+def get_config_path(
+ config_file: str | None = None, project_path: str | None = None
+) -> str | None:
"""Return local config file."""
if config_file:
project_filenames = [config_file]
@@ -112,7 +116,7 @@
".config/ansible-lint.yml",
".config/ansible-lint.yaml",
]
- parent = tail = os.getcwd()
+ parent = tail = project_path or os.getcwd()
while tail:
for project_filename in project_filenames:
filename = os.path.abspath(os.path.join(parent, project_filename))
@@ -460,8 +464,8 @@
parser.add_argument(
"--offline",
dest="offline",
- action="store_const",
- const=True,
+ action=argparse.BooleanOptionalAction,
+ default=False,
help="Disable installation of requirements.yml and schema refreshing",
)
parser.add_argument(
@@ -595,7 +599,9 @@
)
# save info about custom config file, as options.config_file may be modified by merge_config
- file_config, options.config_file = load_config(options.config_file)
+ file_config, options.config_file = load_config(
+ options.config_file, project_path=options.project_dir
+ )
config = merge_config(file_config, options)
options.rulesdirs = get_rules_dirs(
diff -Nru ansible-lint-25.2.1/src/ansiblelint/formatters/__init__.py ansible-lint-25.6.1/src/ansiblelint/formatters/__init__.py
--- ansible-lint-25.2.1/src/ansiblelint/formatters/__init__.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/formatters/__init__.py 2025-06-19 09:30:13.000000000 +0200
@@ -96,7 +96,7 @@
result = (
f"[repr.path]{self._format_path(match.filename or '')}[/][dim]:{match.position}:[/] "
f"[{match.level}][bold]{self.escape(match.tag)}[/]"
- f"{ f': {match.message}' if not options.quiet else '' }[/]"
+ f"{f': {match.message}' if not options.quiet else ''}[/]"
)
if match.level != "error":
result += f" [dim][{match.level}]({match.level})[/][/]"
@@ -307,9 +307,9 @@
],
}
if match.column:
- result["locations"][0]["physicalLocation"]["region"][
- "startColumn"
- ] = match.column
+ result["locations"][0]["physicalLocation"]["region"]["startColumn"] = (
+ match.column
+ )
return result
@staticmethod
diff -Nru ansible-lint-25.2.1/src/ansiblelint/loaders.py ansible-lint-25.6.1/src/ansiblelint/loaders.py
--- ansible-lint-25.2.1/src/ansiblelint/loaders.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/loaders.py 2025-06-19 09:30:13.000000000 +0200
@@ -2,6 +2,7 @@
from __future__ import annotations
+import enum
import logging
import os
from collections import defaultdict
@@ -28,6 +29,19 @@
alternative: str
+class IgnoreRuleQualifier(enum.Enum):
+ """Extra flags for ignored rules."""
+
+ SKIP = "Force skip, not warning"
+
+
+class IgnoreRule(NamedTuple):
+ """Ignored rule."""
+
+ rule: str
+ qualifiers: frozenset[IgnoreRuleQualifier]
+
+
IGNORE_FILE = IgnoreFile(".ansible-lint-ignore", ".config/ansible-lint-ignore.txt")
yaml_load = partial(yaml.load, Loader=FullLoader)
@@ -41,7 +55,19 @@
return yaml_load(content)
-def load_ignore_txt(filepath: Path | None = None) -> dict[str, set[str]]:
+def get_ignore_rule(rule: str, qualifiers: str) -> IgnoreRule:
+ """Validate qualifiers and return an IgnoreRule."""
+ s = set()
+ if qualifiers:
+ for q in qualifiers.split(","):
+ if q == "skip":
+ s.add(IgnoreRuleQualifier.SKIP)
+ else:
+ raise ValueError
+ return IgnoreRule(rule, frozenset(s))
+
+
+def load_ignore_txt(filepath: Path | None = None) -> dict[str, set[IgnoreRule]]:
"""Return a list of rules to ignore."""
result = defaultdict(set)
@@ -64,17 +90,21 @@
entry = line.split("#")[0].rstrip()
if entry:
try:
- path, rule = entry.split()
+ fields = entry.split()
+ path = fields[0]
+ rule = fields[1]
+ qualifiers = fields[2] if len(fields) == 3 else ""
+ result[path].add(get_ignore_rule(rule, qualifiers))
except ValueError as exc: # pragma: no cover
msg = f"Unable to parse line '{line}' from {ignore_file} file."
raise RuntimeError(msg) from exc
- result[path].add(rule)
-
return result
__all__ = [
"IGNORE_FILE",
+ "IgnoreRule",
+ "IgnoreRuleQualifier",
"YAMLError",
"load_ignore_txt",
"yaml_from_file",
diff -Nru ansible-lint-25.2.1/src/ansiblelint/__main__.py ansible-lint-25.6.1/src/ansiblelint/__main__.py
--- ansible-lint-25.2.1/src/ansiblelint/__main__.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/__main__.py 2025-06-19 09:30:13.000000000 +0200
@@ -57,7 +57,7 @@
log_entries,
options,
)
-from ansiblelint.loaders import load_ignore_txt
+from ansiblelint.loaders import IgnoreRule, IgnoreRuleQualifier, load_ignore_txt
from ansiblelint.output import (
console,
console_stderr,
@@ -272,6 +272,19 @@
result.matches.pop(idx)
+# By default, matches ignored in .ansible-lint-ignore are treated
+# as warnings [1]. If the user explicitly adds a skip qualifier
+# to the rule, it is treated as skipped here and does not show up
+# even as a warning.
+# [1] https://github.com/ansible/ansible-lint/issues/3068
+def _rule_is_skipped(tag: str, rules: set[IgnoreRule]) -> bool:
+ for rule in rules:
+ if tag != rule.rule:
+ return False
+ return IgnoreRuleQualifier.SKIP in rule.qualifiers
+ return False
+
+
# pylint: disable=too-many-locals,too-many-statements
def main(argv: list[str] | None = None) -> int:
"""Linter CLI entry point."""
@@ -376,10 +389,17 @@
# Remove skip_list items from the result
result.matches = [m for m in result.matches if m.tag not in app.options.skip_list]
- # Mark matches as ignored inside ignore file
+ # load ignore file
ignore_map = load_ignore_txt(options.ignore_file)
+ # prune qualified skips from ignore file
+ result.matches = [
+ m for m in result.matches if not _rule_is_skipped(m.tag, ignore_map[m.filename])
+ ]
+ # others entries are ignored
for match in result.matches:
- if match.tag in ignore_map[match.filename]: # pragma: no cover
+ if match.tag in [
+ i.rule for i in ignore_map[match.filename]
+ ]: # pragma: no cover
match.ignored = True
_logger.debug("Ignored: %s", match)
diff -Nru ansible-lint-25.2.1/src/ansiblelint/requirements.py ansible-lint-25.6.1/src/ansiblelint/requirements.py
--- ansible-lint-25.2.1/src/ansiblelint/requirements.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/requirements.py 2025-06-19 09:30:13.000000000 +0200
@@ -13,10 +13,12 @@
def __init__(self, name: str = "ansible-lint") -> None:
"""Load linter metadata requirements."""
- for req_str in importlib_metadata.metadata(name).json["requires_dist"]:
- req = Requirement(req_str)
- if req.name:
- self[req.name] = req.specifier
+ metadata = importlib_metadata.metadata(name)
+ if metadata:
+ for req_str in metadata.json["requires_dist"]:
+ req = Requirement(req_str)
+ if req.name:
+ self[req.name] = req.specifier
def matches(self, req_name: str, req_version: str | Version) -> bool:
"""Verify if given version is matching current metadata dependencies."""
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/args.md ansible-lint-25.6.1/src/ansiblelint/rules/args.md
--- ansible-lint-25.2.1/src/ansiblelint/rules/args.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/args.md 2025-06-19 09:30:13.000000000 +0200
@@ -40,6 +40,13 @@
- my_param <= 100
- my_param >= 0
quiet: invalid # <- Value for option `quiet` is invalid.
+
+ - name: Do not use mutually exclusive arguments together
+ ansible.builtin.command:
+ cmd: /bin/echo # <- cmd and argv are mutually exclusive options
+ argv:
+ - Hello
+ when_changed: false
```
## Correct Code
@@ -69,6 +76,18 @@
- my_param <= 100
- my_param >= 0
quiet: True # <- Has correct type value for option `quiet` which is boolean.
+
+ - name: Do not use mutually exclusive arguments together
+ ansible.builtin.command:
+ cmd: "/bin/echo Hello" # <- Does not use `cmd` and `argv`
+ when_changed: false
+
+ - name: Do not use mutually exclusive arguments together alternative
+ ansible.builtin.command:
+ argv: # <- Does not use `cmd` and `argv`
+ - /bin/echo
+ - Hello
+ when_changed: false
```
## Special cases
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/args.py ansible-lint-25.6.1/src/ansiblelint/rules/args.py
--- ansible-lint-25.2.1/src/ansiblelint/rules/args.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/args.py 2025-06-19 09:30:13.000000000 +0200
@@ -64,6 +64,10 @@
# https://github.com/ansible/ansible-lint/issues/2824
"ansible.builtin.async_status": {"_async_dir": "/tmp/ansible-async"},
}
+workarounds_mutex_args_map = {
+ # https://github.com/ansible/ansible-lint/issues/4623
+ "ansible.builtin.command": [{"cmd", "argv"}],
+}
class ValidationPassedError(Exception):
@@ -136,6 +140,19 @@
if loaded_module.resolved_fqcn in workarounds_inject_map:
module_args.update(workarounds_inject_map[loaded_module.resolved_fqcn])
+ if loaded_module.resolved_fqcn in workarounds_mutex_args_map:
+ results.extend(
+ self.create_matcherror(
+ message=f"Module arguments {mutex_set} are mutually exclusive",
+ lineno=task.line,
+ tag="args[module]",
+ filename=file,
+ )
+ for mutex_set in workarounds_mutex_args_map[loaded_module.resolved_fqcn]
+ if len(mutex_set - module_args.keys()) < len(mutex_set) - 1
+ )
+ if results:
+ return self._sanitize_results(results, module_name)
if loaded_module.resolved_fqcn in workarounds_drop_map:
for key in workarounds_drop_map[loaded_module.resolved_fqcn]:
module_args.pop(key, None)
@@ -287,7 +304,7 @@
"""Test rule invalid module options."""
success = "examples/playbooks/rule-args-module-fail.yml"
results = Runner(success, rules=default_rules_collection).run()
- assert len(results) == 5
+ assert len(results) == 6
assert results[0].tag == "args[module]"
# First part of regex is for ansible-core up to 2.18, second part is for ansible-core 2.19+
assert re.match(
@@ -311,6 +328,8 @@
)
assert results[4].tag == "args[module]"
assert "value of state must be one of" in results[4].message
+ assert results[5].tag == "args[module]"
+ assert "are mutually exclusive" in results[5].message
def test_args_module_pass(
default_rules_collection: RulesCollection,
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/inline_env_var.py ansible-lint-25.6.1/src/ansiblelint/rules/inline_env_var.py
--- ansible-lint-25.2.1/src/ansiblelint/rules/inline_env_var.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/inline_env_var.py 2025-06-19 09:30:13.000000000 +0200
@@ -44,9 +44,11 @@
version_changed = "5.0.11"
expected_args = [
+ "argv",
"chdir",
"creates",
"executable",
+ "expand_argument_vars",
"removes",
"stdin",
"stdin_add_newline",
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/name.md ansible-lint-25.6.1/src/ansiblelint/rules/name.md
--- ansible-lint-25.2.1/src/ansiblelint/rules/name.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/name.md 2025-06-19 09:30:13.000000000 +0200
@@ -15,10 +15,15 @@
helps with the identification of tasks inside the source code when they fail.
The use of templating inside `name` keys is discouraged as there are multiple
cases where the rendering of the name template is not possible.
+- `name[unique]` - All task names within a single play should be unique.
If you want to ignore some of the messages above, you can add any of them to the
`skip_list`.
+## name[unique]
+
+This check ensures that every task name is unique within the same play. This includes tasks defined in the `pre_tasks`, `tasks`, `post_tasks`, and `handlers` sections. Having unique names is crucial for reliably using features like `--start-at-task` and makes playbook execution easier to follow and debug.
+
## name[prefix]
This rule applies only to included task files that are not named `main.yml` or
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/name.py ansible-lint-25.6.1/src/ansiblelint/rules/name.py
--- ansible-lint-25.2.1/src/ansiblelint/rules/name.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/name.py 2025-06-19 09:30:13.000000000 +0200
@@ -39,8 +39,47 @@
"name[prefix]": "Task name should start with a prefix.",
"name[casing]": "All names should start with an uppercase letter.",
"name[template]": "Jinja templates should only be at the end of 'name'",
+ "name[unique]": "Task names should be unique within a play.",
}
+ def _check_unique_task_names(
+ self,
+ tasks: list[MutableMapping[str, Any]],
+ seen_names: dict[str, int],
+ file: Lintable,
+ ) -> list[MatchError]:
+ """Helper function to iterate through a list of tasks and check for duplicates."""
+ errors: list[MatchError] = []
+ if not tasks:
+ return errors
+
+ for task in tasks:
+ # We skip tasks without a name, as that is covered by the 'name[missing]' rule.
+ task_name = task.get("name")
+ if not task_name:
+ continue
+
+ # If a task-like dict lacks a line number, we cannot perform the uniqueness check, so we skip it.
+ if "__line__" not in task:
+ continue
+
+ # The linter adds '__line__' to each task dictionary.
+ lineno = task["__line__"]
+
+ if task_name in seen_names:
+ message = f"Task name '{task_name}' is not unique. It was first used on line {seen_names[task_name]}."
+ errors.append(
+ self.create_matcherror(
+ message=message,
+ lineno=lineno,
+ filename=file,
+ tag="name[unique]",
+ )
+ )
+ else:
+ seen_names[task_name] = lineno
+ return errors
+
def matchplay(self, file: Lintable, data: dict[str, Any]) -> list[MatchError]:
"""Return matches found for a specific play (entry in playbook)."""
results: list[MatchError] = []
@@ -48,6 +87,8 @@
return []
if file.failed(): # pragma: no cover
return results
+
+ # Check if the play itself is named
if "name" not in data:
return [
self.create_matcherror(
@@ -64,6 +105,17 @@
data=data,
),
)
+
+ # Check for unique task names within this play
+ seen_task_names: dict[str, int] = {}
+ task_sections = ["pre_tasks", "tasks", "post_tasks", "handlers"]
+ for section in task_sections:
+ tasks = data.get(section, [])
+ if tasks:
+ results.extend(
+ self._check_unique_task_names(tasks, seen_task_names, file)
+ )
+
return results
def matchtask(
@@ -71,6 +123,7 @@
task: Task,
file: Lintable | None = None,
) -> list[MatchError]:
+ """Check rules for a single task."""
results: list[MatchError] = []
if file and file.failed(): # pragma: no cover
return results
@@ -153,7 +206,8 @@
effective_name = name[len(prefix) :]
if (
- effective_name[0].isalpha()
+ effective_name
+ and effective_name[0].isalpha()
and effective_name[0].islower()
and not effective_name[0].isupper()
):
@@ -204,7 +258,7 @@
lintable_dir = lintable_dir.parent
pathex = lintable_dir / stem
- if stems[0].startswith(kind):
+ if stems and stems[0].startswith(kind):
del stems[0]
return str(wcmatch.pathlib.PurePath(*stems, stem))
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/no_log_password.md ansible-lint-25.6.1/src/ansiblelint/rules/no_log_password.md
--- ansible-lint-25.2.1/src/ansiblelint/rules/no_log_password.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/no_log_password.md 2025-06-19 09:30:13.000000000 +0200
@@ -6,6 +6,14 @@
While most Ansible modules mask sensitive data, using secrets inside a loop can result in those secrets being logged.
Explicitly adding `no_log: true` prevents accidentally exposing secrets.
+This is an opt-in rule.
+You must enable it in your Ansible-lint configuration as follows:
+
+```yaml
+enable_list:
+ - no-log-password
+```
+
## Problematic Code
```yaml
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/package_latest.md ansible-lint-25.6.1/src/ansiblelint/rules/package_latest.md
--- ansible-lint-25.2.1/src/ansiblelint/rules/package_latest.md 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/package_latest.md 2025-06-19 09:30:13.000000000 +0200
@@ -2,7 +2,7 @@
This rule checks that package managers install software in a controlled, safe manner.
-Package manager modules, such as `ansible.builtin.yum`, include a `state` parameter that configures how Ansible installs software.
+Package manager modules, such as `ansible.builtin.dnf`, include a `state` parameter that configures how Ansible installs software.
In production environments, you should set `state` to `present` and specify a target version to ensure that packages are installed to a planned and tested version.
Setting `state` to `latest` not only installs software, it performs an update and installs additional packages.
@@ -17,7 +17,7 @@
hosts: localhost
tasks:
- name: Install Ansible
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: ansible
state: latest # <- Installs the latest package.
@@ -33,7 +33,7 @@
state: latest # <- Installs the latest package.
- name: Install sudo with update_only to false
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: sudo
state: latest
update_only: false # <- Updates and installs packages.
@@ -53,9 +53,9 @@
hosts: localhost
tasks:
- name: Install Ansible
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: ansible-2.12.7.0
- state: present # <- Pins the version to install with yum.
+ state: present # <- Pins the version to install with dnf.
- name: Install Ansible-lint
ansible.builtin.pip:
@@ -70,7 +70,7 @@
state: present # <- Ensures the package is installed.
- name: Update sudo with update_only to true
- ansible.builtin.yum:
+ ansible.builtin.dnf:
name: sudo
state: latest
update_only: true # <- Updates but does not install additional packages.
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/package_latest.py ansible-lint-25.6.1/src/ansiblelint/rules/package_latest.py
--- ansible-lint-25.2.1/src/ansiblelint/rules/package_latest.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/package_latest.py 2025-06-19 09:30:13.000000000 +0200
@@ -81,5 +81,6 @@
and not task["action"].get("version")
and not task["action"].get("update_only")
and not task["action"].get("only_upgrade")
+ and not task["action"].get("download_only")
and task["action"].get("state") == "latest"
)
diff -Nru ansible-lint-25.2.1/src/ansiblelint/rules/risky_octal.py ansible-lint-25.6.1/src/ansiblelint/rules/risky_octal.py
--- ansible-lint-25.2.1/src/ansiblelint/rules/risky_octal.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/rules/risky_octal.py 2025-06-19 09:30:13.000000000 +0200
@@ -38,8 +38,7 @@
id = "risky-octal"
description = (
- "Numeric file permissions without leading zero can behave "
- "in unexpected ways."
+ "Numeric file permissions without leading zero can behave in unexpected ways."
)
link = "https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html"
severity = "VERY_HIGH"
diff -Nru ansible-lint-25.2.1/src/ansiblelint/runner.py ansible-lint-25.6.1/src/ansiblelint/runner.py
--- ansible-lint-25.2.1/src/ansiblelint/runner.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/runner.py 2025-06-19 09:30:13.000000000 +0200
@@ -23,6 +23,9 @@
from ansible.parsing.splitter import split_args
from ansible.plugins.loader import add_all_plugin_dirs
from ansible_compat.runtime import AnsibleWarning
+from ruamel.yaml.parser import ParserError as RuamelParserError
+from yaml.parser import ParserError
+from yaml.scanner import ScannerError
import ansiblelint.skip_utils
import ansiblelint.utils
@@ -213,14 +216,33 @@
self.lintables.remove(lintable)
continue
if isinstance(lintable.data, States) and lintable.exc:
+ line = 1
+ column = None
+ detail = ""
+ sub_tag = ""
lintable.exc.__class__.__name__.lower()
+ message = None
+ if lintable.exc.__cause__ and isinstance(
+ lintable.exc.__cause__,
+ ScannerError | ParserError | RuamelParserError,
+ ):
+ sub_tag = "yaml"
+ if isinstance(lintable.exc.args, tuple):
+ message = lintable.exc.args[0]
+ detail = lintable.exc.__cause__.problem
+ if lintable.exc.__cause__.problem_mark:
+ line = lintable.exc.__cause__.problem_mark.line + 1
+ column = lintable.exc.__cause__.problem_mark.column + 1
+
matches.append(
MatchError(
lintable=lintable,
- message=str(lintable.exc),
- details=str(lintable.exc.__cause__),
+ message=message or str(lintable.exc),
+ details=detail or str(lintable.exc.__cause__),
rule=self.rules["load-failure"],
- tag=f"load-failure[{lintable.exc.__class__.__name__.lower()}]",
+ lineno=line,
+ column=column,
+ tag=f"load-failure[{sub_tag or lintable.exc.__class__.__name__.lower()}]",
),
)
lintable.stop_processing = True
diff -Nru ansible-lint-25.2.1/src/ansiblelint/schemas/ansible-navigator.json ansible-lint-25.6.1/src/ansiblelint/schemas/ansible-navigator.json
--- ansible-lint-25.2.1/src/ansiblelint/schemas/ansible-navigator.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/schemas/ansible-navigator.json 2025-06-19 09:30:13.000000000 +0200
@@ -287,7 +287,7 @@
"$ref": "#/$defs/EnvironmentVariablesModel"
},
"image": {
- "default": "quay.io/ansible/creator-ee:v0.2.0",
+ "default": "ghcr.io/ansible/community-ansible-dev-tools:latest",
"description": "Specify the name of the execution environment image",
"title": "Image",
"type": "string"
diff -Nru ansible-lint-25.2.1/src/ansiblelint/schemas/meta.json ansible-lint-25.6.1/src/ansiblelint/schemas/meta.json
--- ansible-lint-25.2.1/src/ansiblelint/schemas/meta.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/schemas/meta.json 2025-06-19 09:30:13.000000000 +0200
@@ -378,6 +378,7 @@
"39",
"40",
"41",
+ "42",
"all"
],
"type": "string"
@@ -875,6 +876,7 @@
"21.02",
"22.03",
"23.05",
+ "24.10",
"all"
],
"type": "string"
@@ -1014,6 +1016,7 @@
"15SP3",
"15SP4",
"15SP5",
+ "15SP6",
"all"
],
"type": "string"
@@ -1129,6 +1132,8 @@
"maverick",
"natty",
"oneiric",
+ "oracular",
+ "plucky",
"precise",
"quantal",
"raring",
@@ -1504,7 +1509,7 @@
"versions": {
"default": "all",
"items": {
- "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "all"],
+ "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "8.0", "all"],
"type": "string"
},
"type": "array"
@@ -1523,7 +1528,7 @@
"versions": {
"default": "all",
"items": {
- "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "all"],
+ "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "8.0", "all"],
"type": "string"
},
"type": "array"
diff -Nru ansible-lint-25.2.1/src/ansiblelint/schemas/__store__.json ansible-lint-25.6.1/src/ansiblelint/schemas/__store__.json
--- ansible-lint-25.2.1/src/ansiblelint/schemas/__store__.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/schemas/__store__.json 2025-06-19 09:30:13.000000000 +0200
@@ -24,7 +24,7 @@
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json"
},
"meta": {
- "etag": "62cce45a9b8bd96872d8ee1c465d3ff6b60facf6a4aeba5c2e128df02b5f52a5",
+ "etag": "60f3ce2a78ec4fb705c589da409a384ac97315e17810379c5049169986ce3097",
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json"
},
"meta-runtime": {
diff -Nru ansible-lint-25.2.1/src/ansiblelint/skip_utils.py ansible-lint-25.6.1/src/ansiblelint/skip_utils.py
--- ansible-lint-25.2.1/src/ansiblelint/skip_utils.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/skip_utils.py 2025-06-19 09:30:13.000000000 +0200
@@ -55,7 +55,8 @@
_logger = logging.getLogger(__name__)
_found_deprecated_tags: set[str] = set()
-_noqa_comment_re = re.compile(r"^# noqa(\s|:)")
+_noqa_comment_re = re.compile(r"^\s*# noqa(\s|:)", flags=re.MULTILINE)
+_noqa_comment_line_re = re.compile(r"^\s*# noqa(\s|:).*$")
# playbook: Sequence currently expects only instances of one of the two
# classes below but we should consider avoiding this chimera.
@@ -257,6 +258,28 @@
yield task
+def _continue_skip_next_lines(
+ lintable: Lintable,
+) -> None:
+ """When a line only contains a noqa comment (and possibly indentation), add the skip also to the next non-empty line."""
+ # If line starts with _noqa_comment_line_re, add next non-empty line to same lintable.line_skips
+ line_content = lintable.content.splitlines()
+ for line_no in list(lintable.line_skips.keys()):
+ if _noqa_comment_line_re.fullmatch(line_content[line_no - 1]):
+ # Find next non-empty line
+ next_line_no = line_no
+ while (
+ next_line_no < len(line_content)
+ and not line_content[next_line_no].strip()
+ ):
+ next_line_no += 1
+ if next_line_no >= len(line_content):
+ continue
+ lintable.line_skips[next_line_no + 1].update(
+ lintable.line_skips[line_no],
+ )
+
+
def _get_rule_skips_from_yaml(
yaml_input: Sequence[Any],
lintable: Lintable,
@@ -268,7 +291,17 @@
return []
def traverse_yaml(obj: Any) -> None:
- for entry in obj.ca.items.values():
+ traversable = list(obj.ca.items.values())
+ if obj.ca.comment:
+ traversable.append(obj.ca.comment)
+ for entry in traversable:
+ # flatten all lists we might have in entries. Some arcane ruamel CommentedMap magic
+ entry = [
+ item
+ for sublist in entry
+ if sublist is not None
+ for item in (sublist if isinstance(sublist, list) else [sublist])
+ ]
for v in entry:
if isinstance(v, CommentToken):
comment_str = v.value
@@ -298,6 +331,7 @@
for comment_obj_str in yaml_comment_obj_strings:
for line in comment_obj_str.split(r"\n"):
rule_id_list.extend(get_rule_skips_from_line(line, lintable=lintable))
+ _continue_skip_next_lines(lintable)
return [normalize_tag(tag) for tag in rule_id_list]
diff -Nru ansible-lint-25.2.1/src/ansiblelint/utils.py ansible-lint-25.6.1/src/ansiblelint/utils.py
--- ansible-lint-25.2.1/src/ansiblelint/utils.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/utils.py 2025-06-19 09:30:13.000000000 +0200
@@ -523,11 +523,11 @@
for loc in self.app.runtime.config.collections_paths:
append_playbook_path(
loc,
- playbook_path[:-1] + [f"{playbook_path[-1]}.yml"],
+ [*playbook_path[:-1], f"{playbook_path[-1]}.yml"],
)
append_playbook_path(
loc,
- playbook_path[:-1] + [f"{playbook_path[-1]}.yaml"],
+ [*playbook_path[:-1], f"{playbook_path[-1]}.yaml"],
)
else:
possible_paths.append(lintable.path.parent / v)
@@ -568,22 +568,29 @@
def _rolepath(self, basedir: str, role: str) -> str | None:
role_path = None
- namespace_name, collection_name, role_name = parse_fqcn(role)
+ namespace_name, collection_name, *role_name = parse_fqcn(role)
possible_paths = [
# if included from a playbook
- path_dwim(basedir, os.path.join("roles", role_name)),
- path_dwim(basedir, role_name),
+ path_dwim(basedir, os.path.join("roles", role_name[-1])),
+ path_dwim(basedir, role_name[-1]),
# if included from roles/[role]/meta/main.yml
- path_dwim(basedir, os.path.join("..", "..", "..", "roles", role_name)),
- path_dwim(basedir, os.path.join("..", "..", role_name)),
+ path_dwim(basedir, os.path.join("..", "..", "..", "roles", role_name[-1])),
+ path_dwim(basedir, os.path.join("..", "..", role_name[-1])),
# if checking a role in the current directory
- path_dwim(basedir, os.path.join("..", role_name)),
+ path_dwim(basedir, os.path.join("..", role_name[-1])),
]
+ if len(role_name) > 1:
+ # This ignores deeper structures than 1 level
+ possible_paths.append(path_dwim(basedir, os.path.join("roles", *role_name)))
+ possible_paths.append(path_dwim(basedir, os.path.join(*role_name)))
+ possible_paths.append(
+ path_dwim(basedir, os.path.join("..", "..", *role_name))
+ )
for loc in self.app.runtime.config.default_roles_path:
loc = os.path.expanduser(loc)
- possible_paths.append(path_dwim(loc, role_name))
+ possible_paths.append(path_dwim(loc, role_name[-1]))
if namespace_name and collection_name:
for loc in get_app(cached=True).runtime.config.collections_paths:
@@ -596,7 +603,7 @@
namespace_name,
collection_name,
"roles",
- role_name,
+ role_name[-1],
),
),
)
@@ -1160,8 +1167,8 @@
yaml.constructor.ConstructorError,
ruamel.yaml.parser.ParserError,
) as exc:
- msg = f"Failed to load YAML file: {lintable.path}"
- raise RuntimeError(msg) from exc
+ msg = "Failed to load YAML file"
+ raise RuntimeError(msg, lintable.path) from exc
if len(result) == 0:
return None # empty documents
@@ -1214,6 +1221,7 @@
"gather_facts",
"hosts",
"import_playbook",
+ "ansible.builtin.import_playbook",
"post_tasks",
"pre_tasks",
"roles",
@@ -1342,4 +1350,7 @@
def parse_fqcn(name: str) -> tuple[str, ...]:
"""Parse name parameter into FQCN segments."""
- return tuple(name.split(".")) if is_fqcn(name) else ("", "", name)
+ if not is_fqcn(name):
+ return ("", "", name)
+
+ return tuple(name.split("."))
diff -Nru ansible-lint-25.2.1/src/ansiblelint/yaml_utils.py ansible-lint-25.6.1/src/ansiblelint/yaml_utils.py
--- ansible-lint-25.2.1/src/ansiblelint/yaml_utils.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/src/ansiblelint/yaml_utils.py 2025-06-19 09:30:13.000000000 +0200
@@ -1,5 +1,6 @@
"""Utility helpers to simplify working with yaml-based data."""
+# cspell: ignore docinfo
# pylint: disable=too-many-lines
from __future__ import annotations
@@ -17,6 +18,7 @@
from ruamel.yaml.comments import CommentedMap, CommentedSeq, Format
from ruamel.yaml.composer import ComposerError
from ruamel.yaml.constructor import RoundTripConstructor
+from ruamel.yaml.docinfo import Version
from ruamel.yaml.emitter import Emitter, ScalarAnalysis
# Module 'ruamel.yaml' does not explicitly export attribute 'YAML'; implicit reexport disabled
@@ -1028,7 +1030,7 @@
return None
@version.setter
- def version(self, val: tuple[int, int] | None) -> None:
+ def version(self, val: str | tuple[int, int] | list[int] | Version | None) -> None:
"""Ensure that yaml version uses our default value.
The yaml Reader updates this value based on the ``%YAML`` directive in files.
@@ -1036,7 +1038,15 @@
But, None effectively resets the parsing version to YAML 1.2 (ruamel's default).
"""
if val is not None:
- self._yaml_version = val
+ if isinstance(val, tuple):
+ self._yaml_version = val
+ elif isinstance(val, list):
+ self._yaml_version = (val[0], val[1])
+ elif isinstance(val, Version):
+ self._yaml_version = (val.major, val.minor)
+ else:
+ msg = f"Unsupported argument {val}"
+ raise TypeError(msg)
elif hasattr(self, "_yaml_version_default"):
self._yaml_version = self._yaml_version_default
# We do nothing if the object did not have a previous default version defined
diff -Nru ansible-lint-25.2.1/test/rules/test_inline_env_var.py ansible-lint-25.6.1/test/rules/test_inline_env_var.py
--- ansible-lint-25.2.1/test/rules/test_inline_env_var.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/rules/test_inline_env_var.py 2025-06-19 09:30:13.000000000 +0200
@@ -59,6 +59,17 @@
command: echo
args:
strip_empty_ends: false
+
+ - name: Command with expand_argument_vars option
+ command:
+ cmd: /bin/echo $LITERAL
+ expand_argument_vars: false
+
+ - name: Mutually exclusive cmd and argv should not trigger a false-positive
+ ansible.builtin.command:
+ cmd: /bin/echo
+ argv:
+ - Hello
"""
FAIL_PLAY_TASKS = """
diff -Nru ansible-lint-25.2.1/test/schemas/f/ansible-navigator.json ansible-lint-25.6.1/test/schemas/f/ansible-navigator.json
--- ansible-lint-25.2.1/test/schemas/f/ansible-navigator.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/schemas/f/ansible-navigator.json 2025-06-19 09:30:13.000000000 +0200
@@ -287,7 +287,7 @@
"$ref": "#/$defs/EnvironmentVariablesModel"
},
"image": {
- "default": "quay.io/ansible/creator-ee:v0.2.0",
+ "default": "ghcr.io/ansible/community-ansible-dev-tools:latest",
"description": "Specify the name of the execution environment image",
"title": "Image",
"type": "string"
diff -Nru ansible-lint-25.2.1/test/schemas/f/meta.json ansible-lint-25.6.1/test/schemas/f/meta.json
--- ansible-lint-25.2.1/test/schemas/f/meta.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/schemas/f/meta.json 2025-06-19 09:30:13.000000000 +0200
@@ -378,6 +378,7 @@
"39",
"40",
"41",
+ "42",
"all"
],
"type": "string"
@@ -875,6 +876,7 @@
"21.02",
"22.03",
"23.05",
+ "24.10",
"all"
],
"type": "string"
@@ -1014,6 +1016,7 @@
"15SP3",
"15SP4",
"15SP5",
+ "15SP6",
"all"
],
"type": "string"
@@ -1129,6 +1132,8 @@
"maverick",
"natty",
"oneiric",
+ "oracular",
+ "plucky",
"precise",
"quantal",
"raring",
@@ -1504,7 +1509,7 @@
"versions": {
"default": "all",
"items": {
- "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "all"],
+ "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "8.0", "all"],
"type": "string"
},
"type": "array"
@@ -1523,7 +1528,7 @@
"versions": {
"default": "all",
"items": {
- "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "all"],
+ "enum": ["5.5", "6.0", "6.5", "6.7", "7.0", "8.0", "all"],
"type": "string"
},
"type": "array"
diff -Nru ansible-lint-25.2.1/test/schemas/f/__store__.json ansible-lint-25.6.1/test/schemas/f/__store__.json
--- ansible-lint-25.2.1/test/schemas/f/__store__.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/schemas/f/__store__.json 2025-06-19 09:30:13.000000000 +0200
@@ -24,7 +24,7 @@
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json"
},
"meta": {
- "etag": "62cce45a9b8bd96872d8ee1c465d3ff6b60facf6a4aeba5c2e128df02b5f52a5",
+ "etag": "60f3ce2a78ec4fb705c589da409a384ac97315e17810379c5049169986ce3097",
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json"
},
"meta-runtime": {
diff -Nru ansible-lint-25.2.1/test/schemas/package.json ansible-lint-25.6.1/test/schemas/package.json
--- ansible-lint-25.2.1/test/schemas/package.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/schemas/package.json 2025-06-19 09:30:13.000000000 +0200
@@ -4,7 +4,7 @@
"js-yaml": "^4.1.0",
"safe-stable-stringify": "^2.5.0",
"ts-node": "^10.9.2",
- "vscode-json-languageservice": "^5.4.3"
+ "vscode-json-languageservice": "^5.5.0"
},
"scripts": {
"compile": "tsc",
@@ -12,15 +12,15 @@
"test": "python3 src/rebuild.py && mocha"
},
"devDependencies": {
- "@types/chai": "^5.2.0",
+ "@types/chai": "^5.2.2",
"@types/js-yaml": "^4.0.9",
"@types/minimatch": "^5.1.2",
"@types/mocha": "^10.0.10",
- "@types/node": "^22.13.10",
+ "@types/node": "^22.15.25",
"chai": "^5.2.0",
"minimatch": "^10.0.1",
- "mocha": "^11.1.0",
- "typescript": "^5.8.2"
+ "mocha": "^11.5.0",
+ "typescript": "^5.8.3"
},
"directories": {
"test": "./src"
diff -Nru ansible-lint-25.2.1/test/schemas/package-lock.json ansible-lint-25.6.1/test/schemas/package-lock.json
--- ansible-lint-25.2.1/test/schemas/package-lock.json 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/schemas/package-lock.json 2025-06-19 09:30:13.000000000 +0200
@@ -9,18 +9,18 @@
"js-yaml": "^4.1.0",
"safe-stable-stringify": "^2.5.0",
"ts-node": "^10.9.2",
- "vscode-json-languageservice": "^5.4.3"
+ "vscode-json-languageservice": "^5.5.0"
},
"devDependencies": {
- "@types/chai": "^5.2.0",
+ "@types/chai": "^5.2.2",
"@types/js-yaml": "^4.0.9",
"@types/minimatch": "^5.1.2",
"@types/mocha": "^10.0.10",
- "@types/node": "^22.13.10",
+ "@types/node": "^22.15.25",
"chai": "^5.2.0",
"minimatch": "^10.0.1",
- "mocha": "^11.1.0",
- "typescript": "^5.8.2"
+ "mocha": "^11.5.0",
+ "typescript": "^5.8.3"
}
},
"node_modules/@cspotcode/source-map-support": {
@@ -191,9 +191,9 @@
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA=="
},
"node_modules/@types/chai": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.0.tgz",
- "integrity": "sha512-FWnQYdrG9FAC8KgPVhDFfrPL1FBsL3NtIt2WsxKvwu/61K6HiuDF3xAb7c7w/k9ML2QOUHcwTgU7dKLFPK6sBg==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -227,12 +227,12 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "22.13.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
- "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
+ "version": "22.15.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.25.tgz",
+ "integrity": "sha512-RJCAZ1E7JgMDJRnyVwIvlnKnNa0oHXrgSeq5aoXdhxCOSuwCe9sccKnngOJq8GuukzSf45u4VeD0JxUXfC3Dwg==",
"license": "MIT",
"dependencies": {
- "undici-types": "~6.20.0"
+ "undici-types": "~6.21.0"
}
},
"node_modules/@vscode/l10n": {
@@ -290,15 +290,6 @@
}
}
},
- "node_modules/ansi-colors": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
- "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -323,19 +314,6 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -361,15 +339,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
- "node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -379,18 +348,6 @@
"balanced-match": "^1.0.0"
}
},
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
@@ -464,30 +421,19 @@
}
},
"node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- ],
+ "license": "MIT",
"dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
+ "readdirp": "^4.0.1"
},
"engines": {
- "node": ">= 8.10.0"
+ "node": ">= 14.16.0"
},
- "optionalDependencies": {
- "fsevents": "~2.3.2"
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
}
},
"node_modules/cliui": {
@@ -587,10 +533,11 @@
}
},
"node_modules/diff": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
- "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -634,18 +581,6 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -688,20 +623,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -741,18 +662,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/glob/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -787,27 +696,6 @@
"he": "bin/he"
}
},
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -817,27 +705,6 @@
"node": ">=8"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
"node_modules/is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
@@ -981,24 +848,25 @@
}
},
"node_modules/mocha": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
- "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.5.0.tgz",
+ "integrity": "sha512-VKDjhy6LMTKm0WgNEdlY77YVsD49LZnPSXJAaPNL9NRYQADxvORsyG1DIQY6v53BKTnlNbEE2MbVCDbnxr4K3w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-colors": "^4.1.3",
"browser-stdout": "^1.3.1",
- "chokidar": "^3.5.3",
+ "chokidar": "^4.0.1",
"debug": "^4.3.5",
- "diff": "^5.2.0",
+ "diff": "^7.0.0",
"escape-string-regexp": "^4.0.0",
"find-up": "^5.0.0",
"glob": "^10.4.5",
"he": "^1.2.0",
"js-yaml": "^4.1.0",
"log-symbols": "^4.1.0",
- "minimatch": "^5.1.6",
+ "minimatch": "^9.0.5",
"ms": "^2.1.3",
+ "picocolors": "^1.1.1",
"serialize-javascript": "^6.0.2",
"strip-json-comments": "^3.1.1",
"supports-color": "^8.1.1",
@@ -1016,15 +884,19 @@
}
},
"node_modules/mocha/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ms": {
@@ -1033,15 +905,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -1124,17 +987,12 @@
"node": ">= 14.16"
}
},
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
+ "license": "ISC"
},
"node_modules/punycode": {
"version": "2.1.1",
@@ -1154,15 +1012,17 @@
}
},
"node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
+ "license": "MIT",
"engines": {
- "node": ">=8.10.0"
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
}
},
"node_modules/require-directory": {
@@ -1339,18 +1199,6 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
"node_modules/ts-node": {
"version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
@@ -1402,9 +1250,9 @@
}
},
"node_modules/typescript": {
- "version": "5.8.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
- "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -1415,9 +1263,9 @@
}
},
"node_modules/undici-types": {
- "version": "6.20.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
- "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"license": "MIT"
},
"node_modules/uri-js": {
@@ -1434,15 +1282,16 @@
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"node_modules/vscode-json-languageservice": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.4.3.tgz",
- "integrity": "sha512-NVSEQDloP9NYccuqKg4eI46kutZpwucBY4csBB6FCxbM7AZVoBt0oxTItPVA+ZwhnG1bg/fmiBRAwcGJyNQoPA==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.5.0.tgz",
+ "integrity": "sha512-JchBzp8ArzhCVpRS/LT4wzEEvwHXIUEdZD064cGTI4RVs34rNCZXPUguIYSfGBcHH1GV79ufPcfy3Pd8+ukbKw==",
+ "license": "MIT",
"dependencies": {
"@vscode/l10n": "^0.0.18",
"jsonc-parser": "^3.3.1",
"vscode-languageserver-textdocument": "^1.0.12",
"vscode-languageserver-types": "^3.17.5",
- "vscode-uri": "^3.0.8"
+ "vscode-uri": "^3.1.0"
}
},
"node_modules/vscode-languageserver-textdocument": {
@@ -1457,9 +1306,10 @@
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
},
"node_modules/vscode-uri": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
- "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
+ "license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
@@ -1712,9 +1562,9 @@
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA=="
},
"@types/chai": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.0.tgz",
- "integrity": "sha512-FWnQYdrG9FAC8KgPVhDFfrPL1FBsL3NtIt2WsxKvwu/61K6HiuDF3xAb7c7w/k9ML2QOUHcwTgU7dKLFPK6sBg==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
"dev": true,
"requires": {
"@types/deep-eql": "*"
@@ -1745,11 +1595,11 @@
"dev": true
},
"@types/node": {
- "version": "22.13.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
- "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
+ "version": "22.15.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.25.tgz",
+ "integrity": "sha512-RJCAZ1E7JgMDJRnyVwIvlnKnNa0oHXrgSeq5aoXdhxCOSuwCe9sccKnngOJq8GuukzSf45u4VeD0JxUXfC3Dwg==",
"requires": {
- "undici-types": "~6.20.0"
+ "undici-types": "~6.21.0"
}
},
"@vscode/l10n": {
@@ -1786,12 +1636,6 @@
"ajv": "^8.0.0"
}
},
- "ansi-colors": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
- "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true
- },
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -1807,16 +1651,6 @@
"color-convert": "^2.0.1"
}
},
- "anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -1839,12 +1673,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
- "binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true
- },
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -1854,15 +1682,6 @@
"balanced-match": "^1.0.0"
}
},
- "braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "requires": {
- "fill-range": "^7.1.1"
- }
- },
"browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
@@ -1916,19 +1735,12 @@
"dev": true
},
"chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
"requires": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "fsevents": "~2.3.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
+ "readdirp": "^4.0.1"
}
},
"cliui": {
@@ -2003,9 +1815,9 @@
"dev": true
},
"diff": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
- "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
"dev": true
},
"eastasianwidth": {
@@ -2037,15 +1849,6 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
- "fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
"find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -2072,13 +1875,6 @@
"signal-exit": "^4.0.1"
}
},
- "fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "optional": true
- },
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -2116,15 +1912,6 @@
}
}
},
- "glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "requires": {
- "is-glob": "^4.0.1"
- }
- },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -2137,42 +1924,12 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
- "is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "requires": {
- "binary-extensions": "^2.0.0"
- }
- },
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
- "dev": true
- },
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
- "is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.1"
- }
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
@@ -2274,24 +2031,24 @@
"dev": true
},
"mocha": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
- "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.5.0.tgz",
+ "integrity": "sha512-VKDjhy6LMTKm0WgNEdlY77YVsD49LZnPSXJAaPNL9NRYQADxvORsyG1DIQY6v53BKTnlNbEE2MbVCDbnxr4K3w==",
"dev": true,
"requires": {
- "ansi-colors": "^4.1.3",
"browser-stdout": "^1.3.1",
- "chokidar": "^3.5.3",
+ "chokidar": "^4.0.1",
"debug": "^4.3.5",
- "diff": "^5.2.0",
+ "diff": "^7.0.0",
"escape-string-regexp": "^4.0.0",
"find-up": "^5.0.0",
"glob": "^10.4.5",
"he": "^1.2.0",
"js-yaml": "^4.1.0",
"log-symbols": "^4.1.0",
- "minimatch": "^5.1.6",
+ "minimatch": "^9.0.5",
"ms": "^2.1.3",
+ "picocolors": "^1.1.1",
"serialize-javascript": "^6.0.2",
"strip-json-comments": "^3.1.1",
"supports-color": "^8.1.1",
@@ -2302,9 +2059,9 @@
},
"dependencies": {
"minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
@@ -2318,12 +2075,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
- },
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -2376,10 +2127,10 @@
"integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
"dev": true
},
- "picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true
},
"punycode": {
@@ -2397,13 +2148,10 @@
}
},
"readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "requires": {
- "picomatch": "^2.2.1"
- }
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true
},
"require-directory": {
"version": "2.1.1",
@@ -2512,15 +2260,6 @@
"has-flag": "^4.0.0"
}
},
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
- },
"ts-node": {
"version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
@@ -2549,14 +2288,14 @@
}
},
"typescript": {
- "version": "5.8.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
- "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="
},
"undici-types": {
- "version": "6.20.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
- "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
},
"uri-js": {
"version": "4.4.1",
@@ -2572,15 +2311,15 @@
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"vscode-json-languageservice": {
- "version": "5.4.3",
- "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.4.3.tgz",
- "integrity": "sha512-NVSEQDloP9NYccuqKg4eI46kutZpwucBY4csBB6FCxbM7AZVoBt0oxTItPVA+ZwhnG1bg/fmiBRAwcGJyNQoPA==",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.5.0.tgz",
+ "integrity": "sha512-JchBzp8ArzhCVpRS/LT4wzEEvwHXIUEdZD064cGTI4RVs34rNCZXPUguIYSfGBcHH1GV79ufPcfy3Pd8+ukbKw==",
"requires": {
"@vscode/l10n": "^0.0.18",
"jsonc-parser": "^3.3.1",
"vscode-languageserver-textdocument": "^1.0.12",
"vscode-languageserver-types": "^3.17.5",
- "vscode-uri": "^3.0.8"
+ "vscode-uri": "^3.1.0"
}
},
"vscode-languageserver-textdocument": {
@@ -2594,9 +2333,9 @@
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
},
"vscode-uri": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
- "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="
},
"which": {
"version": "2.0.2",
diff -Nru ansible-lint-25.2.1/test/test_config.py ansible-lint-25.6.1/test/test_config.py
--- ansible-lint-25.2.1/test/test_config.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_config.py 2025-06-19 09:30:13.000000000 +0200
@@ -12,6 +12,6 @@
for rule in default_rules_collection.rules:
if profile_rule_id == rule.id:
forbidden_tags = profile_banned_tags & set(rule.tags)
- assert (
- not forbidden_tags
- ), f"Rule {profile_rule_id} from {name} profile cannot use {profile_banned_tags & set(rule.tags)} tag."
+ assert not forbidden_tags, (
+ f"Rule {profile_rule_id} from {name} profile cannot use {profile_banned_tags & set(rule.tags)} tag."
+ )
diff -Nru ansible-lint-25.2.1/test/test_file_utils.py ansible-lint-25.6.1/test/test_file_utils.py
--- ansible-lint-25.2.1/test/test_file_utils.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_file_utils.py 2025-06-19 09:30:13.000000000 +0200
@@ -98,13 +98,13 @@
my_options.lintables = [str(lint_path)]
files = file_utils.discover_lintables(my_options)
stderr = capsys.readouterr().err
- assert (
- not stderr
- ), f"No stderr output is expected when the verbosity is off, got: {stderr}"
- assert (
- len(files) == yaml_count
- ), "Expected to find {yaml_count} yaml files in {lint_path}".format_map(
- locals(),
+ assert not stderr, (
+ f"No stderr output is expected when the verbosity is off, got: {stderr}"
+ )
+ assert len(files) == yaml_count, (
+ "Expected to find {yaml_count} yaml files in {lint_path}".format_map(
+ locals(),
+ )
)
diff -Nru ansible-lint-25.2.1/test/test_loaders.py ansible-lint-25.6.1/test/test_loaders.py
--- ansible-lint-25.2.1/test/test_loaders.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_loaders.py 2025-06-19 09:30:13.000000000 +0200
@@ -6,7 +6,14 @@
from pathlib import Path
from textwrap import dedent
-from ansiblelint.loaders import IGNORE_FILE, load_ignore_txt
+import pytest
+
+from ansiblelint.loaders import (
+ IGNORE_FILE,
+ IgnoreRule,
+ IgnoreRuleQualifier,
+ load_ignore_txt,
+)
def test_load_ignore_txt_default_empty() -> None:
@@ -35,6 +42,7 @@
# See https://ansible.readthedocs.io/projects/lint/configuring/#ignoring-rules-for-entire-files
playbook2.yml package-latest # comment
playbook2.yml foo-bar
+ playbook2.yml another-role skip # rule with qualifier
""",
),
)
@@ -47,7 +55,13 @@
finally:
os.chdir(cwd)
- assert result == {"playbook2.yml": {"package-latest", "foo-bar"}}
+ assert result == {
+ "playbook2.yml": {
+ IgnoreRule("package-latest", frozenset()),
+ IgnoreRule("foo-bar", frozenset()),
+ IgnoreRule("another-role", frozenset([IgnoreRuleQualifier.SKIP])),
+ }
+ }
def test_load_ignore_txt_default_success_alternative() -> None:
@@ -76,8 +90,11 @@
os.chdir(cwd)
assert result == {
- "playbook.yml": {"more-foo", "foo-bar"},
- "tasks/main.yml": {"more-bar"},
+ "playbook.yml": {
+ IgnoreRule("more-foo", frozenset()),
+ IgnoreRule("foo-bar", frozenset()),
+ },
+ "tasks/main.yml": {IgnoreRule("more-bar", frozenset())},
}
@@ -108,10 +125,10 @@
os.chdir(cwd)
assert result == {
- "playbook.yml": {"hector"},
- "roles/eduardo/tasks/main.yml": {"lalo"},
- "roles/guzman/tasks/main.yml": {"lalo"},
- "vars/main.yml": {"tuco"},
+ "playbook.yml": {IgnoreRule("hector", frozenset())},
+ "roles/eduardo/tasks/main.yml": {IgnoreRule("lalo", frozenset())},
+ "roles/guzman/tasks/main.yml": {IgnoreRule("lalo", frozenset())},
+ "vars/main.yml": {IgnoreRule("tuco", frozenset())},
}
@@ -120,3 +137,22 @@
result = load_ignore_txt(Path(str(uuid.uuid4())))
assert not result
+
+
+def test_load_ignore_txt_invalid_tags(monkeypatch: pytest.MonkeyPatch) -> None:
+ """Test load_ignore_txt with an existing ignore-file in the default location."""
+ with tempfile.TemporaryDirectory() as temporary_directory:
+ ignore_file = Path(temporary_directory) / IGNORE_FILE.default
+
+ with ignore_file.open("w", encoding="utf-8") as _ignore_file:
+ _ignore_file.write(
+ dedent(
+ """
+ playbook2.yml package-latest invalid-tag
+ """,
+ ),
+ )
+
+ monkeypatch.chdir(temporary_directory)
+ with pytest.raises(RuntimeError, match="Unable to parse line"):
+ load_ignore_txt()
diff -Nru ansible-lint-25.2.1/test/test_main.py ansible-lint-25.6.1/test/test_main.py
--- ansible-lint-25.2.1/test/test_main.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_main.py 2025-06-19 09:30:13.000000000 +0200
@@ -8,6 +8,7 @@
import time
from collections.abc import Mapping
from http.client import RemoteDisconnected
+from os.path import abspath
from pathlib import Path
import pytest
@@ -159,8 +160,9 @@
for x in (
"Invalid type for configuration option setting: CACHE_PLUGIN_TIMEOUT",
"has an invalid value: Invalid type provided for 'int': 'invalid-value'",
+ "has an invalid value: Invalid value provided for 'integer': 'invalid-value'",
)
- )
+ ), proc.stderr
def test_list_tags() -> None:
@@ -179,3 +181,30 @@
assert isinstance(value, list)
for item in value:
assert isinstance(item, str)
+
+
+def test_ro_venv() -> None:
+ """Tests behavior when the virtual environment is read-only."""
+ tox_work_dir = os.environ.get("TOX_WORK_DIR", ".tox")
+ venv_path = f"{tox_work_dir}/ro"
+ commands = [
+ f"mkdir -p {venv_path}",
+ f"chmod -R a+w {venv_path}",
+ f"rm -rf {venv_path}",
+ f"python -m venv --symlinks {venv_path}",
+ f"{venv_path}/bin/python -m pip install -q -e .",
+ f"chmod -R a-w {venv_path}",
+ # running with a ro venv and default cwd
+ f"{venv_path}/bin/ansible-lint --version",
+ # running from a read-only cwd:
+ f"cd / && {abspath(venv_path)}/bin/ansible-lint --version", # noqa: PTH100
+ # running with a ro venv and a custom project path in forced non-online mode, so it will need to install requirements
+ f"{venv_path}/bin/ansible-lint -vv --no-offline --project-dir ./examples/reqs_v2/ ./examples/reqs_v2/",
+ ]
+ for cmd in commands:
+ result = subprocess.run(
+ cmd, capture_output=True, shell=True, text=True, check=False
+ )
+ assert result.returncode == 0, (
+ f"Got {result.returncode} running {cmd}\n\tstderr: {result.stderr}\n\tstdout: {result.stdout}"
+ )
diff -Nru ansible-lint-25.2.1/test/test_profiles.py ansible-lint-25.6.1/test/test_profiles.py
--- ansible-lint-25.2.1/test/test_profiles.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_profiles.py 2025-06-19 09:30:13.000000000 +0200
@@ -21,9 +21,9 @@
assert len(collection.rules) == 5, "Failed to register new rule."
filter_rules_with_profile(collection.rules, "min")
- assert (
- len(collection.rules) == 4
- ), "Failed to unload rule that is not part of 'min' profile."
+ assert len(collection.rules) == 4, (
+ "Failed to unload rule that is not part of 'min' profile."
+ )
def test_profile_listing(capfd: CaptureFixture[str]) -> None:
@@ -58,6 +58,6 @@
continue
err_lines.append(line)
if all(word not in platform_name for word in ["wsl", "microsoft"]) and err_lines:
- assert (
- not err_lines
- ), f"Unexpected stderr output found while running on {platform_name} platform:\n{err_lines}"
+ assert not err_lines, (
+ f"Unexpected stderr output found while running on {platform_name} platform:\n{err_lines}"
+ )
diff -Nru ansible-lint-25.2.1/test/test_rules_collection.py ansible-lint-25.6.1/test/test_rules_collection.py
--- ansible-lint-25.2.1/test/test_rules_collection.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_rules_collection.py 2025-06-19 09:30:13.000000000 +0200
@@ -169,9 +169,9 @@
rule.id,
), f"Rule id {rule.id} did not match our required format."
keys.add(rule.id)
- assert (
- rule.help or rule.description or rule.__doc__
- ), f"Rule {rule.id} must have at least one of: .help, .description, .__doc__"
+ assert rule.help or rule.description or rule.__doc__, (
+ f"Rule {rule.id} must have at least one of: .help, .description, .__doc__"
+ )
assert "yaml" in keys, "yaml rule is missing"
assert len(rules) == 51 # update this number when adding new rules!
assert len(keys) == len(rules), "Duplicate rule ids?"
diff -Nru ansible-lint-25.2.1/test/test_runner.py ansible-lint-25.6.1/test/test_runner.py
--- ansible-lint-25.2.1/test/test_runner.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_runner.py 2025-06-19 09:30:13.000000000 +0200
@@ -241,6 +241,25 @@
assert result[0].tag == "load-failure[not-found]"
+def test_runner_load_failure_yaml(default_rules_collection: RulesCollection) -> None:
+ """Ensure load-failure[yaml] work as expected."""
+ checked_files: set[Lintable] = set()
+
+ filename = Path("examples/broken/load-failure-invalid.yml").resolve()
+ runner = Runner(
+ filename,
+ rules=default_rules_collection,
+ verbosity=0,
+ checked_files=checked_files,
+ )
+ result = runner.run()
+ assert len(runner.checked_files) == 1
+ assert len(result) == 1
+ assert result[0].tag == "load-failure[yaml]"
+ assert result[0].lineno == 5
+ assert result[0].column == 1
+
+
def test_runner_tmp_file(
tmp_path: Path,
default_rules_collection: RulesCollection,
diff -Nru ansible-lint-25.2.1/test/test_schemas.py ansible-lint-25.6.1/test/test_schemas.py
--- ansible-lint-25.2.1/test/test_schemas.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_schemas.py 2025-06-19 09:30:13.000000000 +0200
@@ -47,10 +47,8 @@
) -> 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( # pyright: ignore[reportAttributeAccessIssue]
- TimeoutError(error_msg)
- )
+ mock_request.urlopen.side_effect = urllib.error.URLError( # pyright: ignore[reportAttributeAccessIssue]
+ TimeoutError(error_msg)
)
with caplog.at_level(logging.DEBUG):
assert refresh_schemas(min_age_seconds=0) == 0
diff -Nru ansible-lint-25.2.1/test/test_skiputils.py ansible-lint-25.6.1/test/test_skiputils.py
--- ansible-lint-25.2.1/test/test_skiputils.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_skiputils.py 2025-06-19 09:30:13.000000000 +0200
@@ -64,6 +64,15 @@
assert len(results) == 1
+def test_var_noqa(default_text_runner: RunFromText) -> None:
+ """Check that noqa is properly taken into account on vars and tasks."""
+ results = default_text_runner.run(
+ Path("examples/playbooks/vars/noqa_multiline.yml")
+ )
+ # Should raise no error at "SOME_VAR".
+ assert len(results) == 0
+
+
@pytest.mark.parametrize(
("lintable", "yaml", "expected_form"),
(
diff -Nru ansible-lint-25.2.1/test/test_utils.py ansible-lint-25.6.1/test/test_utils.py
--- ansible-lint-25.2.1/test/test_utils.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/test/test_utils.py 2025-06-19 09:30:13.000000000 +0200
@@ -338,7 +338,11 @@
def test_is_playbook() -> None:
"""Verify that we can detect a playbook as a playbook."""
- assert utils.is_playbook("examples/playbooks/always-run-success.yml")
+ assert utils.is_playbook(filename="examples/playbooks/always-run-success.yml")
+ assert utils.is_playbook(
+ filename="examples/playbooks/import-failed-syntax-check.yml"
+ )
+ assert utils.is_playbook(filename="examples/playbooks/import_playbook_fqcn.yml")
@pytest.mark.parametrize(
@@ -538,3 +542,15 @@
"Failed to find local.testcollection.test.bar.foo playbook."
not in result.stderr
)
+
+
+def test_import_role_children_subdirs() -> None:
+ """Verify import_playbook_children()."""
+ result = run_ansible_lint(
+ Path("playbooks/import_role_fqcn.yml"),
+ cwd=Path(__file__).resolve().parent.parent / "examples",
+ env={
+ "ANSIBLE_COLLECTIONS_PATH": "../collections",
+ },
+ )
+ assert "Failed " not in result.stderr
diff -Nru ansible-lint-25.2.1/tools/generate_docs.py ansible-lint-25.6.1/tools/generate_docs.py
--- ansible-lint-25.2.1/tools/generate_docs.py 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/tools/generate_docs.py 2025-06-19 09:30:13.000000000 +0200
@@ -11,7 +11,7 @@
from ansiblelint.rules import RulesCollection, TransformMixin
if __name__ == "__main__":
- subprocess.run( # noqa: S603
+ subprocess.run(
["ansible-lint", "--list-rules"], # noqa: S607
check=True,
stdout=subprocess.DEVNULL,
diff -Nru ansible-lint-25.2.1/tools/report-coverage ansible-lint-25.6.1/tools/report-coverage
--- ansible-lint-25.2.1/tools/report-coverage 1970-01-01 01:00:00.000000000 +0100
+++ ansible-lint-25.6.1/tools/report-coverage 2025-06-19 09:30:13.000000000 +0200
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -euo pipefail
+coverage combine -q "--data-file=${TOX_ENV_DIR}/.coverage" "${TOX_ENV_DIR}"/.coverage.*
+coverage xml "--data-file=${TOX_ENV_DIR}/.coverage" -o "${TOX_ENV_DIR}/coverage.xml" --ignore-errors --fail-under=0
+COVERAGE_FILE="${TOX_ENV_DIR}/.coverage" coverage report --fail-under=0 --ignore-errors
diff -Nru ansible-lint-25.2.1/tox.ini ansible-lint-25.6.1/tox.ini
--- ansible-lint-25.2.1/tox.ini 2025-04-03 13:56:32.000000000 +0200
+++ ansible-lint-25.6.1/tox.ini 2025-06-19 09:30:13.000000000 +0200
@@ -37,7 +37,6 @@
LC_*
NO_COLOR
PYTEST_*
- PYTEST_REQPASS
PYTHON*
PYTHONBREAKPOINT
PYTHONIOENCODING
@@ -56,7 +55,6 @@
PIP_CONSTRAINT = {tox_root}/.config/constraints.txt
PIP_DISABLE_PIP_VERSION_CHECK = 1
PRE_COMMIT_COLOR = always
- PYTEST_REQPASS = 908
UV_CONSTRAINT = {tox_root}/.config/constraints.txt
deps, devel, hook, lint, pkg, pre, py310, schemas: PIP_CONSTRAINT = /dev/null
deps, devel, hook, lint, pkg, pre, py310, schemas: UV_CONSTRAINT = /dev/null
@@ -77,9 +75,12 @@
--showlocals \
--doctest-modules \
--durations=10 \
+ --junitxml=./junit.xml \
}
- {py,py310,py311,py312,py313}: sh -c "coverage combine -a -q --data-file={env_dir}/.coverage {work_dir}/*/.coverage.* && coverage xml --data-file={env_dir}/.coverage -o {env_dir}/coverage.xml --fail-under=0 && coverage report --data-file={env_dir}/.coverage"
+commands_post =
+ {py,py310,py311,py312,py313}: ./tools/report-coverage
allowlist_externals =
+ ./tools/report-coverage
./tools/test-hook.sh
bash
find
@@ -116,8 +117,9 @@
twine>=4.0.1
commands_pre =
commands =
- bash -c "PIPX_BIN_DIR={work_dir}/.pipx/bin PIPX_HOME={work_dir}/.pipx pipx install --force -e ."
- bash -c "if stderr=$({work_dir}/.pipx/bin/ansible-lint --version >/dev/null) && test -z \"$stderr\"; then echo "ok"; fi"
+ bash -ec "rm -rf src/*.egg-info"
+ bash -ec "PIPX_BIN_DIR={work_dir}/.pipx/bin; PIPX_HOME={work_dir}/.pipx; pipx uninstall ansible-lint >/dev/null || true; pipx install --force -e ."
+ bash -ec "if stderr=$({work_dir}/.pipx/bin/ansible-lint --version >/dev/null) && test -z \"$stderr\"; then echo \"ok\"; fi"
{env_python} -c 'import os.path, shutil, sys; \
dist_dir = os.path.join("{tox_root}", "dist"); \
os.path.isdir(dist_dir) or sys.exit(0); \
@@ -172,8 +174,6 @@
{[testenv]deps}
extras =
test
-set_env =
- PYTEST_REQPASS = 7
commands =
sh -c tools/test-eco.sh
allowlist_externals =
Reply to: