Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-ansible-compat for
openSUSE:Factory checked in at 2023-09-07 21:13:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ansible-compat (Old)
and /work/SRC/openSUSE:Factory/.python-ansible-compat.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ansible-compat"
Thu Sep 7 21:13:32 2023 rev:19 rq:1109447 version:4.1.10
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-ansible-compat/python-ansible-compat.changes
2023-07-24 18:26:12.422234921 +0200
+++
/work/SRC/openSUSE:Factory/.python-ansible-compat.new.1766/python-ansible-compat.changes
2023-09-07 21:14:58.482096268 +0200
@@ -1,0 +2,49 @@
+Wed Sep 6 15:25:15 UTC 2023 - Johannes Kastl <[email protected]>
+
+- fix BuildRequires and Requires
+- ignore 4 new checks that need internet connectivity
+ * test_scan_sys_path[isolatedT-scanT-raises_not_foundT]
+ * test_scan_sys_path[isolatedT-scanF-raises_not_foundT]
+ * test_scan_sys_path[isolatedF-scanT-raises_not_foundF]
+ * test_scan_sys_path[isolatedF-scanF-raises_not_foundT]
+- update to 4.1.10:
+ * Bugfixes
+ - Catch empty collection lists (#332) @lod
+
+-------------------------------------------------------------------
+Wed Sep 6 14:55:28 UTC 2023 - Johannes Kastl <[email protected]>
+
+- update to 4.1.9:
+ * Bugfixes
+ - Automatically add --pre when installing collections from git
+ repositories @ssbarnea
+
+-------------------------------------------------------------------
+Wed Sep 6 06:01:26 UTC 2023 - Johannes Kastl <[email protected]>
+
+- update to 4.1.8:
+ * Bugfixes
+ - Revise site packages collection search test (#325) @cidrblock
+ - Add only those sys.paths which contain an ansible_collections
+ directory path (#322) @ajinkyau
+ - Allow git dependencies in galaxy.yml files (#321) @ssbarnea
+
+-------------------------------------------------------------------
+Wed Sep 6 05:44:29 UTC 2023 - Johannes Kastl <[email protected]>
+
+- update to 4.1.7:
+ * Bugfixes
+ - Add `sys.path` to collection paths (#318) @cidrblock
+
+-------------------------------------------------------------------
+Wed Sep 6 05:39:12 UTC 2023 - Johannes Kastl <[email protected]>
+
+- update to 4.1.6:
+ * Bugfixes
+ - Fix logic on prepare environment (#310) @ssbarnea
+ - Add smoke testing with ansible-lint (#312) @ssbarnea
+ - Adapt collection install test to pass with ansible-core
+ 2.15.3 changes (#313) @ssbarnea
+ - Support meta main yaml extension (#304) @zhan9san
+
+-------------------------------------------------------------------
Old:
----
ansible-compat-4.1.5.tar.gz
New:
----
ansible-compat-4.1.10.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-ansible-compat.spec ++++++
--- /var/tmp/diff_new_pack.AyHXI3/_old 2023-09-07 21:14:59.498132589 +0200
+++ /var/tmp/diff_new_pack.AyHXI3/_new 2023-09-07 21:14:59.502132732 +0200
@@ -24,7 +24,7 @@
%endif
Name: python-ansible-compat
-Version: 4.1.5
+Version: 4.1.10
Release: 0
Summary: Compatibility shim for Ansible 2.9 and newer
License: MIT
@@ -36,18 +36,24 @@
BuildRequires: %{python_module wheel}
BuildRequires: python-rpm-macros
# SECTION test
-BuildRequires: %{python_module pytest}
+# https://github.com/ansible/ansible-compat/blob/main/pyproject.toml#L38
+BuildRequires: ansible-core >= 2.12
BuildRequires: %{python_module PyYAML}
-BuildRequires: %{python_module flaky}
BuildRequires: %{python_module jsonschema >= 4.17.3}
-BuildRequires: %{python_module pytest-mock}
BuildRequires: %{python_module subprocess-tee >= 0.4.1}
-BuildRequires: ansible-core >= 2.12
+# https://github.com/ansible/ansible-compat/blob/main/pyproject.toml#L56
+BuildRequires: %{python_module pytest}
+BuildRequires: %{python_module pytest-mock}
+BuildRequires: %{python_module pytest-plus}
# /SECTION
BuildRequires: fdupes
BuildRequires: python-rpm-generators
-%{?python_enable_dependency_generator}
+Requires: ansible-core >= 2.12
+Requires: python-PyYAML
+Requires: python-jsonschema >= 4.17.3
+Requires: python-packaging
Requires: python-subprocess-tee >= 0.4.1
+%{?python_enable_dependency_generator}
BuildArch: noarch
%python_subpackages
@@ -66,7 +72,22 @@
%check
# excluding tests requiring internet connection
-%pytest -k 'not (test_runtime_example or test_require_collection_no_cache_dir
or test_upgrade_collection or test_install_collection_dest or
test_install_collection or test_require_collection or
test_require_collection_wrong_version or test_prerun_reqs_v2 or
test_prerun_reqs_v1 or test_prepare_environment_with_collections or
test_runtime_require_module)' -W ignore:'There is no current event loop'
+IGNORED_CHECKS="test_install_collection"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_install_collection_dest"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_prepare_environment_with_collections"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_prerun_reqs_v1"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_prerun_reqs_v2"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_require_collection"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_require_collection_no_cache_dir"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_require_collection_wrong_version"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_runtime_example"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_runtime_require_module"
+IGNORED_CHECKS="${IGNORED_CHECKS} or
test_scan_sys_path[isolatedF-scanF-raises_not_foundT]"
+IGNORED_CHECKS="${IGNORED_CHECKS} or
test_scan_sys_path[isolatedF-scanT-raises_not_foundF]"
+IGNORED_CHECKS="${IGNORED_CHECKS} or
test_scan_sys_path[isolatedT-scanF-raises_not_foundT]"
+IGNORED_CHECKS="${IGNORED_CHECKS} or
test_scan_sys_path[isolatedT-scanT-raises_not_foundT]"
+IGNORED_CHECKS="${IGNORED_CHECKS} or test_upgrade_collection"
+%pytest -k "not (${IGNORED_CHECKS})"
%files %{python_files}
%{python_sitelib}/ansible_compat
++++++ _service ++++++
--- /var/tmp/diff_new_pack.AyHXI3/_old 2023-09-07 21:14:59.526133590 +0200
+++ /var/tmp/diff_new_pack.AyHXI3/_new 2023-09-07 21:14:59.530133733 +0200
@@ -1,5 +1,5 @@
<services>
- <service name="download_files" mode="disabled">
+ <service name="download_files" mode="manual">
</service>
</services>
++++++ ansible-compat-4.1.5.tar.gz -> ansible-compat-4.1.10.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/.github/workflows/release.yml
new/ansible-compat-4.1.10/.github/workflows/release.yml
--- old/ansible-compat-4.1.5/.github/workflows/release.yml 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/.github/workflows/release.yml 2023-09-06
14:55:41.000000000 +0200
@@ -30,7 +30,7 @@
- name: Install tox
run: python3 -m pip install --user "tox>=4.0.0"
- name: Check out src from Git
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 0 # needed by setuptools-scm
- name: Build dists
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/.github/workflows/tox.yml
new/ansible-compat-4.1.10/.github/workflows/tox.yml
--- old/ansible-compat-4.1.5/.github/workflows/tox.yml 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/.github/workflows/tox.yml 2023-09-06
14:55:41.000000000 +0200
@@ -33,6 +33,7 @@
py39-ansible214
py39-ansible215
py311-devel
+ smoke
platforms: linux,macos
macos: minmax
build:
@@ -47,7 +48,7 @@
steps:
- name: Check out src from Git
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 0 # needed by setuptools-scm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/.pre-commit-config.yaml
new/ansible-compat-4.1.10/.pre-commit-config.yaml
--- old/ansible-compat-4.1.5/.pre-commit-config.yaml 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/.pre-commit-config.yaml 2023-09-06
14:55:41.000000000 +0200
@@ -20,14 +20,14 @@
test/assets/.*
)$
repos:
- - repo: https://github.com/charliermarsh/ruff-pre-commit
- rev: "v0.0.277"
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: "v0.0.287"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/pre-commit/mirrors-prettier
# keep it before yamllint
- rev: "v3.0.0"
+ rev: "v3.0.3"
hooks:
- id: prettier
additional_dependencies:
@@ -62,12 +62,12 @@
types: [file, yaml]
entry: yamllint --strict
- repo: https://github.com/psf/black
- rev: 23.3.0
+ rev: 23.7.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.4.1
+ rev: v1.5.1
hooks:
- id: mypy
# empty args needed in order to match mypy cli behavior
@@ -84,7 +84,7 @@
- types-pkg_resources
- types-jsonschema>=4.4.9
- repo: https://github.com/pycqa/pylint
- rev: v3.0.0a6
+ rev: v3.0.0a7
hooks:
- id: pylint
additional_dependencies:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/PKG-INFO
new/ansible-compat-4.1.10/PKG-INFO
--- old/ansible-compat-4.1.5/PKG-INFO 2023-07-21 12:58:43.393725200 +0200
+++ new/ansible-compat-4.1.10/PKG-INFO 2023-09-06 14:56:06.785466000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ansible-compat
-Version: 4.1.5
+Version: 4.1.10
Summary: Ansible compatibility goodies
Author-email: Sorin Sbarnea <[email protected]>
Maintainer-email: Sorin Sbarnea <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-4.1.5/examples/reqs_v2/requirements.yml
new/ansible-compat-4.1.10/examples/reqs_v2/requirements.yml
--- old/ansible-compat-4.1.5/examples/reqs_v2/requirements.yml 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/examples/reqs_v2/requirements.yml 2023-09-06
14:55:41.000000000 +0200
@@ -9,3 +9,13 @@
name: geerlingguy.mysql
collections:
- name: community-molecule-0.1.0.tar.gz
+ # Also needed for testing purposes as this should trigger addition of --pre
+ # argument as this is required due to
+ # https://github.com/ansible/ansible-lint/issues/3686
+ # https://github.com/ansible/ansible/issues/79109
+ - name: https://github.com/ansible-collections/amazon.aws.git
+ type: git
+ version: main
+ - name: https://github.com/ansible-collections/community.aws.git
+ type: git
+ version: main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/pyproject.toml
new/ansible-compat-4.1.10/pyproject.toml
--- old/ansible-compat-4.1.5/pyproject.toml 2023-07-21 12:58:17.000000000
+0200
+++ new/ansible-compat-4.1.10/pyproject.toml 2023-09-06 14:55:41.000000000
+0200
@@ -120,6 +120,7 @@
[tool.pytest.ini_options]
# ensure we treat warnings as error
filterwarnings = ["error"]
+testpaths = ["test"]
[tool.ruff]
select = ["ALL"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/readthedocs.yml
new/ansible-compat-4.1.10/readthedocs.yml
--- old/ansible-compat-4.1.5/readthedocs.yml 2023-07-21 12:58:17.000000000
+0200
+++ new/ansible-compat-4.1.10/readthedocs.yml 2023-09-06 14:55:41.000000000
+0200
@@ -13,7 +13,6 @@
python: "3.11"
python:
- system_packages: false
install:
- method: pip
path: .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/requirements.txt
new/ansible-compat-4.1.10/requirements.txt
--- old/ansible-compat-4.1.5/requirements.txt 2023-07-21 12:58:17.000000000
+0200
+++ new/ansible-compat-4.1.10/requirements.txt 2023-09-06 14:55:41.000000000
+0200
@@ -4,25 +4,27 @@
#
# pip-compile --extra=docs --extra=test --output-file=requirements.txt
--strip-extras --unsafe-package=ansible-core --unsafe-package=resolvelib
--unsafe-package=typing_extensions pyproject.toml
#
-argparse-manpage==4.2
+argparse-manpage==4.3
# via ansible-compat (pyproject.toml)
attrs==23.1.0
- # via jsonschema
-beautifulsoup4==4.12.1
+ # via
+ # jsonschema
+ # referencing
+beautifulsoup4==4.12.2
# via
# mkdocs-ansible
# mkdocs-htmlproofer-plugin
-black==23.3.0
+black==23.7.0
# via ansible-compat (pyproject.toml)
build==0.10.0
# via pip-tools
-cairocffi==1.5.0
+cairocffi==1.5.1
# via
# cairosvg
# mkdocs-ansible
cairosvg==2.7.0
# via mkdocs-ansible
-certifi==2022.12.7
+certifi==2023.5.7
# via
# mkdocs-ansible
# requests
@@ -46,9 +48,9 @@
# griffe
# mkdocs-ansible
# mkdocs-material
-coverage==7.2.5
+coverage==7.3.0
# via ansible-compat (pyproject.toml)
-cryptography==40.0.2
+cryptography==41.0.3
# via ansible-core
csscompressor==0.9.5
# via
@@ -62,13 +64,13 @@
# via
# cairosvg
# mkdocs-ansible
-exceptiongroup==1.1.1
+exceptiongroup==1.1.3
# via pytest
ghp-import==2.1.0
# via
# mkdocs
# mkdocs-ansible
-griffe==0.26.0
+griffe==0.29.0
# via
# mkdocs-ansible
# mkdocstrings-python
@@ -80,11 +82,12 @@
# via
# mkdocs-ansible
# requests
-importlib-metadata==6.1.0
+importlib-metadata==6.6.0
# via
# markdown
# mkdocs
# mkdocs-ansible
+ # mkdocstrings
importlib-resources==5.0.7
# via ansible-core
iniconfig==2.0.0
@@ -100,8 +103,10 @@
# via
# mkdocs-ansible
# mkdocs-minify-plugin
-jsonschema==4.17.3
+jsonschema==4.19.0
# via ansible-compat (pyproject.toml)
+jsonschema-specifications==2023.7.1
+ # via jsonschema
markdown==3.3.7
# via
# markdown-include
@@ -112,7 +117,7 @@
# mkdocs-material
# mkdocstrings
# pymdown-extensions
-markdown-exec==1.4.0
+markdown-exec==1.6.0
# via mkdocs-ansible
markdown-include==0.8.1
# via mkdocs-ansible
@@ -125,7 +130,7 @@
# via
# mkdocs
# mkdocs-ansible
-mkdocs==1.4.2
+mkdocs==1.4.3
# via
# mkdocs-ansible
# mkdocs-autorefs
@@ -135,17 +140,17 @@
# mkdocs-minify-plugin
# mkdocs-monorepo-plugin
# mkdocstrings
-mkdocs-ansible==0.1.4
+mkdocs-ansible==0.1.6
# via ansible-compat (pyproject.toml)
mkdocs-autorefs==0.4.1
# via
# mkdocs-ansible
# mkdocstrings
-mkdocs-gen-files==0.4.0
+mkdocs-gen-files==0.5.0
# via mkdocs-ansible
-mkdocs-htmlproofer-plugin==0.11.0
+mkdocs-htmlproofer-plugin==0.13.1
# via mkdocs-ansible
-mkdocs-material==9.1.5
+mkdocs-material==9.1.15
# via mkdocs-ansible
mkdocs-material-extensions==1.1.1
# via
@@ -153,17 +158,17 @@
# mkdocs-material
mkdocs-minify-plugin==0.6.4
# via mkdocs-ansible
-mkdocs-monorepo-plugin==1.0.4
+mkdocs-monorepo-plugin==1.0.5
# via mkdocs-ansible
-mkdocstrings==0.21.2
+mkdocstrings==0.22.0
# via
# mkdocs-ansible
# mkdocstrings-python
-mkdocstrings-python==0.9.0
+mkdocstrings-python==1.1.0
# via mkdocs-ansible
mypy-extensions==1.0.0
# via black
-packaging==23.0
+packaging==23.1
# via
# ansible-compat (pyproject.toml)
# ansible-core
@@ -172,31 +177,31 @@
# mkdocs
# mkdocs-ansible
# pytest
-pathspec==0.11.1
+pathspec==0.11.2
# via black
pillow==9.5.0
# via
# cairosvg
# mkdocs-ansible
-pip==23.1.2
+pip==23.2.1
# via pip-tools
-pip-tools==6.13.0
+pip-tools==7.3.0
# via ansible-compat (pyproject.toml)
-pipdeptree==2.7.0
+pipdeptree==2.7.1
# via mkdocs-ansible
-platformdirs==3.5.1
+platformdirs==3.10.0
# via black
-pluggy==1.0.0
+pluggy==1.2.0
# via pytest
pycparser==2.21
# via
# cffi
# mkdocs-ansible
-pygments==2.14.0
+pygments==2.15.1
# via
# mkdocs-ansible
# mkdocs-material
-pymdown-extensions==9.10
+pymdown-extensions==10.0.1
# via
# markdown-exec
# mkdocs-ansible
@@ -204,14 +209,12 @@
# mkdocstrings
pyproject-hooks==1.0.0
# via build
-pyrsistent==0.19.3
- # via jsonschema
-pytest==7.3.1
+pytest==7.4.0
# via
# ansible-compat (pyproject.toml)
# pytest-mock
# pytest-plus
-pytest-mock==3.10.0
+pytest-mock==3.11.1
# via ansible-compat (pyproject.toml)
pytest-plus==0.4.0
# via ansible-compat (pyproject.toml)
@@ -235,22 +238,30 @@
# via
# mkdocs
# mkdocs-ansible
-regex==2023.3.23
+referencing==0.30.2
+ # via
+ # jsonschema
+ # jsonschema-specifications
+regex==2023.5.5
# via
# mkdocs-ansible
# mkdocs-material
-requests==2.28.2
+requests==2.31.0
# via
# mkdocs-ansible
# mkdocs-htmlproofer-plugin
# mkdocs-material
-setuptools==67.7.2
+rpds-py==0.9.2
+ # via
+ # jsonschema
+ # referencing
+setuptools==68.1.2
# via pip-tools
six==1.16.0
# via
# mkdocs-ansible
# python-dateutil
-soupsieve==2.4
+soupsieve==2.4.1
# via
# beautifulsoup4
# mkdocs-ansible
@@ -265,21 +276,21 @@
# cairosvg
# cssselect2
# mkdocs-ansible
-toml==0.10.2
- # via argparse-manpage
tomli==2.0.1
# via
+ # argparse-manpage
# black
# build
+ # pip-tools
# pyproject-hooks
# pytest
-typing-extensions==4.5.0 ; python_version < "3.10"
+typing-extensions==4.6.2 ; python_version < "3.10"
# via
# ansible-compat (pyproject.toml)
# black
# mkdocs-ansible
# mkdocstrings
-urllib3==1.26.15
+urllib3==2.0.2
# via
# mkdocs-ansible
# requests
@@ -292,7 +303,7 @@
# cssselect2
# mkdocs-ansible
# tinycss2
-wheel==0.40.0
+wheel==0.41.1
# via pip-tools
zipp==3.15.0
# via
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/src/ansible_compat/_version.py
new/ansible-compat-4.1.10/src/ansible_compat/_version.py
--- old/ansible-compat-4.1.5/src/ansible_compat/_version.py 2023-07-21
12:58:43.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat/_version.py 2023-09-06
14:56:06.000000000 +0200
@@ -1,4 +1,4 @@
# file generated by setuptools_scm
# don't change, don't track in version control
-__version__ = version = '4.1.5'
-__version_tuple__ = version_tuple = (4, 1, 5)
+__version__ = version = '4.1.10'
+__version_tuple__ = version_tuple = (4, 1, 10)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/src/ansible_compat/config.py
new/ansible-compat-4.1.10/src/ansible_compat/config.py
--- old/ansible-compat-4.1.5/src/ansible_compat/config.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat/config.py 2023-09-06
14:55:41.000000000 +0200
@@ -1,11 +1,13 @@
"""Store configuration options as a singleton."""
+from __future__ import annotations
+
import ast
import copy
import os
import re
import subprocess
from collections import UserDict
-from typing import Literal, Optional, Union
+from typing import Literal
from packaging.version import Version
@@ -79,9 +81,9 @@
action_warnings: bool = True
agnostic_become_prompt: bool = True
allow_world_readable_tmpfiles: bool = False
- ansible_connection_path: Optional[str] = None
+ ansible_connection_path: str | None = None
ansible_cow_acceptlist: list[str]
- ansible_cow_path: Optional[str] = None
+ ansible_cow_path: str | None = None
ansible_cow_selection: str = "default"
ansible_force_color: bool = False
ansible_nocolor: bool = False
@@ -94,16 +96,12 @@
"/usr/share/ansible/plugins/become",
]
cache_plugin: str = "memory"
- cache_plugin_connection: Optional[str] = None
+ cache_plugin_connection: str | None = None
cache_plugin_prefix: str = "ansible_facts"
cache_plugin_timeout: int = 86400
callable_accept_list: list[str] = []
callbacks_enabled: list[str] = []
- collections_on_ansible_version_mismatch: Union[
- Literal["warning"],
- Literal["warning"],
- Literal["ignore"],
- ] = "warning"
+ collections_on_ansible_version_mismatch: Literal["warning", "ignore"] =
"warning"
collections_paths: list[str] = [
"~/.ansible/collections",
"/usr/share/ansible/collections",
@@ -127,7 +125,7 @@
conditional_bare_vars: bool = False
connection_facts_modules: dict[str, str]
controller_python_warning: bool = True
- coverage_remote_output: Optional[str]
+ coverage_remote_output: str | None
coverage_remote_paths: list[str]
default_action_plugin_path: list[str] = [
"~/.ansible/plugins/action",
@@ -138,7 +136,7 @@
default_ask_vault_pass: bool = False
default_become: bool = False
default_become_ask_pass: bool = False
- default_become_exe: Optional[str] = None
+ default_become_exe: str | None = None
default_become_flags: str
default_become_method: str = "sudo"
default_become_user: str = "root"
@@ -160,18 +158,14 @@
]
default_debug: bool = False
default_executable: str = "/bin/sh"
- default_fact_path: Optional[str] = None
+ default_fact_path: str | None = None
default_filter_plugin_path: list[str] = [
"~/.ansible/plugins/filter",
"/usr/share/ansible/plugins/filter",
]
default_force_handlers: bool = False
default_forks: int = 5
- default_gathering: Union[
- Literal["smart"],
- Literal["explicit"],
- Literal["implicit"],
- ] = "smart"
+ default_gathering: Literal["smart", "explicit", "implicit"] = "smart"
default_gather_subset: list[str] = ["all"]
default_gather_timeout: int = 10
default_handler_includes_static: bool = False
@@ -193,7 +187,7 @@
default_load_callback_plugins: bool = False
default_local_tmp: str = "~/.ansible/tmp"
default_log_filter: list[str] = []
- default_log_path: Optional[str] = None
+ default_log_path: str | None = None
default_lookup_lugin_path: list[str] = [
"~/.ansible/plugins/lookup",
"/usr/share/ansible/plugins/lookup",
@@ -216,12 +210,12 @@
]
default_no_log: bool = False
default_no_target_syslog: bool = False
- default_null_representation: Optional[str] = None
+ default_null_representation: str | None = None
default_poll_interval: int = 15
- default_private_key_file: Optional[str] = None
+ default_private_key_file: str | None = None
default_private_role_vars: bool = False
- default_remote_port: Optional[str] = None
- default_remote_user: Optional[str] = None
+ default_remote_port: str | None = None
+ default_remote_user: str | None = None
default_roles_path: list[str] = [
"~/.ansible/roles",
"/usr/share/ansible/roles",
@@ -259,11 +253,11 @@
"~/.ansible/plugins/vars",
"/usr/share/ansible/plugins/vars",
]
- default_vault_encrypt_identity: Optional[str] = None
+ default_vault_encrypt_identity: str | None = None
default_vault_identity: str = "default"
default_vault_identity_list: list[str] = []
default_vault_id_match: bool = False
- default_vault_password_file: Optional[str] = None
+ default_vault_password_file: str | None = None
default_verbosity: int = 0
deprecation_warnings: bool = False
devel_warning: bool = True
@@ -276,28 +270,20 @@
"~/.ansible/plugins/doc_fragments",
"/usr/share/ansible/plugins/doc_fragments",
]
- duplicate_yaml_dict_key: Union[
- Literal["warn"],
- Literal["error"],
- Literal["ignore"],
- ] = "warn"
+ duplicate_yaml_dict_key: Literal["warn", "error", "ignore"] = "warn"
enable_task_debugger: bool = False
error_on_missing_handler: bool = True
facts_modules: list[str] = ["smart"]
galaxy_cache_dir: str = "~/.ansible/galaxy_cache"
- galaxy_display_progress: Optional[str] = None
+ galaxy_display_progress: str | None = None
galaxy_ignore_certs: bool = False
- galaxy_role_skeleton: Optional[str] = None
+ galaxy_role_skeleton: str | None = None
galaxy_role_skeleton_ignore: list[str] = ["^.git$", "^.*/.git_keep$"]
galaxy_server: str = "https://galaxy.ansible.com"
- galaxy_server_list: Optional[str] = None
+ galaxy_server_list: str | None = None
galaxy_token_path: str = "~/.ansible/galaxy_token"
host_key_checking: bool = True
- host_pattern_mismatch: Union[
- Literal["warning"],
- Literal["error"],
- Literal["ignore"],
- ] = "warning"
+ host_pattern_mismatch: Literal["warning", "error", "ignore"] = "warning"
inject_facts_as_vars: bool = True
interpreter_python: str = "auto_legacy"
interpreter_python_distro_map: dict[str, str]
@@ -305,8 +291,8 @@
invalid_task_attribute_failed: bool = True
inventory_any_unparsed_is_failed: bool = False
inventory_cache_enabled: bool = False
- inventory_cache_plugin: Optional[str] = None
- inventory_cache_plugin_connection: Optional[str] = None
+ inventory_cache_plugin: str | None = None
+ inventory_cache_plugin_connection: str | None = None
inventory_cache_plugin_prefix: str = "ansible_facts"
inventory_cache_timeout: int = 3600
inventory_enabled: list[str] = [
@@ -324,7 +310,7 @@
localhost_warning: bool = True
max_file_size_for_diff: int = 104448
module_ignore_exts: str
- netconf_ssh_config: Optional[str] = None
+ netconf_ssh_config: str | None = None
network_group_modules: list[str] = [
"eos",
"nxos",
@@ -356,19 +342,15 @@
persistent_connect_retry_timeout: int = 15
persistent_connect_timeout: int = 30
persistent_control_path_dir: str = "~/.ansible/pc"
- playbook_dir: Optional[str]
- playbook_vars_root: Union[Literal["top"], Literal["bottom"],
Literal["all"]] = "top"
- plugin_filters_cfg: Optional[str] = None
+ playbook_dir: str | None
+ playbook_vars_root: Literal["top", "bottom", "all"] = "top"
+ plugin_filters_cfg: str | None = None
python_module_rlimit_nofile: int = 0
retry_files_enabled: bool = False
- retry_files_save_path: Optional[str] = None
+ retry_files_save_path: str | None = None
run_vars_plugins: str = "demand"
show_custom_stats: bool = False
- string_conversion_action: Union[
- Literal["warn"],
- Literal["error"],
- Literal["ignore"],
- ] = "warn"
+ string_conversion_action: Literal["warn", "error", "ignore"] = "warn"
string_type_filters: list[str] = [
"string",
"to_json",
@@ -383,11 +365,11 @@
tags_skip: list[str] = []
task_debugger_ignore_errors: bool = True
task_timeout: int = 0
- transform_invalid_group_chars: Union[
- Literal["always"],
- Literal["never"],
- Literal["ignore"],
- Literal["silently"],
+ transform_invalid_group_chars: Literal[
+ "always",
+ "never",
+ "ignore",
+ "silently",
] = "never"
use_persistent_connections: bool = False
variable_plugins_enabled: list[str] = ["host_group_vars"]
@@ -407,8 +389,8 @@
def __init__(
self,
- config_dump: Optional[str] = None,
- data: Optional[dict[str, object]] = None,
+ config_dump: str | None = None,
+ data: dict[str, object] | None = None,
) -> None:
"""Load config dictionary."""
super().__init__()
@@ -461,11 +443,11 @@
"""Allow access to config options using indexing."""
return super().__getitem__(name.upper())
- def __copy__(self) -> "AnsibleConfig":
+ def __copy__(self) -> AnsibleConfig:
"""Allow users to run copy on Config."""
return AnsibleConfig(data=self.data)
- def __deepcopy__(self, memo: object) -> "AnsibleConfig":
+ def __deepcopy__(self, memo: object) -> AnsibleConfig:
"""Allow users to run deeepcopy on Config."""
return AnsibleConfig(data=self.data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/src/ansible_compat/constants.py
new/ansible-compat-4.1.10/src/ansible_compat/constants.py
--- old/ansible-compat-4.1.5/src/ansible_compat/constants.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat/constants.py 2023-09-06
14:55:41.000000000 +0200
@@ -1,6 +1,8 @@
"""Constants used by ansible_compat."""
+from pathlib import Path
+META_MAIN = (Path("meta") / Path("main.yml"), Path("meta") / Path("main.yaml"))
REQUIREMENT_LOCATIONS = [
"requirements.yml",
"roles/requirements.yml",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/src/ansible_compat/errors.py
new/ansible-compat-4.1.10/src/ansible_compat/errors.py
--- old/ansible-compat-4.1.5/src/ansible_compat/errors.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat/errors.py 2023-09-06
14:55:41.000000000 +0200
@@ -1,5 +1,7 @@
"""Module to deal with errors."""
-from typing import TYPE_CHECKING, Any, Optional
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
from ansible_compat.constants import ANSIBLE_MISSING_RC,
INVALID_PREREQUISITES_RC
@@ -14,8 +16,8 @@
def __init__(
self,
- message: Optional[str] = None,
- proc: Optional[Any] = None,
+ message: str | None = None,
+ proc: CompletedProcess[Any] | None = None,
) -> None:
"""Construct generic library exception."""
super().__init__(message)
@@ -25,7 +27,7 @@
class AnsibleCommandError(RuntimeError):
"""Exception running an Ansible command."""
- def __init__(self, proc: "CompletedProcess[Any]") -> None:
+ def __init__(self, proc: CompletedProcess[Any]) -> None:
"""Construct an exception given a completed process."""
message = (
f"Got {proc.returncode} exit code while running: {'
'.join(proc.args)}"
@@ -41,8 +43,8 @@
def __init__(
self,
- message: Optional[str] = "Unable to find a working copy of ansible
executable.",
- proc: Optional[Any] = None,
+ message: str | None = "Unable to find a working copy of ansible
executable.",
+ proc: CompletedProcess[Any] | None = None,
) -> None:
"""."""
super().__init__(message)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/src/ansible_compat/runtime.py
new/ansible-compat-4.1.10/src/ansible_compat/runtime.py
--- old/ansible-compat-4.1.5/src/ansible_compat/runtime.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat/runtime.py 2023-09-06
14:55:41.000000000 +0200
@@ -2,7 +2,6 @@
from __future__ import annotations
import contextlib
-import fnmatch
import importlib
import json
import logging
@@ -10,6 +9,7 @@
import re
import shutil
import subprocess
+import sys
import tempfile
import warnings
from collections import OrderedDict
@@ -27,6 +27,7 @@
parse_ansible_version,
)
from ansible_compat.constants import (
+ META_MAIN,
MSG_INVALID_FQRL,
RC_ANSIBLE_OPTIONS_ERROR,
REQUIREMENT_LOCATIONS,
@@ -47,9 +48,11 @@
else:
CompletedProcess = subprocess.CompletedProcess
+
_logger = logging.getLogger(__name__)
# regex to extract the first version from a collection range specifier
version_re = re.compile(":[>=<]*([^,]*)")
+namespace_re = re.compile("^[a-z][a-z0-9_]+$")
class AnsibleWarning(Warning):
@@ -203,6 +206,9 @@
self.cache_dir = get_cache_dir(self.project_dir)
self.config = AnsibleConfig()
+ # Add the sys.path to the collection paths if not isolated
+ self._add_sys_path_to_collection_paths()
+
if not self.version_in_range(lower=min_required_version):
msg = f"Found incompatible version of ansible runtime
{self.version}, instead of {min_required_version} or newer."
raise RuntimeError(msg)
@@ -230,6 +236,18 @@
# Monkey patch ansible warning in order to use warnings module.
Display.warning = warning
+ def _add_sys_path_to_collection_paths(self) -> None:
+ """Add the sys.path to the collection paths."""
+ if not self.isolated and self.config.collections_scan_sys_path:
+ for path in sys.path:
+ if (
+ path not in self.config.collections_paths
+ and (Path(path) / "ansible_collections").is_dir()
+ ):
+ self.config.collections_paths.append( # pylint:
disable=E1101
+ path,
+ )
+
def load_collections(self) -> None:
"""Load collection data."""
self.collections = OrderedDict()
@@ -402,7 +420,9 @@
) -> None:
"""Install an Ansible collection.
- Can accept version constraints like 'foo.bar:>=1.2.3'
+ Can accept arguments like:
+ 'foo.bar:>=1.2.3'
+ 'git+https://github.com/ansible-collections/ansible.posix.git,main'
"""
cmd = [
"ansible-galaxy",
@@ -413,11 +433,18 @@
if force:
cmd.append("--force")
+ if isinstance(collection, Path):
+ collection = str(collection)
# As ansible-galaxy install is not able to automatically determine
# if the range requires a pre-release, we need to manuall add the --pre
# flag when needed.
- matches = version_re.search(str(collection))
- if matches and CollectionVersion(matches[1]).is_prerelease:
+ matches = version_re.search(collection)
+
+ if (
+ not is_url(collection)
+ and matches
+ and CollectionVersion(matches[1]).is_prerelease
+ ):
cmd.append("--pre")
cpaths: list[str] = self.config.collections_paths
@@ -521,13 +548,20 @@
raise AnsibleCommandError(result)
# Run galaxy collection install works on v2 requirements.yml
- if "collections" in reqs_yaml:
+ if "collections" in reqs_yaml and reqs_yaml["collections"] is not None:
cmd = [
"ansible-galaxy",
"collection",
"install",
"-v",
]
+ for collection in reqs_yaml["collections"]:
+ if isinstance(collection, dict) and collection.get("type", "")
== "git":
+ _logger.info(
+ "Adding '--pre' to ansible-galaxy collection install
because we detected one collection being sourced from git.",
+ )
+ cmd.append("--pre")
+ break
if offline:
_logger.warning(
"Skipped installing collection dependencies due to running
in offline mode.",
@@ -553,19 +587,6 @@
_logger.error(result.stderr)
raise AnsibleCommandError(result)
- def search_galaxy_paths(self, search_dir: Path, depth: int = 0) ->
list[str]:
- """Search for galaxy paths (only one level deep)."""
- galaxy_paths: list[str] = []
- for file in os.listdir(search_dir):
- file_path = Path(file)
- if file_path.is_dir() and depth < 1:
- galaxy_paths.extend(self.search_galaxy_paths(file_path, 1))
- elif fnmatch.fnmatch(file, "galaxy.yml"):
- galaxy_paths.append(str(search_dir / file))
- if depth == 0 and not galaxy_paths:
- return ["galaxy.yml"]
- return galaxy_paths
-
def prepare_environment( # noqa: C901
self,
required_collections: dict[str, str] | None = None,
@@ -587,7 +608,13 @@
for req_file in REQUIREMENT_LOCATIONS:
self.install_requirements(Path(req_file), retry=retry,
offline=offline)
- for gpath in self.search_galaxy_paths(self.project_dir):
+ self._prepare_ansible_paths()
+
+ if not install_local:
+ return
+
+ for gpath in search_galaxy_paths(self.project_dir):
+ # processing all found galaxy.yml files
galaxy_path = Path(gpath)
if galaxy_path.exists():
data = yaml_from_file(galaxy_path)
@@ -599,63 +626,58 @@
required_version,
)
self.install_collection(
- f"{name}:{required_version}",
+ f"{name}{',' if is_url(name) else
':'}{required_version}",
destination=destination,
)
- if self.cache_dir:
- destination = self.cache_dir / "collections"
- for name, min_version in required_collections.items():
- self.install_collection(
- f"{name}:>={min_version}",
- destination=destination,
- )
-
- self._prepare_ansible_paths()
-
- if not install_local:
- return
+ if self.cache_dir:
+ destination = self.cache_dir / "collections"
+ for name, min_version in required_collections.items():
+ self.install_collection(
+ f"{name}:>={min_version}",
+ destination=destination,
+ )
- if galaxy_path.exists():
- if destination:
- # while function can return None, that would not break the
logic
- colpath = Path(
-
f"{destination}/ansible_collections/{colpath_from_path(Path.cwd())}",
- )
- if colpath.is_symlink():
- if os.path.realpath(colpath) == Path.cwd():
- _logger.warning(
- "Found symlinked collection, skipping its
installation.",
- )
- return
+ if Path("galaxy.yml").exists():
+ if destination:
+ # while function can return None, that would not break the
logic
+ colpath = Path(
+
f"{destination}/ansible_collections/{colpath_from_path(Path.cwd())}",
+ )
+ if colpath.is_symlink():
+ if os.path.realpath(colpath) == Path.cwd():
_logger.warning(
- "Collection is symlinked, but not pointing to %s
directory, so we will remove it.",
- Path.cwd(),
+ "Found symlinked collection, skipping its
installation.",
)
- colpath.unlink()
+ return
+ _logger.warning(
+ "Collection is symlinked, but not pointing to %s
directory, so we will remove it.",
+ Path.cwd(),
+ )
+ colpath.unlink()
- # molecule scenario within a collection
- self.install_collection_from_disk(
- galaxy_path.parent,
- destination=destination,
- )
- elif (
- Path().resolve().parent.name == "roles"
- and Path("../../galaxy.yml").exists()
- ):
- # molecule scenario located within roles/<role-name>/molecule
inside
- # a collection
- self.install_collection_from_disk(
- Path("../.."),
- destination=destination,
- )
- else:
- # no collection, try to recognize and install a standalone role
- self._install_galaxy_role(
- self.project_dir,
- role_name_check=role_name_check,
- ignore_errors=True,
- )
+ # molecule scenario within a collection
+ self.install_collection_from_disk(
+ galaxy_path.parent,
+ destination=destination,
+ )
+ elif (
+ Path().resolve().parent.name == "roles"
+ and Path("../../galaxy.yml").exists()
+ ):
+ # molecule scenario located within roles/<role-name>/molecule
inside
+ # a collection
+ self.install_collection_from_disk(
+ Path("../.."),
+ destination=destination,
+ )
+ else:
+ # no collection, try to recognize and install a standalone role
+ self._install_galaxy_role(
+ self.project_dir,
+ role_name_check=role_name_check,
+ ignore_errors=True,
+ )
# reload collections
self.load_collections()
@@ -665,11 +687,16 @@
version: str | None = None,
*,
install: bool = True,
- ) -> None:
+ ) -> tuple[CollectionVersion, Path]:
"""Check if a minimal collection version is present or exits.
In the future this method may attempt to install a missing or outdated
collection before failing.
+
+ :param name: collection name
+ :param version: minimal version required
+ :param install: if True, attempt to install a missing collection
+ :returns: tuple of (found_version, collection_path)
"""
try:
ns, coll = name.split(".", 1)
@@ -714,15 +741,19 @@
msg = f"Found {name} collection {found_version}
but {version} or newer is required."
_logger.fatal(msg)
raise InvalidPrerequisiteError(msg)
+ return found_version, collpath.resolve()
break
else:
if install:
self.install_collection(f"{name}:>={version}" if version else
name)
- self.require_collection(name=name, version=version,
install=False)
- else:
- msg = f"Collection '{name}' not found in '{paths}'"
- _logger.fatal(msg)
- raise InvalidPrerequisiteError(msg)
+ return self.require_collection(
+ name=name,
+ version=version,
+ install=False,
+ )
+ msg = f"Collection '{name}' not found in '{paths}'"
+ _logger.fatal(msg)
+ raise InvalidPrerequisiteError(msg)
def _prepare_ansible_paths(self) -> None:
"""Configure Ansible environment variables."""
@@ -802,13 +833,17 @@
"""
yaml = None
galaxy_info = {}
- meta_filename = Path(project_dir) / "meta" / "main.yml"
- if not meta_filename.exists():
+ for meta_main in META_MAIN:
+ meta_filename = Path(project_dir) / meta_main
+
+ if meta_filename.exists():
+ break
+ else:
if ignore_errors:
return
- else:
- yaml = yaml_from_file(meta_filename)
+
+ yaml = yaml_from_file(meta_filename)
if yaml and "galaxy_info" in yaml:
galaxy_info = yaml["galaxy_info"]
@@ -900,3 +935,22 @@
def _get_galaxy_role_name(galaxy_infos: dict[str, Any]) -> str:
"""Compute role name from meta/main.yml."""
return galaxy_infos.get("role_name", "")
+
+
+def search_galaxy_paths(search_dir: Path) -> list[str]:
+ """Search for galaxy paths (only one level deep)."""
+ galaxy_paths: list[str] = []
+ for file in [".", *os.listdir(search_dir)]:
+ # We ignore any folders that are not valid namespaces, just like
+ # ansible galaxy does at this moment.
+ if file != "." and not namespace_re.match(file):
+ continue
+ file_path = search_dir / file / "galaxy.yml"
+ if file_path.is_file():
+ galaxy_paths.append(str(file_path))
+ return galaxy_paths
+
+
+def is_url(name: str) -> bool:
+ """Return True if a dependency name looks like an URL."""
+ return bool(re.match("^git[+@]", name))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/src/ansible_compat/schema.py
new/ansible-compat-4.1.10/src/ansible_compat/schema.py
--- old/ansible-compat-4.1.5/src/ansible_compat/schema.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat/schema.py 2023-09-06
14:55:41.000000000 +0200
@@ -1,16 +1,19 @@
"""Utils for JSON Schema validation."""
+from __future__ import annotations
+
import json
from collections.abc import Mapping, Sequence
from dataclasses import dataclass
-from typing import Union
+from typing import TYPE_CHECKING
import jsonschema
from jsonschema.validators import validator_for
-from ansible_compat.types import JSON
+if TYPE_CHECKING:
+ from ansible_compat.types import JSON
-def to_path(schema_path: Sequence[Union[str, int]]) -> str:
+def to_path(schema_path: Sequence[str | int]) -> str:
"""Flatten a path to a dot delimited string.
:param schema_path: The schema path
@@ -19,7 +22,7 @@
return ".".join(str(index) for index in schema_path)
-def json_path(absolute_path: Sequence[Union[str, int]]) -> str:
+def json_path(absolute_path: Sequence[str | int]) -> str:
"""Flatten a data path to a dot delimited string.
:param absolute_path: The path
@@ -44,7 +47,7 @@
data_path: str
json_path: str
message: str
- expected: Union[bool, int, str]
+ expected: bool | int | str
relative_schema: str
validator: str
found: str
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-4.1.5/src/ansible_compat.egg-info/PKG-INFO
new/ansible-compat-4.1.10/src/ansible_compat.egg-info/PKG-INFO
--- old/ansible-compat-4.1.5/src/ansible_compat.egg-info/PKG-INFO
2023-07-21 12:58:43.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat.egg-info/PKG-INFO
2023-09-06 14:56:06.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ansible-compat
-Version: 4.1.5
+Version: 4.1.10
Summary: Ansible compatibility goodies
Author-email: Sorin Sbarnea <[email protected]>
Maintainer-email: Sorin Sbarnea <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-4.1.5/src/ansible_compat.egg-info/SOURCES.txt
new/ansible-compat-4.1.10/src/ansible_compat.egg-info/SOURCES.txt
--- old/ansible-compat-4.1.5/src/ansible_compat.egg-info/SOURCES.txt
2023-07-21 12:58:43.000000000 +0200
+++ new/ansible-compat-4.1.10/src/ansible_compat.egg-info/SOURCES.txt
2023-09-06 14:56:06.000000000 +0200
@@ -61,12 +61,15 @@
test/test_prerun.py
test/test_runtime.py
test/test_runtime_example.py
+test/test_runtime_scan_path.py
test/test_schema.py
test/assets/requirements-invalid-collection.yml
test/assets/requirements-invalid-role.yml
test/assets/validate0_data.json
test/assets/validate0_expected.json
test/assets/validate0_schema.json
+test/assets/galaxy_paths/.bar/galaxy.yml
+test/assets/galaxy_paths/foo/galaxy.yml
test/collections/acme.broken/galaxy.yml
test/collections/acme.goodies/galaxy.yml
test/collections/acme.goodies/molecule/default/converge.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-4.1.5/test/collections/acme.goodies/galaxy.yml
new/ansible-compat-4.1.10/test/collections/acme.goodies/galaxy.yml
--- old/ansible-compat-4.1.5/test/collections/acme.goodies/galaxy.yml
2023-07-21 12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/test/collections/acme.goodies/galaxy.yml
2023-09-06 14:55:41.000000000 +0200
@@ -8,6 +8,7 @@
dependencies:
community.molecule: ">=0.1.0" # used to also test '=>' condition
ansible.utils: "*" # used to also test '*'
+ git+https://github.com/ansible-collections/community.crypto.git: main #
tests ability to install from git
build_ignore:
- "*.egg-info"
- .DS_Store
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/test/conftest.py
new/ansible-compat-4.1.10/test/conftest.py
--- old/ansible-compat-4.1.5/test/conftest.py 2023-07-21 12:58:17.000000000
+0200
+++ new/ansible-compat-4.1.10/test/conftest.py 2023-09-06 14:55:41.000000000
+0200
@@ -1,6 +1,12 @@
"""Pytest fixtures."""
+import importlib.metadata
+import json
import pathlib
+import subprocess
+import sys
from collections.abc import Generator
+from pathlib import Path
+from typing import Callable
import pytest
@@ -26,3 +32,96 @@
instance = Runtime(project_dir=tmp_path, isolated=True)
yield instance
instance.clean()
+
+
+def query_pkg_version(pkg: str) -> str:
+ """Get the version of a current installed package.
+
+ :param pkg: Package name
+ :return: Package version
+ """
+ return importlib.metadata.version(pkg)
+
+
[email protected]()
+def pkg_version() -> Callable[[str], str]:
+ """Get the version of a current installed package.
+
+ :return: Callable function to get package version
+ """
+ return query_pkg_version
+
+
+class VirtualEnvironment:
+ """Virtualenv wrapper."""
+
+ def __init__(self, path: Path) -> None:
+ """Initialize.
+
+ :param path: Path to virtualenv
+ """
+ self.project = path
+ self.venv_path = self.project / "venv"
+ self.venv_bin_path = self.venv_path / "bin"
+ self.venv_python_path = self.venv_bin_path / "python"
+
+ def create(self) -> None:
+ """Create virtualenv."""
+ cmd = [str(sys.executable), "-m", "venv", str(self.venv_path)]
+ subprocess.check_call(args=cmd)
+ # Install this package into the virtual environment
+ self.install(f"{__file__}/../..")
+
+ def install(self, *packages: str) -> None:
+ """Install packages in virtualenv.
+
+ :param packages: Packages to install
+ """
+ cmd = [str(self.venv_python_path), "-m", "pip", "install", *packages]
+ subprocess.check_call(args=cmd)
+
+ def python_script_run(self, script: str) ->
subprocess.CompletedProcess[str]:
+ """Run command in project dir using venv.
+
+ :param args: Command to run
+ """
+ proc = subprocess.run(
+ args=[self.venv_python_path, "-c", script],
+ capture_output=True,
+ cwd=self.project,
+ check=False,
+ text=True,
+ )
+ return proc
+
+ def site_package_dirs(self) -> list[Path]:
+ """Get site packages.
+
+ :return: List of site packages dirs
+ """
+ script = "import json, site; print(json.dumps(site.getsitepackages()))"
+ proc = subprocess.run(
+ args=[self.venv_python_path, "-c", script],
+ capture_output=True,
+ check=False,
+ text=True,
+ )
+ dirs = json.loads(proc.stdout)
+ if not isinstance(dirs, list):
+ msg = "Expected list of site packages"
+ raise TypeError(msg)
+ sanitized = list({Path(d).resolve() for d in dirs})
+ return sanitized
+
+
[email protected](scope="module")
+def venv_module(tmp_path_factory: pytest.TempPathFactory) ->
VirtualEnvironment:
+ """Create a virtualenv in a temporary directory.
+
+ :param tmp_path: pytest fixture for temp path
+ :return: VirtualEnvironment instance
+ """
+ test_project = tmp_path_factory.mktemp(basename="test_project-",
numbered=True)
+ _venv = VirtualEnvironment(test_project)
+ _venv.create()
+ return _venv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/test/test_prerun.py
new/ansible-compat-4.1.10/test/test_prerun.py
--- old/ansible-compat-4.1.5/test/test_prerun.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/test/test_prerun.py 2023-09-06
14:55:41.000000000 +0200
@@ -6,6 +6,6 @@
def test_get_cache_dir_relative() -> None:
"""Test behaviors of get_cache_dir."""
- relative_path = Path(".")
+ relative_path = Path()
abs_path = relative_path.resolve()
assert get_cache_dir(relative_path) == get_cache_dir(abs_path)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/test/test_runtime.py
new/ansible-compat-4.1.10/test/test_runtime.py
--- old/ansible-compat-4.1.5/test/test_runtime.py 2023-07-21
12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/test/test_runtime.py 2023-09-06
14:55:41.000000000 +0200
@@ -1,19 +1,18 @@
"""Tests for Runtime class."""
# pylint: disable=protected-access
+from __future__ import annotations
+
import logging
import os
import pathlib
import subprocess
-from collections.abc import Iterator
from contextlib import contextmanager
from pathlib import Path
from shutil import rmtree
-from typing import Any, Union
+from typing import TYPE_CHECKING, Any
import pytest
-from _pytest.monkeypatch import MonkeyPatch
from packaging.version import Version
-from pytest_mock import MockerFixture
from ansible_compat.config import ansible_version
from ansible_compat.constants import INVALID_PREREQUISITES_RC
@@ -22,7 +21,18 @@
AnsibleCompatError,
InvalidPrerequisiteError,
)
-from ansible_compat.runtime import CompletedProcess, Runtime
+from ansible_compat.runtime import (
+ CompletedProcess,
+ Runtime,
+ is_url,
+ search_galaxy_paths,
+)
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+
+ from _pytest.monkeypatch import MonkeyPatch
+ from pytest_mock import MockerFixture
def test_runtime_version(runtime: Runtime) -> None:
@@ -466,16 +476,27 @@
runtime.install_collection("examples/reqs_v2/community-molecule-0.1.0.tar.gz")
+def test_install_collection_git(runtime: Runtime) -> None:
+ """Check that valid collection installs do not fail."""
+ runtime.install_collection(
+ "git+https://github.com/ansible-collections/ansible.posix,main",
+ )
+
+
def test_install_collection_dest(runtime: Runtime, tmp_path: pathlib.Path) ->
None:
"""Check that valid collection to custom destination passes."""
+ # Since Ansible 2.15.3 there is no guarantee that this will install the
collection at requested path
+ # as it might decide to not install anything if requirement is already
present at another location.
runtime.install_collection(
"examples/reqs_v2/community-molecule-0.1.0.tar.gz",
destination=tmp_path,
)
- expected_file = (
- tmp_path / "ansible_collections" / "community" / "molecule" /
"MANIFEST.json"
- )
- assert expected_file.is_file()
+ runtime.load_collections()
+ for collection in runtime.collections:
+ if collection == "community.molecule":
+ return
+ msg = "Failed to find collection as installed."
+ raise AssertionError(msg)
def test_install_collection_fail(runtime: Runtime) -> None:
@@ -633,8 +654,8 @@
ids=("1", "2", "3", "4", "5"),
)
def test_runtime_version_in_range(
- lower: Union[str, None],
- upper: Union[str, None],
+ lower: str | None,
+ upper: str | None,
expected: bool,
) -> None:
"""Validate functioning of version_in_range."""
@@ -652,6 +673,7 @@
"ansible.posix", # from tests/requirements.yml
"ansible.utils", # from galaxy.yml
"community.molecule", # from galaxy.yml
+ "community.crypto", # from galaxy.yml as a git dependency
],
id="normal",
),
@@ -789,3 +811,53 @@
assert "ansible.builtin.free" in runtime.plugins.strategy
assert "ansible.builtin.is_abs" in runtime.plugins.test
assert "ansible.builtin.bool" in runtime.plugins.filter
+
+
[email protected](
+ ("path", "result"),
+ (
+ pytest.param(
+ "test/assets/galaxy_paths",
+ ["test/assets/galaxy_paths/foo/galaxy.yml"],
+ id="1",
+ ),
+ pytest.param(
+ "test/collections",
+ [], # should find nothing because these folders are not valid
namespaces
+ id="2",
+ ),
+ pytest.param(
+ "test/assets/galaxy_paths/foo",
+ ["test/assets/galaxy_paths/foo/galaxy.yml"],
+ id="3",
+ ),
+ ),
+)
+def test_galaxy_path(path: str, result: list[str]) -> None:
+ """Check behavior of galaxy path search."""
+ assert search_galaxy_paths(Path(path)) == result
+
+
[email protected](
+ ("name", "result"),
+ (
+ pytest.param(
+ "foo",
+ False,
+ id="0",
+ ),
+ pytest.param(
+ "git+git",
+ True,
+ id="1",
+ ),
+ pytest.param(
+ "[email protected]",
+ True,
+ id="2",
+ ),
+ ),
+)
+def test_is_url(name: str, result: bool) -> None:
+ """Checks functionality of is_url."""
+ assert is_url(name) == result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/test/test_runtime_scan_path.py
new/ansible-compat-4.1.10/test/test_runtime_scan_path.py
--- old/ansible-compat-4.1.5/test/test_runtime_scan_path.py 1970-01-01
01:00:00.000000000 +0100
+++ new/ansible-compat-4.1.10/test/test_runtime_scan_path.py 2023-09-06
14:55:41.000000000 +0200
@@ -0,0 +1,105 @@
+"""Test the scan path functionality of the runtime."""
+
+import json
+import textwrap
+from dataclasses import dataclass, fields
+from pathlib import Path
+
+import pytest
+from _pytest.monkeypatch import MonkeyPatch
+
+from ansible_compat.runtime import Runtime
+
+from .conftest import VirtualEnvironment
+
+V2_COLLECTION_TARBALL =
Path("examples/reqs_v2/community-molecule-0.1.0.tar.gz")
+V2_COLLECTION_NAMESPACE = "community"
+V2_COLLECTION_NAME = "molecule"
+V2_COLLECTION_VERSION = "0.1.0"
+V2_COLLECTION_FULL_NAME = f"{V2_COLLECTION_NAMESPACE}.{V2_COLLECTION_NAME}"
+
+
+@dataclass
+class ScanSysPath:
+ """Parameters for scan tests."""
+
+ isolated: bool
+ scan: bool
+ raises_not_found: bool
+
+ def __str__(self) -> str:
+ """Return a string representation of the object."""
+ parts = [
+ f"{field.name}{str(getattr(self, field.name))[0]}" for field in
fields(self)
+ ]
+ return "-".join(parts)
+
+
[email protected](
+ ("param"),
+ (
+ ScanSysPath(isolated=True, scan=True, raises_not_found=True),
+ ScanSysPath(isolated=True, scan=False, raises_not_found=True),
+ ScanSysPath(isolated=False, scan=True, raises_not_found=False),
+ ScanSysPath(isolated=False, scan=False, raises_not_found=True),
+ ),
+ ids=str,
+)
+def test_scan_sys_path(
+ venv_module: VirtualEnvironment,
+ monkeypatch: MonkeyPatch,
+ runtime_tmp: Runtime,
+ tmp_path: Path,
+ param: ScanSysPath,
+) -> None:
+ """Confirm sys path is scanned for collections.
+
+ :param venv_module: Fixture for a virtual environment
+ :param monkeypatch: Fixture for monkeypatching
+ :param runtime_tmp: Fixture for a Runtime object
+ :param tmp_dir: Fixture for a temporary directory
+ :param param: The parameters for the test
+ """
+ first_site_package_dir = venv_module.site_package_dirs()[0]
+
+ installed_to = (
+ first_site_package_dir
+ / "ansible_collections"
+ / V2_COLLECTION_NAMESPACE
+ / V2_COLLECTION_NAME
+ )
+ if not installed_to.exists():
+ # Install the collection into the venv site packages directory, force
+ # as of yet this test is not isolated from the rest of the system
+ runtime_tmp.install_collection(
+ collection=V2_COLLECTION_TARBALL,
+ destination=first_site_package_dir,
+ force=True,
+ )
+ # Confirm the collection is installed
+ assert installed_to.exists()
+ # Set the sys scan path environment variable
+ monkeypatch.setenv("ANSIBLE_COLLECTIONS_SCAN_SYS_PATH", str(param.scan))
+ # Set the ansible collections paths to avoid bleed from other tests
+ monkeypatch.setenv("ANSIBLE_COLLECTIONS_PATH", str(tmp_path))
+
+ script = textwrap.dedent(
+ f"""
+ import json;
+ from ansible_compat.runtime import Runtime;
+ r = Runtime(isolated={param.isolated});
+ fv, cp = r.require_collection(name="{V2_COLLECTION_FULL_NAME}",
version="{V2_COLLECTION_VERSION}", install=False);
+ print(json.dumps({{"found_version": str(fv), "collection_path":
str(cp)}}));
+ """,
+ )
+
+ proc = venv_module.python_script_run(script)
+ if param.raises_not_found:
+ assert proc.returncode != 0, (proc.stdout, proc.stderr)
+ assert "InvalidPrerequisiteError" in proc.stderr
+ assert "'community.molecule' not found" in proc.stderr
+ else:
+ assert proc.returncode == 0, (proc.stdout, proc.stderr)
+ result = json.loads(proc.stdout)
+ assert result["found_version"] == V2_COLLECTION_VERSION
+ assert result["collection_path"] == str(installed_to)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-4.1.5/tox.ini
new/ansible-compat-4.1.10/tox.ini
--- old/ansible-compat-4.1.5/tox.ini 2023-07-21 12:58:17.000000000 +0200
+++ new/ansible-compat-4.1.10/tox.ini 2023-09-06 14:55:41.000000000 +0200
@@ -71,7 +71,7 @@
PIP_DISABLE_PIP_VERSION_CHECK = 1
PIP_CONSTRAINT = {toxinidir}/requirements.txt
PRE_COMMIT_COLOR = always
- PYTEST_REQPASS = 82
+ PYTEST_REQPASS = 93
FORCE_COLOR = 1
allowlist_externals =
ansible
@@ -154,3 +154,22 @@
mkdocs {posargs:build} --strict
extras = docs
passenv = *
+
+[testenv:smoke]
+description = Run ansible-lint own testing with current code from compat
library
+commands_pre =
+ ansible localhost -m ansible.builtin.git -a
'repo=https://github.com/ansible/ansible-lint dest={envdir}/tmp/ansible-lint'
+ pip install -e "{envdir}/tmp/ansible-lint[test]"
+commands =
+ bash -c "pip freeze|grep ansible"
+ pytest -k role
+deps =
+ ansible-core
+setenv =
+ {[testenv]setenv}
+ PIP_CONSTRAINT = /dev/null
+ PYTEST_REQPASS = 0
+changedir = {envdir}/tmp/ansible-lint
+allowlist_externals =
+ pwd
+ bash