def get_image_tags(image, prefix='v'): """Retrieve tags from dockerhub of an image. :param image: image name, organisation/repository. :param prefix: prefix by which to filter images. :returns: sorted list of tags, newest first, ordered by semver. """ tags_data = get_image_meta(image) tags = list() for t in tags_data: name = t['name'] if prefix is not None: if name.startswith(prefix): name = name[len(prefix):] else: continue try: semver.parse(name) except ValueError: continue else: tags.append(name) ordered_tags = sorted(tags, reverse=True, key=functools.cmp_to_key(semver.compare)) if prefix is not None: ordered_tags = ['{}{}'.format(prefix, x) for x in ordered_tags] return ordered_tags
def get_template_data(self): """Return a dictionary with add-on information.""" data = {} if not self.current_version: return data data["name"] = self.name data["channel"] = self.channel data["description"] = self.description data["url"] = self.url data["repo"] = self.addon_repository.html_url data["archs"] = self.archs data["slug"] = self.slug data["target"] = self.repository_target data["image"] = self.image data["images"] = {} for arch in self.archs: data["images"][arch] = self.image.replace("{arch}", arch) try: semver.parse(self.current_version) data["version"] = "v%s" % self.current_version except ValueError: data["version"] = self.current_version data["commit"] = self.current_commit.sha try: data["date"] = self.current_release.created_at except AttributeError: data["date"] = self.current_commit.last_modified return data
def __init__(self, sha, current_version): if not sha: raise exceptions.InvalidArgumentsException('sha cannot be empty') if not current_version: raise exceptions.InvalidArgumentsException( 'current_version cannot be empty') try: semver.parse(current_version) except (TypeError, ValueError): raise exceptions.InvalidArgumentsException( 'Version is not a legal semantic ' 'version string') self._current_version = current_version self._sha = sha self._logger = logger.Logger(__name__) self._log_ctx = { 'sha': self.sha, 'current_version': self._current_version } self.features = set() self.bugs = set() self.issues = set() self.commits = set()
def _is_release_tag_valid_c(release_tag): try: semver.parse(release_tag) except Exception: return False else: return True
def convert(self, value, param, ctx): if isinstance(value, VersionSearchFilter): return value if isinstance(value, str): m = re.match(_version_search_pattern, value) if m is not None and len(m.groups()) == 2: version_search = VersionSearchFilter(name=self.key) version_search.comp = m.group(1) version_search.vers = m.group(2) # default to == if no comparator was provided if not version_search.comp: version_search.comp = "==" if version_search.comp not in [ ">", "<", ">=", "<=", "=", "==" ]: self.fail( "Failed to parse verison filter: %s is not a valid comparitor" % version_search.comp) try: semver.parse(version_search.vers) except ValueError: self.fail("Failed to parse version info: %s" % version_search.vers) return version_search self.fail("Failed to parse version filter %s" % value)
def rm(version): """ Remove a version """ semver.parse(version) if not os.path.exists(STORAGE + '/' + version): print(':: v%s is not installed' % version) return print(':: deleting binary...') shutil.rmtree(STORAGE + '/' + version) config = utils.get_shell_config() content = [] with codecs.open(config, 'r', 'utf-8') as f: content = f.read().split('\n') for i, line in enumerate(content): if STORAGE + '/' + version in line: print(':: cleaning up %s' % config) del content[i] with codecs.open(config, 'w', 'utf-8') as f: f.write('\n'.join(content))
def set_type(self, schema_version, schema_type, schema=None, schema_object=None): """ Used primarily after MLObject instantiation to set the schema_version and schema_type. Does verification of both fields and then loads a stub object with all fields set to 'None' except schema_version and schema_type.""" try: SemVer.parse(schema_version) self.__schema_version = schema_version except ValueError: raise ValueError( f"'{schema_version}' is not a valid semantic version.") except TypeError: raise ValueError( f"'{schema_version}' is not a valid semantic version.") self.__schema_type = check_and_return_schema_type_by_string( schema_type) self.__schema = schema self.__schema_object = schema_object self.create_stub_object() self.schema_version = self.get_schema_version() self.schema_type = self.get_schema_type().name.lower()
def validate_semver(field, value, error): """Validate semver string""" try: semver.parse(value) except ValueError: error(field, 'Must be a valid semver string')
def version(): """ Returns the version of BTW. This value is computed once and then cached. """ global _cached_version # pylint: disable-msg=global-statement if _cached_version is not None: return _cached_version # We have to be running from a git tree. unclean = subprocess.check_output(["git", "status", "--porcelain"]) if not (settings.DEBUG or settings.BTW_TESTING) and unclean: raise Exception("running with unclean tree while DEBUG is false") describe = subprocess.check_output(["git", "describe", "--match", "v*"]).strip() if unclean: describe += "-unclean" sep = describe.find("-") semver.parse(describe[1:len(describe) if sep == -1 else sep]) _cached_version = describe return describe
def revisions(snap, version_filter_track, arch="amd64", exclude_pre=False): """Get revisions of snap snap: name of snap version_filter: snap version to filter on """ re_comp = re.compile("[ \t+]{2,}") revision_list = sh.snapcraft.revisions(snap, "--arch", arch, _err_to_out=True) revision_list = revision_list.stdout.decode().splitlines()[1:] revisions_to_process = [] for line in revision_list: line = re_comp.split(line) try: semver.parse(line[-2]) revisions_to_process.append(line) except ValueError: print(f"Skipping: {line}") continue revision_list = [ line for line in revisions_to_process if exclude_pre and semver.parse(line[-2])["prerelease"] is None and any(version_filter_track in item for item in line) ] rev = max_rev(revision_list, version_filter_track.split("/")[0]) rev_map = [line for line in revision_list if rev == int(line[0])] if rev_map: return rev_map[0] return []
def get_version_number(): """ Prompts the user to enter the version number being released. Outputs the current version number. """ context = {} context['current_version'] = apptemplate.VERSION puts('Current version: %(current_version)s' % context) new_version = None input = None while not new_version: if input is not None: puts('Invalid version number') input = raw_input('Enter the new version number: ') print input try: semver.parse(input) except ValueError: pass else: new_version = input return new_version
def get_image_tags(image, prefix='v', proxies=None): """Retrieve tags from dockerhub of an image. :param image: image name, organisation/repository. :param prefix: prefix by which to filter images. :returns: sorted list of tags, newest first, ordered by semver. Or the list [None] if an error occurs fetching tag meta information. """ try: tags_data = _get_image_meta(image, proxies=proxies) except Exception as e: logger = labslauncher.get_named_logger("ImageMeta") logger.warning(e) logger.warning("Failed to fetch image information from dockerhub.") return [None] tags = list() for t in tags_data: name = t['name'] if name[0] != prefix: continue try: semver.parse(name[1:]) except ValueError: continue else: tags.append(name[1:]) ordered_tags = [ '{}{}'.format(prefix, x) for x in sorted( tags, reverse=True, key=functools.cmp_to_key(semver.compare)) ] return ordered_tags
def normalize_version(vers_string): """Make a semantic version out of a less strict version number , e.g. 0.5 to 0.5.0.""" try: return semver.parse(vers_string) except ValueError: return semver.parse(".".join(distutils.version.StrictVersion(vers_string).version))
def validate(self): semver.parse(self.release_version) existing_dir(self.repo_dir) # check whether a release with the given version exists try: self.github_helper.repository.release_from_tag(self.release_version) except NotFoundError: raise RuntimeError(f'No release with tag {self.release_version} found')
def build_pr_name(jina_core_version, module, module_version): pr_name = f'chore: testing/building {module} ({module_version}) on new jina core: {jina_core_version}' if COMPARISON_LEVEL == 'major': version = semver.parse(jina_core_version) pr_name = f'chore: testing/building {module} ({module_version}) on new jina core: {version["major"]}.' elif COMPARISON_LEVEL == 'minor': version = semver.parse(jina_core_version) pr_name = f'chore: testing/building {module} ({module_version}) on new jina core: {version["major"]}.{version["minor"]}.' return pr_name
def _sync_upstream(snap_list, starting_ver, force, patches, dry_run): """ Syncs the upstream k8s release tags with our snap branches Usage: snaps-source.py sync-upstream --snap-list includes/k8s-snap-list.inc """ env = os.environ.copy() supported_releases = [] upstream_releases = git.remote_tags("https://github.com/kubernetes/kubernetes") for rel in upstream_releases: _fmt_rel = rel.lstrip("v") try: semver.parse(_fmt_rel) if semver.compare(_fmt_rel, starting_ver) >= 0: supported_releases.append(rel) except ValueError as error: click.echo(f"Skipping invalid {_fmt_rel}: {error}") snaps = yaml.safe_load(Path(snap_list).read_text(encoding="utf8")) for snap in snaps: click.echo(f"Checking: git+ssh://[email protected]/snap-{snap}") git_repo = f"git+ssh://[email protected]/snap-{snap}" snap_releases = git.remote_branches(git_repo) if not set(supported_releases).issubset(set(snap_releases)): snap_releases = list(set(supported_releases).difference(set(snap_releases))) snap_releases.sort() for snap_rel in snap_releases: click.echo(f"Creating branch for {snap}-{snap_rel}") _create_branch(git_repo, "master", snap_rel, dry_run=False, force=force, patches=patches) _fmt_version = semver.parse(snap_rel.lstrip("v")) _fmt_version_str = f'{_fmt_version["major"]}.{_fmt_version["minor"]}' tracks_to_publish = [] if _fmt_version['prerelease']: click.echo(f"This is a pre-release, skipping for now") continue tracks_to_publish = [f"{_fmt_version_str}/edge"] else: tracks_to_publish = [ f"{_fmt_version_str}/edge", f"{_fmt_version_str}/candidate", f"{_fmt_version_str}/beta"] click.echo(f"Generating recipe for {snap}-{_fmt_version_str}") if not dry_run: _create_snap_recipe( snap=snap, version=_fmt_version_str, track=tracks_to_publish, owner="k8s-jenkaas-admins", tag=snap_rel, repo=git_repo, dry_run=False, snap_recipe_email=os.environ.get("K8STEAMCI_USR"), snap_recipe_password=os.environ.get("K8STEAMCI_PSW"), )
def main(): """ Main method. This method holds what you want to execute when the script is run on command line. """ args = get_arguments() setup_logging(args) version_path = os.path.abspath(os.path.join( os.path.dirname(__file__), '..', '..', '.VERSION' )) try: version_text = open(version_path).read().strip() except Exception: print ('Could not open or read the .VERSION file') sys.exit(1) try: semver.parse(version_text) except ValueError: print ('The .VERSION file contains an invalid version: "{0}"'.format( version_text )) sys.exit(1) new_version = version_text if args.version: try: if semver.parse(args.version): new_version = args.version except Exception: print ('Could not parse "{0}" as a version'.format( args.version )) sys.exit(1) elif args.bump_major: new_version = semver.bump_major(version_text) elif args.bump_minor: new_version = semver.bump_minor(version_text) elif args.bump_patch: new_version = semver.bump_patch(version_text) try: with open(version_path, 'w') as version_file: version_file.write(new_version) except Exception: print ('Could not write the .VERSION file') sys.exit(1) print new_version
def _check_version(self): version = self._get_key('version') if not isinstance(version, six.string_types): self.log.warning('Version value in metadata is not a string') return try: semver.parse(version) except ValueError: self.log.warning( 'Version "{0}" in metadata does not match the expected ' 'version format'.format(version))
def __extractValidTags(self, data): valid_tags = [] for tag in data["tags"]: try: semver.parse(tag) except Exception: pass else: valid_tags.append(tag) logger.debug(f"Valid tags are {valid_tags}") return valid_tags
def __call__(self, value): try: semver.parse(value) except ValueError: raise ValidationError( self.message, code=self.code, params={ 'value': value, } )
def __validate__(keycloak_version, keycloak_format): if keycloak_version is None: raise ValueError('keycloak_version is required') if keycloak_format is None: raise ValueError('keycloak_format is required') if str(keycloak_format) != 'zip' and str(keycloak_format) != 'tar.gz': raise ValueError( 'keycloak_format is invalid valid. Should be one of .zip or .tar.gz' ) parse(keycloak_version) #validate version is formatted as semver.
def is_valid_semver_version(version_string): version_string = version_string[0:version_string.find('-')] version_string = version_string.replace('-', '.0+') print("trying: " + version_string) try: semver.parse(version_string) return True except ValueError: return False
def compare(version_a, version_b): """Compares 2 sem versions""" version_a = normalize(version_a) version_b = normalize(version_b) try: semver.parse(version_a) semver.parse(version_b) except: log.debug(f"Unable to parse {version_a} and/or {version_b}") return semver.compare(version_a, version_b)
def use(version): """ Switch to a different version """ semver.parse(version) if not os.path.exists(STORAGE + '/' + version): print(':: v%s is not installed.' % version) sys.exit(1) utils.append_to_path(version)
def test_output_should_contain_version(self): from ssmash import __version__ as package_version # Exercise runner = CliRunner() result = runner.invoke(cli.run_ssmash) # Verify cfn = yaml.safe_load(result.stdout) ssmash_version = cfn["Metadata"]["ssmash"]["version"] assert ssmash_version == package_version semver.parse(ssmash_version)
def _compare_to_version(self, *args, **kwargs): try: status = args[1] except IndexError: logger.error('msync._compare_to_version() called '\ 'without enough arguments!') return "Not enough arguments!" # Now the fun begins working_prompt = 'Fetching and comparing against all our modules. '\ 'This takes a second...' self.reply(self.message, str(working_prompt), self.opts) all_modules = self._get_all_modules() matching_modules = [] if status == 'current': current_msync = self._get_current_msync() for module in all_modules: # Use a requests Session to take advantage of connection pooling s = requests.Session() kwargs = {'module': module, 'session': s} modver = self._get_single_version(**kwargs) # Sometimes we get 404s. ¯\_(ツ)_/¯ if modver != False: if semver.compare(modver, current_msync) == 0: # semvers matched matching_modules.append(module) elif status == 'olderthan' or status == 'newerthan': try: compare_version = args[2] except IndexError: logger.error("msync._compare_to_version() called with 'olderthan' or "\ "'newerthan' but no version provide to compare against...") return "Not enough arguments!" compare = {'olderthan': -1, 'newerthan': 1} try: semver.parse(compare_version) except ValueError: return "Invalid semver" for module in all_modules: modver = self._get_single_version( '', '', module) # Workaround until **kwargs is worked out if modver != False: comparison = semver.compare(modver, compare_version) if comparison == compare[status] or comparison == 0: matching_modules.append(module) else: return 'How did you get here?' report = self._generate_report(matching_modules, *args) report_url = self._gist(report) return report_url
def validate(self): semver.parse(self.release_version) # if a tag with the given release version exists, we cannot create another release # pointing to it if self.github_helper.tag_exists(tag_name=self.release_version): raise RuntimeError( f"Cannot create tag '{self.release_version}' for release: Tag already exists" ) if self.component_descriptor_file_path: existing_file(self.component_descriptor_file_path) with open(self.component_descriptor_file_path) as f: # TODO: Proper validation not_empty(f.read().strip())
def __init__(self, pact, result, broker_pact=None): self.result = result self.pact = pact self.provider = pact['provider']['name'] self.consumer = pact['consumer']['name'] self.metadata = pact['metadata'] if 'pactSpecification' in self.metadata: # the Ruby implementation generates non-compliant metadata, handle that :-( self.version = semver.parse(self.metadata['pactSpecification']['version']) else: self.version = semver.parse(self.metadata['pact-specification']['version']) self.interactions = [Interaction(self, interaction, self.result) for interaction in pact['interactions']] self.broker_pact = broker_pact
def _parse_image(name, current_image, new_image): if not new_image[0] == name: return current_image try: semver.parse(new_image[1]) except ValueError as e: return current_image if not current_image or semver.match(new_image[1], '>=' + current_image[1]): return [ new_image[0], new_image[1] ] return current_image
def is_dir_name_semver(self, dir_name): """ Checks if the dir_name is a semver or not. :param dir_name: the name of the directory :return: True if the dir_name is a semver, False otherwise """ try: semver.parse(dir_name) except ValueError: logging.warning( 'Ignoring directory "%s" as it is not in semver format.') return False return True
def set_version(self, value, branch=None): """ Sets the version of setup.py file to the specified version number. Note, This will actually create a commit on top of the branch you specify. Args: value (str): The semantic version string. branch (:str, optional): The branch to push to commit to. Defaults to the default repository branch. Returns: pyci.api.model.Bump: The commit that was created. Raises: pyci.api.exceptions.TargetVersionEqualsCurrentVersionException: Current version in setup.py is equal to the given value. """ if not value: raise exceptions.InvalidArgumentsException('value cannot be empty') try: semver.parse(value) except (TypeError, ValueError): raise exceptions.InvalidArgumentsException( 'value is not a legal semantic version') branch = branch or self.default_branch_name last_branch_commit = self._get_or_create_commit(sha=branch) current_version = last_branch_commit.setup_py_version self._debug('Generating setup.py file contents...', next_version=value) setup_py = utils.generate_setup_py(last_branch_commit.setup_py, value) self._debug('Generated setup.py file contents.') commit_message = BUMP_VERSION_COMMIT_MESSAGE_FORMAT.format(value) if current_version == value: raise exceptions.TargetVersionEqualsCurrentVersionException( version=current_version) bump_commit = self.commit(path='setup.py', contents=setup_py, message=commit_message) return model.Bump(impl=bump_commit.impl, prev_version=current_version, next_version=value, sha=bump_commit.sha)
def main(): p = argparse.ArgumentParser() p.add_argument("input_file") p.add_argument("output_file") args = p.parse_args() actual_data = [] sim_data = [] ult_data = [] pat = re.compile("^A(?P<actual>.*),S(?P<sim>.*),S(?P<ult>.*)$", re.M) with open(args.input_file, 'r') as fin: for line in fin: m = re.match(pat, line) actual = m.group("actual") sim = m.group("sim") ult = m.group("ult") # Parse into decimal m_actual = semver.parse(actual) m_sim = semver.parse(sim) m_ult = semver.parse(ult) actual_data.append(m_actual) sim_data.append(m_sim) ult_data.append(m_ult) max_minor = {} for v in (sim_data + actual_data + ult_data): old_max = max_minor.get(v[0], 0) max_minor[v[0]] = max(v[1],old_max) with open(args.output_file, 'w') as fo: for i in range(len(sim_data)): simV = sim_data[i] ultV = ult_data[i] actV = actual_data[i] simMinor = int(100 * float(simV[1])/(max_minor[simV[0]] + 1)) ultMinor = int(100 * float(ultV[1])/(max_minor[ultV[0]] + 1)) actMinor = int(100 * float(actV[1])/(max_minor[actV[0]] + 1)) f_actual = float("%02d.%02d" % (actV[0], actMinor)) f_sim = float("%02d.%02d" % (simV[0], simMinor)) f_ult = float("%02d.%02d" % (ultV[0], ultMinor)) print "SimVersion = %s, f_sim = %s, ActVersion = %s, f_actual = %s" % (simV, f_sim, actV, f_actual) fo.write("{} {} {}\n".format(f_actual, f_sim, f_ult))
def validate_versions(content_versions): valid_versions = [] invalid_versions = [] for version in content_versions: try: semver.parse(version) valid_versions.append(version) except ValueError as e: log.exception(e) log.warning('The version string "%s" is not valid, skipping: %s', version, e) invalid_versions.append(version) continue return (valid_versions, invalid_versions)
def test_should_parse_version(self): self.assertEqual( parse("1.2.3-alpha.1.2+build.11.e0f985a"), {'major': 1, 'minor': 2, 'patch': 3, 'prerelease': 'alpha.1.2', 'build': 'build.11.e0f985a'}) self.assertEqual( parse("1.2.3-alpha-1+build.11.e0f985a"), {'major': 1, 'minor': 2, 'patch': 3, 'prerelease': 'alpha-1', 'build': 'build.11.e0f985a'})
def _parse_str(self, version): """ Parse version as string and initialize self with data from version :param version: :return: """ version = semver.parse(version) self._parse_dict(version)
def _list_source_contents_from_multidir(cls, source): for pth in os.listdir(source): single_path = os.path.join(source, pth) if pth.endswith('.yaml'): pth = pth[:-5] yield RES_TYPE.Composer, pth, single_path elif os.path.exists(os.path.join(single_path, 'meta.yaml')): try: semver.parse(pth) except ValueError: name = pth else: # if it was semver then single_path may look like # /a/b/name/version # and source may look like /a/b/name # we can extract name from this path then name = os.path.split(source)[-1] yield RES_TYPE.Normal, name, single_path else: maybe_cr = os.path.join(single_path, "{}.yaml".format( os.path.split(source)[-1])) if os.path.exists(maybe_cr): name = os.path.split(source)[-1] yield RES_TYPE.Composer, name, maybe_cr continue if not os.path.isdir(single_path): continue for single in os.listdir(single_path): try: semver.parse(single) except ValueError: fp = os.path.join(single_path, single) raise RepositoryException( "Unexpected repository content " "structure: {} ""Expected directory " "with version number".format(single_path)) else: fp = os.path.join(single_path, single) if os.path.exists(os.path.join(fp, 'meta.yaml')): yield RES_TYPE.Normal, pth, fp elif os.path.exists( os.path.join(fp, '{}.yaml'.format(pth))): cr = os.path.join(fp, '{}.yaml'.format(pth)) yield RES_TYPE.Composer, pth, cr
def test_should_parse_version(): result = parse("1.2.3-alpha.1.2+build.11.e0f985a") assert result == { 'major': 1, 'minor': 2, 'patch': 3, 'prerelease': 'alpha.1.2', 'build': 'build.11.e0f985a', } result = parse("1.2.3-alpha-1+build.11.e0f985a") assert result == { 'major': 1, 'minor': 2, 'patch': 3, 'prerelease': 'alpha-1', 'build': 'build.11.e0f985a', }
def set(self, field, value): """ Set any field of semver to `value` :rtype : Version :param field:type of field (one of Version.VALID_FIELDS) :param value: :return: :raise ValueError: """ if field not in self.VALID_FIELDS: raise ValueError("Incorrect value of \"type\"") version = Version(self) setattr(version, field, value) semver.parse(str(version)) return version
def match(version, spec): if version[0] == 'v': version = version[1:] if spec[0] == '^': base = spec[1:] parsed_base = semver.parse(base) if parsed_base['major'] > 0: top = semver.bump_major(base) elif parsed_base['minor'] > 0: top = semver.bump_minor(base) else: top = semver.bump_patch(base) return semver.match(version, ">="+base) and semver.match(version, "<="+top) else: try: return semver.match(version, spec) except ValueError: # this happens when the spec isn't an expression, in which case we need an exact match return semver.parse(version) == semver.parse(spec)
def semver_bumper(old_version, part="patch"): """Bump the version with ``semver`` module. :arg str part: Specify which part should be bumped. Possible values are ``"patch"``, ``"minor"``, or ``"major"``. If ``part`` is a valid version number, it would bump the version number to ``part``. :rtype: str :return: new version number. """ import semver bump = getattr(semver, "bump_" + part, None) if callable(bump): new_version = bump(old_version) else: new_version = part semver.parse(new_version) return new_version
def read(self): """ Read version from version file :rtype : Version :return: """ with self._path.open(mode='r') as fh: version = fh.read().strip() version = semver.parse(version) return Version(version)
def tag_semver(self): """ Job tag, parsed as semver (or None if no match). Allows a 'v' prefix """ if self.tag is None: return None try: return semver.parse(self._tag_without_v) except ValueError: pass
def test_should_parse_zero_prerelease(): result = parse("1.2.3-rc.0+build.0") assert result == { 'major': 1, 'minor': 2, 'patch': 3, 'prerelease': 'rc.0', 'build': 'build.0', } result = parse("1.2.3-rc.0.0+build.0") assert result == { 'major': 1, 'minor': 2, 'patch': 3, 'prerelease': 'rc.0.0', 'build': 'build.0', }
def test_get_decision_trees_bulk_specific_version(self): """get_decision_trees_bulk should succeed when given a specific version. It should give a proper JSON response with a list containing a dict with `id` field being string and 'tree' field being a dict with the field 'version''major' being the version given as a parameter. """ payload = [{"id": self.agent_id1, "timestamp": valid_data.VALID_LAST_TIMESTAMP}, {"id": self.agent_id2, "timestamp": valid_data.VALID_LAST_TIMESTAMP}] version = 1 decision_trees = self.client.get_decision_trees_bulk(payload, version) self.assertNotEqual(decision_trees[0].get("tree").get("_version"), None) tree_version = semver.parse(decision_trees[0].get("tree").get("_version")) self.assertEqual(tree_version["major"], version) self.assertNotEqual(decision_trees[1].get("tree").get("_version"), None) tree_version = semver.parse(decision_trees[1].get("tree").get("_version")) self.assertEqual(tree_version["major"], version) self.addCleanup(self.clean_up_agents, [self.agent_id1, self.agent_id2])
def test_should_raise_value_error_for_zero_prefixed_versions(): with pytest.raises(ValueError): parse("01.2.3") with pytest.raises(ValueError): parse("1.02.3") with pytest.raises(ValueError): parse("1.2.03")
def test_get_decision_tree_with_specific_version(): version = 1 decision_tree = CLIENT.get_decision_tree( AGENT_ID, valid_data.VALID_TIMESTAMP, version) assert_is_instance(decision_tree, dict) assert_not_equal(decision_tree.get("_version"), None) tree_version = semver.parse(decision_tree.get("_version")) assert_equal(tree_version["major"], version) assert_not_equal(decision_tree.get("configuration"), None) assert_not_equal(decision_tree.get("trees"), None)
def _list_source_contents(cls, source): if source.endswith('.yaml'): # single CR pth = os.path.split(source)[-1][:-5] return ((RES_TYPE.Composer, pth, source), ) elif os.path.isdir(source): meta_path = os.path.join(source, 'meta.yaml') if os.path.exists(meta_path): # single normal pth = os.path.split(source)[-1] try: semver.parse(pth) except ValueError: name = pth else: # if it was semver then single_path may look like # /a/b/name/version # and source may look like /a/b/name # we can extract name from this path then name = source.split(os.path.sep)[-2] return ((RES_TYPE.Normal, name, source), ) return tuple(cls._list_source_contents_from_multidir(source))
def get_latest_release(self): response = requests.get(self.releases_url) releases = response.json() latest_version = None for r in releases: if r["prerelease"] and not self.include_prereleases: continue version = r["tag_name"] # some tag was create with 'v' letter, we should remove it (ex. v0.0.3-alpha -> 0.0.3-alpha) if version[0] == "v": version = version[1:] # latest version of semver can't parse 0 per-release version (ex: 1.0.0-rc.0) try: semver.parse(version) except ValueError: continue if latest_version is None or semver.compare(version, latest_version) > 0: latest_version = version return latest_version
def set(self, field, value): """ Set any field of semver to `value` :rtype : Version :param field:type of field (one of Version.VALID_FIELDS) :param value: :return: :raise ValueError: """ if field not in self.VALID_FIELDS: raise ValueError("Invalid field type: %s" % field) version = Version(self) setattr(version, field, value) # validation try: semver.parse(str(version)) except ValueError as exc: raise InvalidVersionError("Invalid value for field %s: %s" % (field, value)) from exc return version
def get_tags(image): php_version = semver.parse(image[0]) php_versions = [] if php_version["major"] == 7: if php_version["minor"] == 0: php_versions.append("7") else: php_versions.append(str(php_version["major"])) php_versions.extend([minorize(image[0]), image[0]]) for tag in php_versions: yield matrix_join((tag,) + image[1:], "-")
def test_semantic_version(self): """ociVersion (string, required) MUST be in SemVer v2.0.0 format. The spec wording in the docstring summary is from [1,2]. v0.5.0 used 'must' instead of 'MUST', but that was accidental [3]. This test is not restricted to known versions, because we expect a semantic-versioned field to extend to all spec releases (otherwise what's the point of SemVer?). [1]: https://github.com/opencontainers/runtime-spec/blob/v1.0.0-rc1/config.md#specification-version [2]: https://github.com/opencontainers/runtime-spec/blob/v0.5.0/config.md#specification-version [3]: https://github.com/opencontainers/runtime-spec/pull/409 """ self.assertTrue(isinstance(util.VERSION, str), 'ociVersion is not a string') try: version = semver.parse(version=util.VERSION) except ValueError as error: raise self.failureException(str(error)) from error
def _parse_semver(input): try: semver.parse(input) return input except ValueError as e: try: input = _add_zero_version_component(input) semver.parse(input) return input except ValueError as e: try: input = _add_zero_version_component(input) semver.parse(input) return input except ValueError as e: return None
def select_tag(self, tags): """ Compare the available tags and return the newest tag for the specific version. :param tags: list of available tags :return: the tag to use or None if not tag is compatible """ # Get tags with matching version valid_tags = [] for tag in tags: try: t = semver.parse(tag) if (self.major is not None and t['major'] != self.major) or \ (self.minor is not None and t['minor'] != self.minor) or \ (self.patch is not None and t['patch'] != self.patch): continue valid_tags.append(tag) except ValueError: # ignore tags we cannot parse pass if len(valid_tags) == 0: return None # Now figure out which version is the newest. We may only # use versions meeting the version requirement as specified by # self.major, self.minor, and self.patch, to ensure compatibility see # rules at semver.org best_match = valid_tags[0] for t in valid_tags: if semver.match(best_match, "<" + t): best_match = t return best_match
def version_is_valid(version): """Determines whether a given version meets the semver spec, and if so returns the parsed result. Args: version (str): The version to test Returns: dict: The parsed version (or an empty dict). Examples: >>> bool(version_is_valid('1.0.1')) True >>> bool(version_is_valid('1.0.1')['major']) True >>> bool(version_is_valid('1.0')) False """ try: return semver.parse(version) except (ValueError, TypeError): logger.debug('%s is not a valid version', version) return {}
def flash(self): """ Takes the currently active tab, compiles the Python script therein into a hex file and flashes it all onto the connected device. WARNING: This method is getting more complex due to several edge cases. Ergo, it's a target for refactoring. """ user_defined_microbit_path = None self.python_script = '' logger.info('Preparing to flash script.') # The first thing to do is check the script is valid and of the # expected length. # Grab the Python script. tab = self.view.current_tab if tab is None: # There is no active text editor. Exit. return # Check the script's contents. python_script = tab.text().encode('utf-8') logger.debug('Python script:') logger.debug(python_script) # Check minification status. minify = False if uflash.get_minifier(): minify = self.editor.minify # Attempt and handle minification. if len(python_script) >= uflash._MAX_SIZE: message = _('Unable to flash "{}"').format(tab.label) if minify and can_minify: orginal = len(python_script) script = python_script.decode('utf-8') try: mangled = nudatus.mangle(script).encode('utf-8') except TokenError as e: msg, (line, col) = e.args logger.debug('Minify failed') logger.exception(e) message = _("Problem with script") information = _("{} [{}:{}]").format(msg, line, col) self.view.show_message(message, information, 'Warning') return saved = orginal - len(mangled) percent = saved / orginal * 100 logger.debug('Script minified, {} bytes ({:.2f}%) saved:' .format(saved, percent)) logger.debug(mangled) python_script = mangled if len(python_script) >= 8192: information = _("Our minifier tried but your " "script is too long!") self.view.show_message(message, information, 'Warning') return elif minify and not can_minify: information = _("Your script is too long and the minifier" " isn't available") self.view.show_message(message, information, 'Warning') return else: information = _("Your script is too long!") self.view.show_message(message, information, 'Warning') return # By this point, there's a valid Python script in "python_script". # Assign this to an attribute for later processing in a different # method. self.python_script = python_script # Next step: find the microbit port and serial number. path_to_microbit = uflash.find_microbit() logger.info('Path to micro:bit: {}'.format(path_to_microbit)) port = None serial_number = None try: port, serial_number = self.find_device() logger.info('Serial port: {}'.format(port)) logger.info('Device serial number: {}'.format(serial_number)) except Exception as ex: logger.warning('Unable to make serial connection to micro:bit.') logger.warning(ex) # Determine the location of the BBC micro:bit. If it can't be found # fall back to asking the user to locate it. if path_to_microbit is None: # Ask the user to locate the device. path_to_microbit = self.view.get_microbit_path(HOME_DIRECTORY) user_defined_microbit_path = path_to_microbit logger.debug('User defined path to micro:bit: {}'.format( user_defined_microbit_path)) # Check the path and that it exists simply because the path maybe based # on stale data. if path_to_microbit and os.path.exists(path_to_microbit): force_flash = False # If set to true, fully flash the device. # If there's no port but there's a path_to_microbit, then we're # probably running on Windows with an old device, so force flash. if not port: force_flash = True if not self.python_script.strip(): # If the script is empty, this is a signal to simply force a # flash. logger.info("Python script empty. Forcing flash.") force_flash = True logger.info("Checking target device.") # Get the version of MicroPython on the device. try: version_info = microfs.version() logger.info(version_info) board_info = version_info['version'].split() if (board_info[0] == 'micro:bit' and board_info[1].startswith('v')): # New style versions, so the correct information will be # in the "release" field. try: # Check the release is a correct semantic version. semver.parse(version_info['release']) board_version = version_info['release'] except ValueError: # If it's an invalid semver, set to unknown version to # force flash. board_version = '0.0.1' else: # 0.0.1 indicates an old unknown version. This is just a # valid arbitrary flag for semver comparison a couple of # lines below. board_version = '0.0.1' logger.info('Board MicroPython: {}'.format(board_version)) logger.info( 'Mu MicroPython: {}'.format(uflash.MICROPYTHON_VERSION)) # If there's an older version of MicroPython on the device, # update it with the one packaged with Mu. if semver.compare(board_version, uflash.MICROPYTHON_VERSION) < 0: force_flash = True except Exception: # Could not get version of MicroPython. This means either the # device has a really old version of MicroPython or is running # something else. In any case, flash MicroPython onto the # device. logger.warn('Could not detect version of MicroPython.') force_flash = True # Check use of custom runtime. rt_hex_path = self.editor.microbit_runtime.strip() message = _('Flashing "{}" onto the micro:bit.').format(tab.label) if (rt_hex_path and os.path.exists(rt_hex_path)): message = message + _(" Runtime: {}").format(rt_hex_path) force_flash = True # Using a custom runtime, so flash it. else: rt_hex_path = None self.editor.microbit_runtime = '' # Check for use of user defined path (to save hex onto local # file system. if user_defined_microbit_path: force_flash = True # If we need to flash the device with a clean hex, do so now. if force_flash: logger.info('Flashing new MicroPython runtime onto device') self.editor.show_status_message(message, 10) self.set_buttons(flash=False) if user_defined_microbit_path or not port: # The user has provided a path to a location on the # filesystem. In this case save the combined hex/script # in the specified path_to_microbit. # Or... Mu has a path to a micro:bit but can't establish # a serial connection, so use the combined hex/script # to flash the device. self.flash_thread = DeviceFlasher([path_to_microbit], self.python_script, rt_hex_path) # Reset python_script so Mu doesn't try to copy it as the # main.py file. self.python_script = '' else: # We appear to need to flash a connected micro:bit device, # so just flash the Python hex with no embedded Python # script, since this will be copied over when the # flashing operation has finished. model_serial_number = int(serial_number[:4]) if rt_hex_path: # If the user has specified a bespoke runtime hex file # assume they know what they're doing and hope for the # best. self.flash_thread = DeviceFlasher([path_to_microbit], b'', rt_hex_path) elif model_serial_number in self.valid_serial_numbers: # The connected board has a serial number that # indicates the MicroPython hex bundled with Mu # supports it. In which case, flash it. self.flash_thread = DeviceFlasher([path_to_microbit], b'', None) else: message = _('Unsupported BBC micro:bit.') information = _("Your device is newer than this " "version of Mu. Please update Mu " "to the latest version to support " "this device.\n\n" "https://codewith.mu/") self.view.show_message(message, information) return if sys.platform == 'win32': # Windows blocks on write. self.flash_thread.finished.connect(self.flash_finished) else: if user_defined_microbit_path: # Call the flash_finished immediately the thread # finishes if Mu is writing the hex file to a user # defined location on the local filesystem. self.flash_thread.finished.connect(self.flash_finished) else: # Other platforms don't block, so schedule the finish # call for 10 seconds (approximately how long flashing # the connected device takes). self.flash_timer = QTimer() self.flash_timer.timeout.connect(self.flash_finished) self.flash_timer.setSingleShot(True) self.flash_timer.start(10000) self.flash_thread.on_flash_fail.connect(self.flash_failed) self.flash_thread.start() else: try: self.copy_main() except IOError as ioex: # There was a problem with the serial communication with # the device, so revert to forced flash... "old style". # THIS IS A HACK! :-( logger.warning('Could not copy file to device.') logger.error(ioex) logger.info('Falling back to old-style flashing.') self.flash_thread = DeviceFlasher([path_to_microbit], self.python_script, rt_hex_path) self.python_script = '' if sys.platform == 'win32': # Windows blocks on write. self.flash_thread.finished.connect(self.flash_finished) else: self.flash_timer = QTimer() self.flash_timer.timeout.connect(self.flash_finished) self.flash_timer.setSingleShot(True) self.flash_timer.start(10000) self.flash_thread.on_flash_fail.connect(self.flash_failed) self.flash_thread.start() except Exception as ex: self.flash_failed(ex) else: # Try to be helpful... essentially there is nothing Mu can do but # prompt for patience while the device is mounted and/or do the # classic "have you tried switching it off and on again?" trick. # This one's for James at the Raspberry Pi Foundation. ;-) message = _('Could not find an attached BBC micro:bit.') information = _("Please ensure you leave enough time for the BBC" " micro:bit to be attached and configured" " correctly by your computer. This may take" " several seconds." " Alternatively, try removing and re-attaching the" " device or saving your work and restarting Mu if" " the device remains unfound.") self.view.show_message(message, information)
def _version_strip_patch(value): return "{major}.{minor}".format(**semver.parse(value))
def __init__(self, name=None, version=None, console=None): self.name = name if version: semver.parse(version) # raises ValueError when invalid self.version = version self.console = console
def resolve(self, ctx, path, use_checkout): """ Fetches the dependency if necessary. :param ctx: A waf ConfigurationContext :param path: The path where the dependency should be located :param use_checkout: If not None the given checkout will be used """ path = os.path.abspath(os.path.expanduser(path)) repo_url = self.repository_url(ctx, git_protocol_handler) # Use the first 6 characters of the SHA1 hash of the repository url # to uniquely identify the repository repo_hash = hashlib.sha1(repo_url.encode('utf-8')).hexdigest()[:6] # The folder for storing different versions of this repository repo_folder = os.path.join(path, self.name + '-' + repo_hash) if not os.path.exists(repo_folder): ctx.to_log( "Creating new repository folder: {}".format(repo_folder)) os.makedirs(repo_folder) # Do we have the master folder? master_path = os.path.join(repo_folder, 'master') # If the master folder does not exist, do a git clone first if not os.path.isdir(master_path): ctx.git_clone(repo_url, master_path, cwd=repo_folder) else: # We only want to pull if we haven't just cloned. This avoids # having to type in the username and password twice when using # https as a git protocol. try: # git pull will fail if the repository is unavailable # This is not a problem if we have already downloaded # the required version for this dependency ctx.git_pull(cwd=master_path) except Exception as e: ctx.to_log('Exception when executing git pull:') ctx.to_log(e) # If the project contains submodules we also get those ctx.git_get_submodules(master_path) # Do we need a specific checkout? (master, commit or dev branch) if use_checkout: checkout_path = os.path.join(repo_folder, use_checkout) # The master is already up-to-date, but the other checkouts # should be cloned to separate directories if use_checkout != 'master': # If the checkout folder does not exist, # then clone from the git repository if not os.path.isdir(checkout_path): ctx.git_clone(repo_url, checkout_path, cwd=repo_folder) ctx.git_checkout(use_checkout, cwd=checkout_path) else: # If the checkout folder exists, we may need to update it ctx.git_pull(cwd=checkout_path) # If the project contains submodules we also get those ctx.git_get_submodules(checkout_path) # The major version of the latest tag should not be larger than # the specified major version tags = ctx.git_tags(cwd=checkout_path) for tag in tags: try: if semver.parse(tag)['major'] > self.major: ctx.fatal("Tag {} in checkout {} is newer than the " "required major version {}".format( tag, use_checkout, self.major)) except ValueError: # ignore tags we cannot parse pass return checkout_path tags = [] # git tags will fail for standalone dependencies # This is not a problem if the folder is already present # for the required version of this dependency try: tags = ctx.git_tags(cwd=master_path) except Exception as e: ctx.to_log('Exception when executing git tags:') ctx.to_log(e) # As a fallback, use the existing folder names as tags tags = [d for d in os.listdir(repo_folder) if os.path.isdir(os.path.join(repo_folder, d))] ctx.to_log('Using the following fallback tags:') ctx.to_log(tags) if len(tags) == 0: ctx.fatal("No version tags specified for {} - impossible to track " "version".format(self.name)) tag = self.select_tag(tags) if not tag: ctx.fatal("No compatible tags found {} to track major version {} " "of {}".format(tags, self.major, self.name)) # Do we have the newest tag checked out tag_path = os.path.join(repo_folder, tag) if not os.path.isdir(tag_path): ctx.git_local_clone(master_path, tag_path, cwd=repo_folder) ctx.git_checkout(tag, cwd=tag_path) # If the project contains submodules we also get those ctx.git_get_submodules(tag_path) return tag_path
gh = github3.login(sys.argv[1], token=sys.argv[2].strip()) repos = [] pinax = gh.organization("pinax") for repo in pinax.repositories(): if repo.name in app_repos: tags = list(repo.tags()) versions = {} for tag in tags: if tag.name.startswith("v"): tag_name = tag.name[1:] else: tag_name = tag.name try: semver.parse(tag_name) except ValueError: continue versions[tag_name] = tag if len(versions) == 0: continue version = sorted(versions.keys(), reverse=True, key=functools.cmp_to_key(semver.compare))[0] # noqa tagged_sha = versions[version].commit["sha"] tagged_commit = repo.commit(tagged_sha) since = [ commit for commit in list(repo.commits(sha="master", since=tagged_commit.commit.author["date"])) # noqa if commit.sha != tagged_sha ] triaged_latest = sum([m.open_issues for m in repo.milestones() if m.title == latest]) # noqa triaged_post = sum([m.open_issues for m in repo.milestones() if m.title == latest_post]) # noqa
import os import logging _version_path = os.path.join(os.path.dirname(__file__), 'version.txt') VERSION = open(_version_path).read().rstrip() #rstrip() removes newlines try: import semver except ImportError: pass else: VERSION_INFO = semver.parse(VERSION)