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 2022-06-23 10:23:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ansible-compat (Old)
and /work/SRC/openSUSE:Factory/.python-ansible-compat.new.1548 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ansible-compat"
Thu Jun 23 10:23:39 2022 rev:4 rq:984255 version:2.1.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-ansible-compat/python-ansible-compat.changes
2022-05-30 12:44:19.800420844 +0200
+++
/work/SRC/openSUSE:Factory/.python-ansible-compat.new.1548/python-ansible-compat.changes
2022-06-23 10:23:59.707722043 +0200
@@ -1,0 +2,11 @@
+Tue Jun 14 21:02:38 UTC 2022 - Sebastian Wagner <[email protected]>
+
+- Update to version 2.1.0:
+ - Minor Changes
+ - Add module to work with schemas (#143) @ssbarnea
+ - Bugfixes
+ - Expose role_name_check in prepare_environment (#147) @zhan9san
+ - Install role in cache dir (#135) @zhan9san
+ - Prevent occasional FileExistsError with symlink recreation (#145) @ssbarnea
+
+-------------------------------------------------------------------
Old:
----
ansible-compat-2.0.4.tar.gz
New:
----
ansible-compat-2.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-ansible-compat.spec ++++++
--- /var/tmp/diff_new_pack.OiAti3/_old 2022-06-23 10:24:00.127722500 +0200
+++ /var/tmp/diff_new_pack.OiAti3/_new 2022-06-23 10:24:00.135722508 +0200
@@ -19,7 +19,7 @@
# only works with the python version which the package 'ansible' uses
%define pythons python3
Name: python-ansible-compat
-Version: 2.0.4
+Version: 2.1.0
Release: 0
Summary: Compatibility shim for Ansible 2.9 and newer
License: MIT
@@ -35,6 +35,7 @@
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module PyYAML}
BuildRequires: %{python_module flaky}
+BuildRequires: %{python_module jsonschema >= 4.5.1}
BuildRequires: %{python_module pytest-mock}
BuildRequires: %{python_module subprocess-tee}
BuildRequires: ansible
++++++ ansible-compat-2.0.4.tar.gz -> ansible-compat-2.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/.github/CODEOWNERS
new/ansible-compat-2.1.0/.github/CODEOWNERS
--- old/ansible-compat-2.0.4/.github/CODEOWNERS 2022-05-16 18:24:27.000000000
+0200
+++ new/ansible-compat-2.1.0/.github/CODEOWNERS 2022-05-23 18:11:08.000000000
+0200
@@ -1,2 +1 @@
-* @ssbarnea
-* @webknjaz
+* @ansible/devtools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/.pre-commit-config.yaml
new/ansible-compat-2.1.0/.pre-commit-config.yaml
--- old/ansible-compat-2.0.4/.pre-commit-config.yaml 2022-05-16
18:24:27.000000000 +0200
+++ new/ansible-compat-2.1.0/.pre-commit-config.yaml 2022-05-23
18:11:08.000000000 +0200
@@ -10,7 +10,6 @@
skip:
# https://github.com/pre-commit-ci/issues/issues/55
- pip-compile
- - pip-compile-docs
default_language_version:
# Needed in order to make pip-compile output predictable.
python: python3.9
@@ -92,6 +91,7 @@
- subprocess-tee>=0.3.5
- types-PyYAML
- types-pkg_resources
+ - types-jsonschema
- repo: https://github.com/pycqa/pylint
rev: v2.13.8
hooks:
@@ -106,38 +106,20 @@
hooks:
- id: pip-compile-upgrade
# To run it execute: `pre-commit run pip-compile-upgrade --hook-stage
manual`
- name: Upgrade contraints files and requirements
- files: ^(setup\.py|setup\.cfg|constraints\.txt)$
+ name: Upgrade constraints files and requirements
+ files: ^(setup\.py|setup\.cfg|requirements\.txt)$
language: python
- entry: python -m piptools compile --upgrade -q --extra test
--output-file=constraints.txt setup.cfg
- pass_filenames: false
- stages:
- - manual
- additional_dependencies:
- - pip-tools>=6.5.1
- - id: pip-compile-docs-upgrade
- name: Upgrade contraints files and requirements for docs
- files: ^(setup\.py|setup\.cfg|docs\/requirements\.(txt|in))$
- language: python
- entry: python -m piptools compile --upgrade -q docs/requirements.in
--output-file=docs/requirements.txt setup.cfg
+ entry: python -m piptools compile --upgrade -q --extra docs --extra
test --output-file=requirements.txt setup.cfg
pass_filenames: false
stages:
- manual
additional_dependencies:
- pip-tools>=6.5.1
- id: pip-compile
- name: Check contraints files and requirements
- files: ^(setup\.py|setup\.cfg|constraints\.txt)$
- language: python
- entry: python -m piptools compile -q --extra test
--output-file=constraints.txt setup.cfg
- pass_filenames: false
- additional_dependencies:
- - pip-tools>=6.5.1
- - id: pip-compile-docs
- name: Check contraints files and requirements for docs
- files: ^(setup\.py|setup\.cfg|docs\/requirements\.(txt|in))$
+ name: Check constraints files and requirements
+ files: ^(setup\.py|setup\.cfg|requirements\.txt)$
language: python
- entry: python -m piptools compile -q docs/requirements.in
--output-file=docs/requirements.txt setup.cfg
+ entry: python -m piptools compile -q --extra docs --extra test
--output-file=requirements.txt setup.cfg
pass_filenames: false
additional_dependencies:
- pip-tools>=6.5.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/.readthedocs.yml
new/ansible-compat-2.1.0/.readthedocs.yml
--- old/ansible-compat-2.0.4/.readthedocs.yml 1970-01-01 01:00:00.000000000
+0100
+++ new/ansible-compat-2.1.0/.readthedocs.yml 2022-05-23 18:11:08.000000000
+0200
@@ -0,0 +1,45 @@
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html
+# for details
+
+---
+# Required
+version: 2
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+ # keep dirhtml for nice URLs without .html extension
+ builder: dirhtml
+ configuration: docs/conf.py
+ fail_on_warning: true
+
+# Build documentation with MkDocs
+#mkdocs:
+# configuration: mkdocs.yml
+# fail_on_warning: true
+
+# Optionally build your docs in additional formats
+# such as PDF and ePub
+formats: []
+
+submodules:
+ include: all # []
+ exclude: []
+ recursive: true
+
+build:
+ image: latest
+
+# Optionally set the version of Python and requirements required
+# to build docs
+python:
+ version: "3.8"
+ install:
+ # On https://readthedocs.org/dashboard/ansible-lint/environmentvariables/
we
+ # do have PIP_CONSTRAINTS=requirements.txt which ensures we install only
+ # pinned requirements that that we know to be working.
+ - method: pip
+ path: .
+ extra_requirements:
+ - docs
+ system_packages: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/PKG-INFO
new/ansible-compat-2.1.0/PKG-INFO
--- old/ansible-compat-2.0.4/PKG-INFO 2022-05-16 18:24:46.884977600 +0200
+++ new/ansible-compat-2.1.0/PKG-INFO 2022-05-23 18:11:29.260798700 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ansible-compat
-Version: 2.0.4
+Version: 2.1.0
Summary: Ansible compatibility goodies
Home-page: https://github.com/ansible-community/ansible-compat
Author: Sorin Sbarnea
@@ -35,6 +35,7 @@
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
+Provides-Extra: docs
Provides-Extra: test
License-File: LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/constraints.txt
new/ansible-compat-2.1.0/constraints.txt
--- old/ansible-compat-2.0.4/constraints.txt 2022-05-16 18:24:27.000000000
+0200
+++ new/ansible-compat-2.1.0/constraints.txt 1970-01-01 01:00:00.000000000
+0100
@@ -1,58 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.9
-# To update, run:
-#
-# pip-compile --extra=test --output-file=constraints.txt setup.cfg
-#
-attrs==21.4.0
- # via pytest
-click==8.1.3
- # via pip-tools
-commonmark==0.9.1
- # via pytest-markdown
-coverage==6.3.3
- # via ansible-compat (setup.cfg)
-flaky==3.7.0
- # via ansible-compat (setup.cfg)
-iniconfig==1.1.1
- # via pytest
-more-itertools==8.13.0
- # via pytest-plus
-packaging==21.3
- # via pytest
-pep517==0.12.0
- # via pip-tools
-pip-tools==6.6.1
- # via ansible-compat (setup.cfg)
-pluggy==1.0.0
- # via pytest
-py==1.11.0
- # via pytest
-pyparsing==3.0.9
- # via packaging
-pytest==6.2.5
- # via
- # ansible-compat (setup.cfg)
- # pytest-markdown
- # pytest-mock
- # pytest-plus
-pytest-markdown==1.0.2
- # via ansible-compat (setup.cfg)
-pytest-mock==3.7.0
- # via ansible-compat (setup.cfg)
-pytest-plus==0.2
- # via ansible-compat (setup.cfg)
-pyyaml==6.0
- # via ansible-compat (setup.cfg)
-subprocess-tee==0.3.5
- # via ansible-compat (setup.cfg)
-toml==0.10.2
- # via pytest
-tomli==2.0.1
- # via pep517
-wheel==0.37.1
- # via pip-tools
-
-# The following packages are considered to be unsafe in a requirements file:
-# pip
-# setuptools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/docs/requirements.in
new/ansible-compat-2.1.0/docs/requirements.in
--- old/ansible-compat-2.0.4/docs/requirements.in 2022-05-16
18:24:27.000000000 +0200
+++ new/ansible-compat-2.1.0/docs/requirements.in 1970-01-01
01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-sphinx-autobuild>=0.7.1,<1.0
-sphinx>=4.2.0,<5.0
-sphinx_ansible_theme
-myst_parser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/docs/requirements.txt
new/ansible-compat-2.1.0/docs/requirements.txt
--- old/ansible-compat-2.0.4/docs/requirements.txt 2022-05-16
18:24:27.000000000 +0200
+++ new/ansible-compat-2.1.0/docs/requirements.txt 1970-01-01
01:00:00.000000000 +0100
@@ -1,110 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.9
-# To update, run:
-#
-# pip-compile --output-file=docs/requirements.txt docs/requirements.in
setup.cfg
-#
-alabaster==0.7.12
- # via sphinx
-ansible-pygments==0.1.1
- # via sphinx-ansible-theme
-argh==0.26.2
- # via sphinx-autobuild
-babel==2.10.1
- # via sphinx
-certifi==2021.10.8
- # via requests
-charset-normalizer==2.0.12
- # via requests
-docutils==0.17.1
- # via
- # myst-parser
- # sphinx
- # sphinx-rtd-theme
-idna==3.3
- # via requests
-imagesize==1.3.0
- # via sphinx
-importlib-metadata==4.11.3
- # via sphinx
-jinja2==3.1.2
- # via
- # myst-parser
- # sphinx
-livereload==2.6.3
- # via sphinx-autobuild
-markdown-it-py==2.1.0
- # via
- # mdit-py-plugins
- # myst-parser
-markupsafe==2.1.1
- # via jinja2
-mdit-py-plugins==0.3.0
- # via myst-parser
-mdurl==0.1.1
- # via markdown-it-py
-myst-parser==0.17.2
- # via -r docs/requirements.in
-packaging==21.3
- # via sphinx
-pathtools==0.1.2
- # via sphinx-autobuild
-port-for==0.3.1
- # via sphinx-autobuild
-pygments==2.12.0
- # via
- # ansible-pygments
- # sphinx
-pyparsing==3.0.9
- # via packaging
-pytz==2022.1
- # via babel
-pyyaml==6.0
- # via
- # ansible-compat (setup.cfg)
- # myst-parser
- # sphinx-autobuild
-requests==2.27.1
- # via sphinx
-six==1.16.0
- # via livereload
-snowballstemmer==2.2.0
- # via sphinx
-sphinx==4.5.0
- # via
- # -r docs/requirements.in
- # myst-parser
- # sphinx-ansible-theme
- # sphinx-rtd-theme
-sphinx-ansible-theme==0.9.1
- # via -r docs/requirements.in
-sphinx-autobuild==0.7.1
- # via -r docs/requirements.in
-sphinx-rtd-theme==1.0.0
- # via sphinx-ansible-theme
-sphinxcontrib-applehelp==1.0.2
- # via sphinx
-sphinxcontrib-devhelp==1.0.2
- # via sphinx
-sphinxcontrib-htmlhelp==2.0.0
- # via sphinx
-sphinxcontrib-jsmath==1.0.1
- # via sphinx
-sphinxcontrib-qthelp==1.0.3
- # via sphinx
-sphinxcontrib-serializinghtml==1.1.5
- # via sphinx
-subprocess-tee==0.3.5
- # via ansible-compat (setup.cfg)
-tornado==6.1
- # via
- # livereload
- # sphinx-autobuild
-typing-extensions==4.2.0
- # via myst-parser
-urllib3==1.26.9
- # via requests
-watchdog==2.1.8
- # via sphinx-autobuild
-zipp==3.8.0
- # via importlib-metadata
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/requirements.txt
new/ansible-compat-2.1.0/requirements.txt
--- old/ansible-compat-2.0.4/requirements.txt 1970-01-01 01:00:00.000000000
+0100
+++ new/ansible-compat-2.1.0/requirements.txt 2022-05-23 18:11:08.000000000
+0200
@@ -0,0 +1,162 @@
+#
+# This file is autogenerated by pip-compile with python 3.9
+# To update, run:
+#
+# pip-compile --extra=docs --extra=test --output-file=requirements.txt
setup.cfg
+#
+alabaster==0.7.12
+ # via sphinx
+ansible-pygments==0.1.1
+ # via sphinx-ansible-theme
+argh==0.26.2
+ # via sphinx-autobuild
+attrs==21.4.0
+ # via
+ # jsonschema
+ # pytest
+babel==2.10.1
+ # via sphinx
+certifi==2022.5.18.1
+ # via requests
+charset-normalizer==2.0.12
+ # via requests
+click==8.1.3
+ # via pip-tools
+commonmark==0.9.1
+ # via pytest-markdown
+coverage==6.3.3
+ # via ansible-compat (setup.cfg)
+docutils==0.17.1
+ # via
+ # myst-parser
+ # sphinx
+ # sphinx-rtd-theme
+flaky==3.7.0
+ # via ansible-compat (setup.cfg)
+idna==3.3
+ # via requests
+imagesize==1.3.0
+ # via sphinx
+importlib-metadata==4.11.3
+ # via sphinx
+iniconfig==1.1.1
+ # via pytest
+jinja2==3.1.2
+ # via
+ # myst-parser
+ # sphinx
+jsonschema==4.5.1
+ # via ansible-compat (setup.cfg)
+livereload==2.6.3
+ # via sphinx-autobuild
+markdown-it-py==2.1.0
+ # via
+ # mdit-py-plugins
+ # myst-parser
+markupsafe==2.1.1
+ # via jinja2
+mdit-py-plugins==0.3.0
+ # via myst-parser
+mdurl==0.1.1
+ # via markdown-it-py
+more-itertools==8.13.0
+ # via pytest-plus
+myst-parser==0.17.2
+ # via ansible-compat (setup.cfg)
+packaging==21.3
+ # via
+ # pytest
+ # sphinx
+pathtools==0.1.2
+ # via sphinx-autobuild
+pep517==0.12.0
+ # via pip-tools
+pip-tools==6.6.1
+ # via ansible-compat (setup.cfg)
+pluggy==1.0.0
+ # via pytest
+port-for==0.3.1
+ # via sphinx-autobuild
+py==1.11.0
+ # via pytest
+pygments==2.12.0
+ # via
+ # ansible-pygments
+ # sphinx
+pyparsing==3.0.9
+ # via packaging
+pyrsistent==0.18.1
+ # via jsonschema
+pytest==6.2.5
+ # via
+ # ansible-compat (setup.cfg)
+ # pytest-markdown
+ # pytest-mock
+ # pytest-plus
+pytest-markdown==1.0.2
+ # via ansible-compat (setup.cfg)
+pytest-mock==3.7.0
+ # via ansible-compat (setup.cfg)
+pytest-plus==0.2
+ # via ansible-compat (setup.cfg)
+pytz==2022.1
+ # via babel
+pyyaml==6.0
+ # via
+ # ansible-compat (setup.cfg)
+ # myst-parser
+ # sphinx-autobuild
+requests==2.27.1
+ # via sphinx
+six==1.16.0
+ # via livereload
+snowballstemmer==2.2.0
+ # via sphinx
+sphinx==4.5.0
+ # via
+ # ansible-compat (setup.cfg)
+ # myst-parser
+ # sphinx-ansible-theme
+ # sphinx-rtd-theme
+sphinx-ansible-theme==0.9.1
+ # via ansible-compat (setup.cfg)
+sphinx-autobuild==0.7.1
+ # via ansible-compat (setup.cfg)
+sphinx-rtd-theme==1.0.0
+ # via sphinx-ansible-theme
+sphinxcontrib-applehelp==1.0.2
+ # via sphinx
+sphinxcontrib-devhelp==1.0.2
+ # via sphinx
+sphinxcontrib-htmlhelp==2.0.0
+ # via sphinx
+sphinxcontrib-jsmath==1.0.1
+ # via sphinx
+sphinxcontrib-qthelp==1.0.3
+ # via sphinx
+sphinxcontrib-serializinghtml==1.1.5
+ # via sphinx
+subprocess-tee==0.3.5
+ # via ansible-compat (setup.cfg)
+toml==0.10.2
+ # via pytest
+tomli==2.0.1
+ # via pep517
+tornado==6.1
+ # via
+ # livereload
+ # sphinx-autobuild
+typing-extensions==4.2.0
+ # via myst-parser
+urllib3==1.26.9
+ # via requests
+watchdog==2.1.8
+ # via sphinx-autobuild
+wheel==0.37.1
+ # via pip-tools
+zipp==3.8.0
+ # via importlib-metadata
+
+# The following packages are considered to be unsafe in a requirements file:
+# pip
+# setuptools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/setup.cfg
new/ansible-compat-2.1.0/setup.cfg
--- old/ansible-compat-2.0.4/setup.cfg 2022-05-16 18:24:46.884977600 +0200
+++ new/ansible-compat-2.1.0/setup.cfg 2022-05-23 18:11:29.260798700 +0200
@@ -56,8 +56,14 @@
install_requires =
PyYAML
subprocess-tee >= 0.3.5
+ jsonschema >= 4.5.1
[options.extras_require]
+docs =
+ sphinx-autobuild>=0.7.1,<1.0
+ sphinx>=4.2.0,<5.0
+ sphinx_ansible_theme
+ myst_parser
test =
coverage
flaky
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/src/ansible_compat/runtime.py
new/ansible-compat-2.1.0/src/ansible_compat/runtime.py
--- old/ansible-compat-2.0.4/src/ansible_compat/runtime.py 2022-05-16
18:24:27.000000000 +0200
+++ new/ansible-compat-2.1.0/src/ansible_compat/runtime.py 2022-05-23
18:11:08.000000000 +0200
@@ -302,6 +302,7 @@
retry: bool = False,
install_local: bool = False,
offline: bool = False,
+ role_name_check: int = 0,
) -> None:
"""Make dependencies available if needed."""
if required_collections is None:
@@ -342,7 +343,9 @@
self.install_collection_from_disk("../..", destination=destination)
else:
# no collection, try to recognize and install a standalone role
- self._install_galaxy_role(self.project_dir, ignore_errors=True)
+ self._install_galaxy_role(
+ self.project_dir, role_name_check=role_name_check,
ignore_errors=True
+ )
def require_collection( # noqa: C901
self,
@@ -447,6 +450,20 @@
if roles_path != self.config.default_roles_path:
self._update_env("ANSIBLE_ROLES_PATH", roles_path)
+ def _get_roles_path(self) -> pathlib.Path:
+ """Return roles installation path.
+
+ If `self.isolated` is set to `True`, `self.cache_dir` would be
+ created, then it returns the `self.cache_dir/roles`. When
`self.isolated` is
+ not mentioned or set to `False`, it returns the first path in
+ `default_roles_path`.
+ """
+ if self.cache_dir:
+ path = pathlib.Path(f"{self.cache_dir}/roles")
+ else:
+ path =
pathlib.Path(os.path.expanduser(self.config.default_roles_path[0]))
+ return path
+
def _install_galaxy_role(
self, project_dir: str, role_name_check: int = 0, ignore_errors: bool
= False
) -> None:
@@ -495,16 +512,19 @@
fqrn = f"{role_namespace}{role_name}"
else:
fqrn = pathlib.Path(project_dir).absolute().name
- path =
pathlib.Path(os.path.expanduser(self.config.default_roles_path[0]))
+ path = self._get_roles_path()
path.mkdir(parents=True, exist_ok=True)
link_path = path / fqrn
# despite documentation stating that is_file() reports true for
symlinks,
# it appears that is_dir() reports true instead, so we rely on
exists().
target = pathlib.Path(project_dir).absolute()
- exists = link_path.exists() or link_path.is_symlink()
- if not exists or os.readlink(link_path) != str(target):
- if link_path.exists():
- link_path.unlink()
+ if not link_path.exists() or (
+ link_path.is_symlink() and os.readlink(link_path) != str(target)
+ ):
+ # must call unlink before checking exists because a broken
+ # link reports as not existing and we want to repair it
+ link_path.unlink(missing_ok=True)
+ # https://github.com/python/cpython/issues/73843
link_path.symlink_to(str(target), target_is_directory=True)
_logger.info(
"Using %s symlink to current repository in order to enable Ansible
to find the role using its expected full name.",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/src/ansible_compat/schema.py
new/ansible-compat-2.1.0/src/ansible_compat/schema.py
--- old/ansible-compat-2.0.4/src/ansible_compat/schema.py 1970-01-01
01:00:00.000000000 +0100
+++ new/ansible-compat-2.1.0/src/ansible_compat/schema.py 2022-05-23
18:11:08.000000000 +0200
@@ -0,0 +1,128 @@
+"""Utils for JSON Schema validation."""
+import json
+from dataclasses import dataclass
+from typing import Any, Deque, Dict, List, Mapping, Union
+
+import jsonschema
+from jsonschema.validators import validator_for
+
+
+def to_path(schema_path: Deque[str]) -> str:
+ """Flatten a path to a dot delimited string.
+
+ :param schema_path: The schema path
+ :returns: The dot delimited path
+ """
+ return ".".join(str(index) for index in schema_path)
+
+
+def json_path(absolute_path: Deque[str]) -> str:
+ """Flatten a data path to a dot delimited string.
+
+ :param absolute_path: The path
+ :returns: The dot delimited string
+ """
+ path = "$"
+ for elem in absolute_path:
+ if isinstance(elem, int):
+ path += "[" + str(elem) + "]"
+ else:
+ path += "." + elem
+ return path
+
+
+@dataclass
+class JsonSchemaError:
+ # pylint: disable=too-many-instance-attributes
+ """Data structure to hold a json schema validation error."""
+
+ message: str
+ data_path: str
+ json_path: str
+ schema_path: str
+ relative_schema: str
+ expected: Union[bool, int, str]
+ validator: str
+ found: str
+
+ @property
+ def _hash_key(self) -> Any:
+ # line attr is knowingly excluded, as dict is not hashable
+ return (
+ self.schema_path,
+ self.data_path,
+ self.json_path,
+ self.message,
+ self.expected,
+ )
+
+ def __hash__(self) -> int:
+ """Return a hash value of the instance."""
+ return hash(self._hash_key)
+
+ def __eq__(self, other: object) -> bool:
+ """Identify whether the other object represents the same rule match."""
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.__hash__() == other.__hash__()
+
+ def __lt__(self, other: object) -> bool:
+ """Return whether the current object is less than the other."""
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return bool(self._hash_key < other._hash_key)
+
+ def to_friendly(self) -> str:
+ """Provide a friendly explanation of the error.
+
+ :returns: The error message
+ """
+ return f"In '{self.data_path}': {self.message}."
+
+
+def validate(
+ schema: Union[str, Mapping[str, Any]], data: Dict[str, Any]
+) -> List[JsonSchemaError]:
+ """Validate some data against a JSON schema.
+
+ :param schema: the JSON schema to use for validation
+ :param data: The data to validate
+ :returns: Any errors encountered
+ """
+ errors: List[JsonSchemaError] = []
+
+ if isinstance(schema, str):
+ schema = json.loads(schema)
+ try:
+ if not isinstance(schema, Mapping):
+ raise jsonschema.SchemaError("Invalid schema, must be a mapping")
+ validator = validator_for(schema)
+ validator.check_schema(schema)
+ except jsonschema.SchemaError as exc:
+ error = JsonSchemaError(
+ message=str(exc),
+ data_path="schema sanity check",
+ json_path="",
+ schema_path="",
+ relative_schema="",
+ expected="",
+ validator="",
+ found="",
+ )
+ errors.append(error)
+ return errors
+
+ for validation_error in validator(schema).iter_errors(data):
+ if isinstance(validation_error, jsonschema.ValidationError):
+ error = JsonSchemaError(
+ message=validation_error.message,
+ data_path=to_path(validation_error.absolute_path),
+ json_path=json_path(validation_error.absolute_path),
+ schema_path=to_path(validation_error.schema_path),
+ relative_schema=validation_error.schema,
+ expected=validation_error.validator_value,
+ validator=validation_error.validator,
+ found=str(validation_error.instance),
+ )
+ errors.append(error)
+ return sorted(errors)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-2.0.4/src/ansible_compat.egg-info/PKG-INFO
new/ansible-compat-2.1.0/src/ansible_compat.egg-info/PKG-INFO
--- old/ansible-compat-2.0.4/src/ansible_compat.egg-info/PKG-INFO
2022-05-16 18:24:46.000000000 +0200
+++ new/ansible-compat-2.1.0/src/ansible_compat.egg-info/PKG-INFO
2022-05-23 18:11:28.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ansible-compat
-Version: 2.0.4
+Version: 2.1.0
Summary: Ansible compatibility goodies
Home-page: https://github.com/ansible-community/ansible-compat
Author: Sorin Sbarnea
@@ -35,6 +35,7 @@
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
+Provides-Extra: docs
Provides-Extra: test
License-File: LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-2.0.4/src/ansible_compat.egg-info/SOURCES.txt
new/ansible-compat-2.1.0/src/ansible_compat.egg-info/SOURCES.txt
--- old/ansible-compat-2.0.4/src/ansible_compat.egg-info/SOURCES.txt
2022-05-16 18:24:46.000000000 +0200
+++ new/ansible-compat-2.1.0/src/ansible_compat.egg-info/SOURCES.txt
2022-05-23 18:11:29.000000000 +0200
@@ -2,13 +2,14 @@
.gitignore
.pre-commit-config.yaml
.pylintrc
+.readthedocs.yml
.yamllint
LICENSE
README.md
codecov.yml
-constraints.txt
mypy.ini
pyproject.toml
+requirements.txt
setup.cfg
tox.ini
.github/CODEOWNERS
@@ -21,8 +22,6 @@
docs/conf.py
docs/examples.md
docs/index.md
-docs/requirements.in
-docs/requirements.txt
examples/reqs_v1/requirements.yml
examples/reqs_v2/requirements.yml
src/ansible_compat/__init__.py
@@ -34,6 +33,7 @@
src/ansible_compat/prerun.py
src/ansible_compat/py.typed
src/ansible_compat/runtime.py
+src/ansible_compat/schema.py
src/ansible_compat.egg-info/PKG-INFO
src/ansible_compat.egg-info/SOURCES.txt
src/ansible_compat.egg-info/dependency_links.txt
@@ -48,6 +48,7 @@
test/test_prerun.py
test/test_runtime.py
test/test_runtime_example.py
+test/test_schema.py
test/assets/requirements-invalid-collection.yml
test/assets/requirements-invalid-role.yml
test/collections/acme.broken/galaxy.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-compat-2.0.4/src/ansible_compat.egg-info/requires.txt
new/ansible-compat-2.1.0/src/ansible_compat.egg-info/requires.txt
--- old/ansible-compat-2.0.4/src/ansible_compat.egg-info/requires.txt
2022-05-16 18:24:46.000000000 +0200
+++ new/ansible-compat-2.1.0/src/ansible_compat.egg-info/requires.txt
2022-05-23 18:11:29.000000000 +0200
@@ -1,5 +1,12 @@
PyYAML
subprocess-tee>=0.3.5
+jsonschema>=4.5.1
+
+[docs]
+sphinx-autobuild<1.0,>=0.7.1
+sphinx<5.0,>=4.2.0
+sphinx_ansible_theme
+myst_parser
[test]
coverage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/test/test_runtime.py
new/ansible-compat-2.1.0/test/test_runtime.py
--- old/ansible-compat-2.0.4/test/test_runtime.py 2022-05-16
18:24:27.000000000 +0200
+++ new/ansible-compat-2.1.0/test/test_runtime.py 2022-05-23
18:11:08.000000000 +0200
@@ -134,6 +134,12 @@
result = runtime.exec(["ansible-galaxy", "list"])
assert result.returncode == 0, result
assert role_name in result.stdout
+ if isolated:
+ assert
pathlib.Path(f"{runtime.cache_dir}/roles/{role_name}").is_symlink()
+ else:
+ assert pathlib.Path(
+
f"{os.path.expanduser(runtime.config.default_roles_path[0])}/{role_name}"
+ ).is_symlink()
runtime.clean()
# also test that clean does not break when cache_dir is missing
tmp_dir = runtime.cache_dir
@@ -505,6 +511,36 @@
runtime_tmp._install_galaxy_role(runtime_tmp.project_dir,
role_name_check=1)
[email protected](
+ "galaxy_info",
+ (
+ """galaxy_info:
+ role_name: foo-bar
+ namespace: acme
+""",
+ """galaxy_info:
+ role_name: foo-bar
+""",
+ ),
+ ids=("bad-name", "bad-name-without-namespace"),
+)
+def test_install_galaxy_role_name_role_name_check_equals_to_1(
+ runtime_tmp: Runtime,
+ galaxy_info: str,
+ caplog: pytest.LogCaptureFixture,
+) -> None:
+ """Check install role with bad role name in galaxy info."""
+ caplog.set_level(logging.WARN)
+ pathlib.Path(f"{runtime_tmp.project_dir}/meta").mkdir()
+ pathlib.Path(f"{runtime_tmp.project_dir}/meta/main.yml").write_text(
+ galaxy_info,
+ encoding="utf-8",
+ )
+
+ runtime_tmp._install_galaxy_role(runtime_tmp.project_dir,
role_name_check=1)
+ assert "Computed fully qualified role name of " in caplog.text
+
+
def test_install_galaxy_role_no_checks(runtime_tmp: Runtime) -> None:
"""Check install role with bad namespace in galaxy info."""
runtime_tmp.prepare_environment()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/test/test_schema.py
new/ansible-compat-2.1.0/test/test_schema.py
--- old/ansible-compat-2.0.4/test/test_schema.py 1970-01-01
01:00:00.000000000 +0100
+++ new/ansible-compat-2.1.0/test/test_schema.py 2022-05-23
18:11:08.000000000 +0200
@@ -0,0 +1,48 @@
+"""Tests for schema utilities."""
+from ansible_compat.schema import JsonSchemaError, validate
+
+schema = {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "properties": {
+ "environment": {"type": "object", "additionalProperties": {"type":
"string"}}
+ },
+}
+
+instance = {"environment": {"a": False, "b": True, "c": "foo"}}
+
+expected_results = [
+ JsonSchemaError(
+ message="False is not of type 'string'",
+ data_path="environment.a",
+ json_path="$.environment.a",
+ schema_path="properties.environment.additionalProperties.type",
+ relative_schema='{"type": "string"}',
+ expected="string",
+ validator="type",
+ found="False",
+ ),
+ JsonSchemaError(
+ message="True is not of type 'string'",
+ data_path="environment.b",
+ json_path="$.environment.b",
+ schema_path="properties.environment.additionalProperties.type",
+ relative_schema='{"type": "string"}',
+ expected="string",
+ validator="type",
+ found="True",
+ ),
+]
+
+
+def test_schema() -> None:
+ """Test the schema validator."""
+ results = validate(schema=schema, data=instance)
+ # ensure we produce consistent results between runs
+ for _ in range(1, 100):
+ new_results = validate(schema=schema, data=instance)
+ assert results == new_results, "inconsistent returns"
+ # print(result)
+ assert len(results) == len(expected_results)
+ assert sorted(results) == results, "multiple errors not sorted"
+ for i, result in enumerate(results):
+ assert result == expected_results[i]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-compat-2.0.4/tox.ini
new/ansible-compat-2.1.0/tox.ini
--- old/ansible-compat-2.0.4/tox.ini 2022-05-16 18:24:27.000000000 +0200
+++ new/ansible-compat-2.1.0/tox.ini 2022-05-23 18:11:08.000000000 +0200
@@ -50,9 +50,9 @@
setenv =
COVERAGE_FILE = {env:COVERAGE_FILE:{toxworkdir}/.coverage.{envname}}
PIP_DISABLE_PIP_VERSION_CHECK = 1
- PIP_CONSTRAINT = {toxinidir}/constraints.txt
+ PIP_CONSTRAINT = {toxinidir}/requirements.txt
PRE_COMMIT_COLOR = always
- PYTEST_REQPASS = 75
+ PYTEST_REQPASS = 78
FORCE_COLOR = 1
allowlist_externals =
ansible
@@ -75,7 +75,7 @@
PRE_COMMIT_HOME
[testenv:deps]
-description = Bump all test depeendencies
+description = Bump all test dependencies
basepython = {[testenv:lint]basepython}
envdir = {toxworkdir}/lint
deps = {[testenv:lint]deps}
@@ -123,6 +123,5 @@
-d "{toxworkdir}/doctree" \
docs/ "{toxworkdir}/html"
deps =
- -r docs/requirements.txt
- --editable .
+ --editable .[docs]
passenv = *