def set_option(self, optname, value, action=None, optdict=None): super(AssibleDeprecatedChecker, self).set_option(optname, value, action, optdict) if optname == 'collection-version' and value is not None: self.collection_version = SemanticVersion( self.config.collection_version) if optname == 'collection-name' and value is not None: self.collection_name = self.config.collection_name
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 assible/assible, in which case we're # also happy. if v.get('version_added_collection') == 'assible.builtin': if version_added == 'historical' and accept_historical: return v try: version = StrictVersion() version.parse(version_added) except ValueError as exc: raise _add_assible_error_code(Invalid( 'version_added (%r) is not a valid assible-base 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_assible_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_assible_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
def _check_version(self, node, version, collection_name): if not isinstance(version, (str, float)): self.add_message('invalid-version', node=node, args=(version, )) return version_no = str(version) if collection_name == 'assible.builtin': # Assible-base try: if not version_no: raise ValueError('Version string should not be empty') loose_version = LooseVersion(str(version_no)) if ASSIBLE_VERSION >= loose_version: self.add_message('assible-deprecated-version', node=node, args=(version, )) except ValueError: self.add_message('assible-invalid-deprecated-version', node=node, args=(version, )) elif collection_name: # Collections try: if not version_no: raise ValueError('Version string should not be empty') semantic_version = SemanticVersion(version_no) if collection_name == self.collection_name and self.collection_version is not None: if self.collection_version >= semantic_version: self.add_message('collection-deprecated-version', node=node, args=(version, )) if semantic_version.major != 0 and ( semantic_version.minor != 0 or semantic_version.patch != 0): self.add_message('removal-version-must-be-major', node=node, args=(version, )) except ValueError: self.add_message('collection-invalid-deprecated-version', node=node, args=(version, ))
def removal_version(value, is_assible): """Validate a removal version string.""" msg = ('Removal version must be a string' if is_assible else 'Removal version must be a semantic version (https://semver.org/)') if not isinstance(value, string_types): raise Invalid(msg) try: if is_assible: version = StrictVersion() version.parse(value) 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, )) except ValueError: raise Invalid(msg) return value
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 == 'assible.builtin': try: parsed_version = StrictVersion() parsed_version.parse(version) except ValueError as exc: raise _add_assible_error_code( Invalid('%s (%r) is not a valid assible-base 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_assible_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_assible_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
def test_from_loose_version(value, expected): assert SemanticVersion.from_loose_version(value) == expected
def test_comparison_with_string(): assert SemanticVersion('1.0.0') > '0.1.0'
def test_prerelease(value, expected): assert SemanticVersion(value).is_prerelease is expected
def test_stable(value, expected): assert SemanticVersion(value).is_stable is expected
def test_valid(value): SemanticVersion(value)
def test_ge(left, right, expected): assert (SemanticVersion(left) >= SemanticVersion(right)) is expected
def test_lt(left, right, expected): assert (SemanticVersion(left) < SemanticVersion(right)) is expected
def test_semanticversion_none(): assert SemanticVersion().major is None
('1.0.0', False), ] STABLE = [ ('1.0.0-alpha', False), ('1.0.0-alpha.1', False), ('1.0.0-0.3.7', False), ('1.0.0-x.7.z.92', False), ('0.1.2', False), ('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