summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Martz <matt@sivel.net>2022-07-21 15:56:14 -0500
committerGitHub <noreply@github.com>2022-07-21 15:56:14 -0500
commit1429672213af648aef239138745d593e2920ebdd (patch)
tree5862c2f9a60d0cf69aea32fdbf91a1f8d5cbe23c
parent9d4ced1237380051334b54379ff64e45c0341a6d (diff)
downloadansible-1429672213af648aef239138745d593e2920ebdd.tar.gz
Add pep440 version_type for version test (#78308)
-rw-r--r--changelogs/fragments/pep440-version-type.yml3
-rw-r--r--docs/docsite/rst/playbook_guide/playbooks_tests.rst20
-rw-r--r--lib/ansible/plugins/test/core.py10
-rw-r--r--lib/ansible/plugins/test/version.yml81
l---------lib/ansible/plugins/test/version_compare.yml1
-rw-r--r--test/integration/targets/test_core/tasks/main.yml1
6 files changed, 115 insertions, 1 deletions
diff --git a/changelogs/fragments/pep440-version-type.yml b/changelogs/fragments/pep440-version-type.yml
new file mode 100644
index 0000000000..ca9e5f29fe
--- /dev/null
+++ b/changelogs/fragments/pep440-version-type.yml
@@ -0,0 +1,3 @@
+minor_changes:
+- Jinja version test - Add pep440 version_type for version test.
+ (https://github.com/ansible/ansible/issues/78288)
diff --git a/docs/docsite/rst/playbook_guide/playbooks_tests.rst b/docs/docsite/rst/playbook_guide/playbooks_tests.rst
index 75e041bc11..71eaee838b 100644
--- a/docs/docsite/rst/playbook_guide/playbooks_tests.rst
+++ b/docs/docsite/rst/playbook_guide/playbooks_tests.rst
@@ -169,7 +169,19 @@ As of Ansible 2.11 the ``version`` test accepts a ``version_type`` parameter whi
.. code-block:: console
- loose, strict, semver, semantic
+ loose, strict, semver, semantic, pep440
+
+``loose``
+ This type corresponds to the Python ``distutils.version.LooseVersion`` class. All version formats are valid for this type. The rules for comparison are simple and predictable, but may not always give expected results.
+
+``strict``
+ This type corresponds to the Python ``distutils.version.StrictVersion`` class. A version number consists of two or three dot-separated numeric components, with an optional "pre-release" tag on the end. The pre-release tag consists of a single letter 'a' or 'b' followed by a number. If the numeric components of two version numbers are equal, then one with a pre-release tag will always be deemed earlier (lesser) than one without.
+
+``semver``/``semantic``
+ This type implements the `Semantic Version <https://semver.org>`_ scheme for version comparison.
+
+``pep440``
+ This type implements the Python `PEP-440 <https://peps.python.org/pep-0440/>`_ versioning rules for version comparison. Added in version 2.14.
Using ``version_type`` to compare a semantic version would be achieved like the following
@@ -177,6 +189,12 @@ Using ``version_type`` to compare a semantic version would be achieved like the
{{ sample_semver_var is version('2.0.0-rc.1+build.123', 'lt', version_type='semver') }}
+In Ansible 2.14, the ``pep440`` option for ``version_type`` was added, and the rules of this type are defined in `PEP-440 <https://peps.python.org/pep-0440/>`_. The following example showcases how this type can differentiate pre-releases as being less than a general release.
+
+.. code-block:: yaml+jinja
+
+ {{ '2.14.0rc1' is version('2.14.0', 'lt', version_type='pep440') }}
+
When using ``version`` in a playbook or role, don't use ``{{ }}`` as described in the `FAQ <https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#when-should-i-use-also-how-to-interpolate-variables-or-dynamic-variable-names>`_
.. code-block:: yaml
diff --git a/lib/ansible/plugins/test/core.py b/lib/ansible/plugins/test/core.py
index 01faff9848..d9e7e8b61d 100644
--- a/lib/ansible/plugins/test/core.py
+++ b/lib/ansible/plugins/test/core.py
@@ -32,6 +32,12 @@ from ansible.module_utils.parsing.convert_bool import boolean
from ansible.utils.display import Display
from ansible.utils.version import SemanticVersion
+try:
+ from packaging.version import Version as PEP440Version
+ HAS_PACKAGING = True
+except ImportError:
+ HAS_PACKAGING = False
+
display = Display()
@@ -165,6 +171,7 @@ def version_compare(value, version, operator='eq', strict=None, version_type=Non
'strict': StrictVersion,
'semver': SemanticVersion,
'semantic': SemanticVersion,
+ 'pep440': PEP440Version,
}
if strict is not None and version_type is not None:
@@ -176,6 +183,9 @@ def version_compare(value, version, operator='eq', strict=None, version_type=Non
if not version:
raise errors.AnsibleFilterError("Version parameter to compare against cannot be empty")
+ if version_type == 'pep440' and not HAS_PACKAGING:
+ raise errors.AnsibleFilterError("The pep440 version_type requires the Python 'packaging' library")
+
Version = LooseVersion
if strict:
Version = StrictVersion
diff --git a/lib/ansible/plugins/test/version.yml b/lib/ansible/plugins/test/version.yml
new file mode 100644
index 0000000000..0ecd38cec9
--- /dev/null
+++ b/lib/ansible/plugins/test/version.yml
@@ -0,0 +1,81 @@
+DOCUMENTATION:
+ name: version
+ author: Ansible Core
+ version_added: "1.6"
+ short_description: compare version strings
+ description:
+ - Compare version strings using various versioning schemes
+ options:
+ _input:
+ description: Left hand version to compare
+ type: string
+ required: True
+ version:
+ description: Right hand version to compare
+ type: string
+ required: True
+ operator:
+ description: Comparison operator
+ type: string
+ required: False
+ choices:
+ - ==
+ - '='
+ - eq
+ - <
+ - lt
+ - <=
+ - le
+ - '>'
+ - gt
+ - '>='
+ - ge
+ - '!='
+ - <>
+ - ne
+ default: eq
+ strict:
+ description: Whether to use strict version scheme. Mutually exclusive with C(version_type)
+ type: boolean
+ required: False
+ default: False
+ version_type:
+ description: Version scheme to use for comparison. Mutually exclusive with C(strict). See C(notes) for descriptions on the version types.
+ type: string
+ required: False
+ choices:
+ - loose
+ - strict
+ - semver
+ - semantic
+ - pep440
+ default: loose
+ notes:
+ - C(loose) - This type corresponds to the Python C(distutils.version.LooseVersion) class. All version formats are valid for this type. The rules for comparison are simple and predictable, but may not always give expected results.
+ - C(strict) - This type corresponds to the Python C(distutils.version.StrictVersion) class. A version number consists of two or three dot-separated numeric components, with an optional "pre-release" tag on the end. The pre-release tag consists of a single letter C(a) or C(b) followed by a number. If the numeric components of two version numbers are equal, then one with a pre-release tag will always be deemed earlier (lesser) than one without.
+ - C(semver)/C(semantic) - This type implements the L(Semantic Version,https://semver.org) scheme for version comparison.
+ - C(pep440) - This type implements the Python L(PEP-440,https://peps.python.org/pep-0440/) versioning rules for version comparison. Added in version 2.14.
+EXAMPLES: |
+ - name: version test examples
+ assert:
+ that:
+ - "'1.0' is version_compare('1.0', '==')" # old name
+ - "'1.0' is version('1.0', '==')"
+ - "'1.0' is version('2.0', '!=')"
+ - "'1.0' is version('2.0', '<')"
+ - "'2.0' is version('1.0', '>')"
+ - "'1.0' is version('1.0', '<=')"
+ - "'1.0' is version('1.0', '>=')"
+ - "'1.0' is version_compare('1.0', '==', strict=true)" # old name
+ - "'1.0' is version('1.0', '==', strict=true)"
+ - "'1.0' is version('2.0', '!=', strict=true)"
+ - "'1.0' is version('2.0', '<', strict=true)"
+ - "'2.0' is version('1.0', '>', strict=true)"
+ - "'1.0' is version('1.0', '<=', strict=true)"
+ - "'1.0' is version('1.0', '>=', strict=true)"
+ - "'1.2.3' is version('2.0.0', 'lt', version_type='semver')"
+ - "'2.14.0rc1' is version('2.14.0', 'lt', version_type='pep440')"
+RETURN:
+ _value:
+ description: Returns C(True) or C(False) depending on the outcome of the comparison.
+ type: boolean
diff --git a/lib/ansible/plugins/test/version_compare.yml b/lib/ansible/plugins/test/version_compare.yml
new file mode 120000
index 0000000000..d752ae7afe
--- /dev/null
+++ b/lib/ansible/plugins/test/version_compare.yml
@@ -0,0 +1 @@
+version.yml \ No newline at end of file
diff --git a/test/integration/targets/test_core/tasks/main.yml b/test/integration/targets/test_core/tasks/main.yml
index 9f753e3cb9..8c2decbdee 100644
--- a/test/integration/targets/test_core/tasks/main.yml
+++ b/test/integration/targets/test_core/tasks/main.yml
@@ -271,6 +271,7 @@
- "'1.0' is version('1.0', '<=', true)"
- "'1.0' is version('1.0', '>=', true)"
- "'1.2.3' is version('2.0.0', 'lt', version_type='semver')"
+ - "'2.14.0rc1' is version('2.14.0', 'lt', version_type='pep440')"
- version_bad_operator is failed
- version_bad_value is failed
- version_strict_version_type is failed