Ejemplo n.º 1
0
def removal_version(value, is_ansible, current_version=None, is_tombstone=False):
    """Validate a removal version string."""
    msg = (
        'Removal version must be a string' if is_ansible else
        'Removal version must be a semantic version (https://semver.org/)'
    )
    if not isinstance(value, string_types):
        raise Invalid(msg)
    try:
        if is_ansible:
            version = StrictVersion()
            version.parse(value)
            version = LooseVersion(value)  # We're storing Ansible's version as a LooseVersion
        else:
            version = SemanticVersion()
            version.parse(value)
            if version.major != 0 and (version.minor != 0 or version.patch != 0):
                raise Invalid('removal_version (%r) must be a major release, not a minor or patch release '
                              '(see specification at https://semver.org/)' % (value, ))
        if current_version is not None:
            if is_tombstone:
                # For a tombstone, the removal version must not be in the future
                if version > current_version:
                    raise Invalid('The tombstone removal_version (%r) must not be after the '
                                  'current version (%s)' % (value, current_version))
            else:
                # For a deprecation, the removal version must be in the future
                if version <= current_version:
                    raise Invalid('The deprecation removal_version (%r) must be after the '
                                  'current version (%s)' % (value, current_version))
    except ValueError:
        raise Invalid(msg)
    return value
Ejemplo n.º 2
0
def find_deprecations(obj, path=None):
    if not isinstance(obj, (list, dict)):
        return

    try:
        items = obj.items()
    except AttributeError:
        items = enumerate(obj)

    for key, value in items:
        if path is None:
            this_path = []
        else:
            this_path = path[:]

        this_path.append(key)

        if key != 'deprecated':
            for result in find_deprecations(value, path=this_path):
                yield result
        else:
            try:
                version = value['version']
                this_path.append('version')
            except KeyError:
                version = value['removed_in']
                this_path.append('removed_in')
            if StrictVersion(version) <= ANSIBLE_MAJOR:
                yield (this_path, version)
Ejemplo n.º 3
0
def check_removal_version(v, version_field, collection_name_field, error_code='invalid-removal-version'):
    version = v.get(version_field)
    collection_name = v.get(collection_name_field)
    if not isinstance(version, string_types) or not isinstance(collection_name, string_types):
        # If they are not strings, schema validation will have already complained.
        return v
    if collection_name == 'ansible.builtin':
        try:
            parsed_version = StrictVersion()
            parsed_version.parse(version)
        except ValueError as exc:
            raise _add_ansible_error_code(
                Invalid('%s (%r) is not a valid ansible-core version: %s' % (version_field, version, exc)),
                error_code=error_code)
        return v
    try:
        parsed_version = SemanticVersion()
        parsed_version.parse(version)
        if parsed_version.major != 0 and (parsed_version.minor != 0 or parsed_version.patch != 0):
            raise _add_ansible_error_code(
                Invalid('%s (%r) must be a major release, not a minor or patch release (see specification at '
                        'https://semver.org/)' % (version_field, version)),
                error_code='removal-version-must-be-major')
    except ValueError as exc:
        raise _add_ansible_error_code(
            Invalid('%s (%r) is not a valid collection version (see specification at https://semver.org/): '
                    '%s' % (version_field, version, exc)),
            error_code=error_code)
    return v
Ejemplo n.º 4
0
def version_added(v,
                  error_code='version-added-invalid',
                  accept_historical=False):
    if 'version_added' in v:
        version_added = v.get('version_added')
        if isinstance(version_added, string_types):
            # If it is not a string, schema validation will have already complained
            # - or we have a float and we are in ansible/ansible, in which case we're
            # also happy.
            if v.get('version_added_collection') == 'ansible.builtin':
                if version_added == 'historical' and accept_historical:
                    return v
                try:
                    version = StrictVersion()
                    version.parse(version_added)
                except ValueError as exc:
                    raise _add_ansible_error_code(Invalid(
                        'version_added (%r) is not a valid ansible-core version: '
                        '%s' % (version_added, exc)),
                                                  error_code=error_code)
            else:
                try:
                    version = SemanticVersion()
                    version.parse(version_added)
                    if version.major != 0 and version.patch != 0:
                        raise _add_ansible_error_code(
                            Invalid(
                                'version_added (%r) must be a major or minor release, '
                                'not a patch release (see specification at '
                                'https://semver.org/)' % (version_added, )),
                            error_code='version-added-must-be-major-or-minor')
                except ValueError as exc:
                    raise _add_ansible_error_code(Invalid(
                        'version_added (%r) is not a valid collection version '
                        '(see specification at https://semver.org/): '
                        '%s' % (version_added, exc)),
                                                  error_code=error_code)
    elif 'version_added_collection' in v:
        # Must have been manual intervention, since version_added_collection is only
        # added automatically when version_added is present
        raise Invalid(
            'version_added_collection cannot be specified without version_added'
        )
    return v
Ejemplo n.º 5
0
import os
import re
import sys

from ansible.module_utils.compat.version import StrictVersion

import yaml

import ansible.config

from ansible.plugins.loader import fragment_loader
from ansible.release import __version__ as ansible_version
from ansible.utils.plugin_docs import get_docstring

DOC_RE = re.compile(b'^DOCUMENTATION', flags=re.M)
ANSIBLE_MAJOR = StrictVersion('.'.join(ansible_version.split('.')[:2]))


def find_deprecations(obj, path=None):
    if not isinstance(obj, (list, dict)):
        return

    try:
        items = obj.items()
    except AttributeError:
        items = enumerate(obj)

    for key, value in items:
        if path is None:
            this_path = []
        else:
Ejemplo n.º 6
0
    ('0.1.2+bob', False),
    ('1.0.0', True),
    ('1.0.0+bob', True),
]

LOOSE_VERSION = [
    (LooseVersion('1'), SemanticVersion('1.0.0')),
    (LooseVersion('1-alpha'), SemanticVersion('1.0.0-alpha')),
    (LooseVersion('1.0.0-alpha+build'), SemanticVersion('1.0.0-alpha+build')),
]

LOOSE_VERSION_INVALID = [
    LooseVersion('1.a.3'),
    LooseVersion(),
    'bar',
    StrictVersion('1.2.3'),
]


def test_semanticversion_none():
    assert SemanticVersion().major is None


@pytest.mark.parametrize('left,right,expected', EQ)
def test_eq(left, right, expected):
    assert (SemanticVersion(left) == SemanticVersion(right)) is expected


@pytest.mark.parametrize('left,right,expected', NE)
def test_ne(left, right, expected):
    assert (SemanticVersion(left) != SemanticVersion(right)) is expected