def intrusively_determine_lib_origin_version(localdir=None): """ Intrusively determine the origin code's source URL if there is access to the Unikraft library directory. Args: localdir: The local directory to read from. Returns origin url. """ if localdir is None: raise ValueError("expected localdir") makefile_uk = os.path.join(localdir, MAKEFILE_UK) if os.path.exists(makefile_uk) is False: raise CannotReadMakefilefile(makefile_uk) makefile_vars = make_list_vars(makefile_uk)['makefile'] for var in makefile_vars: if var.endswith(UNIKRAFT_LIB_MAKEFILE_VERSION_EXT): return makefile_vars[var] return None
def bump(ctx, self, version=None, fast_forward=False, force_version=False): """ Change the Unikraft library's source origin version. Usually this involves updating the LIBNAME_VERSION variable in the Makefile.uk file. Args: version: The version to set. If None, the latest version will be set. fast_forward: If True, choose the latest version. force_version: Whatever the specified version is, use it. Raises: NonCompatibleUnikraftLibrary: Provided path is not a Unikraft library. UnknownLibraryOriginVersion: The provided version does not match known versions from the origin. BumpLibraryDowngrade: Attempting to downgrade a library. NoRemoteVersionsAvailable: No remote versions to select from. CannotDetermineRemoteVersion: Unable to determine which version to upgrade to. UnknownLibraryProvider: Undetermined origin provider. KraftError: Miscellaneous error. """ if self.origin_provider is None: raise UnknownLibraryProvider(self.name) # Retrieve known versions versions = self.origin_provider.probe_remote_versions() semversions = [] if len(versions) == 0: raise NoRemoteVersionsAvailable(self.origin_provider.source) # filter out non-semver versions for known_version in list(versions.keys()): found = SEMVER_PATTERN.search(known_version) if found is not None: semversions.append(known_version) current_version = self.origin_version if version is None: # Pick the highest listed verson if ctx.obj.assume_yes: # There are no semversions if len(semversions) == 0: raise CannotDetermineRemoteVersion(self.localdir) current_not_semver = False try: semver.VersionInfo.parse(current_version) except ValueError as e: logger.warn(e) current_not_semver = True # Remove non-semvers latest_version = None _semversions = semversions semversions = list() for checkv in _semversions: try: semver.VersionInfo.parse(checkv) semversions.append(checkv) except ValueError: continue latest_version = sorted(semversions, reverse=True)[0] # Pick the latest version if fast_forward or current_not_semver: version = latest_version # Check if we're already at the latest version elif semver.compare(current_version, latest_version) == 0: version = latest_version # Find the next version else: semversions = sorted(semversions) for i in range(len(semversions)): try: comparison = semver.compare( semversions[i], current_version) except ValueError as e: logger.warn(e) continue if comparison == 0: # We should have never made it this far, but because we # did, we're at the latest version. if i + 1 == len(semversions): version = latest_version break # Select the next version else: version = semversions[i + 1] break # Prompt user for a version else: version = read_user_choice( 'version', sorted(list(versions.keys()), reverse=True)) if version not in versions.keys(): if ctx.obj.assume_yes: logger.warn("Provided version '%s' not known in: {%s}" % (version, ', '.join(versions.keys()))) else: raise UnknownLibraryOriginVersion(version, versions.keys()) if VSEMVER_PATTERN.search(version): version = version[1:] # Are we dealing with a semver pattern? try: if semver.compare(current_version, version) == 0: logger.info("Library already latest version: %s" % version) return version if semver.compare(current_version, version) > 0: if force_version: logger.warn("Downgrading library from %s to %s..." % (current_version, version)) else: raise BumpLibraryDowngrade(current_version, version) except ValueError: if current_version == version: logger.info("Library already at version: %s" % version) return version # Actually perform the bump makefile_uk = os.path.join(self.localdir, MAKEFILE_UK) logger.debug("Reading %s..." % makefile_uk) makefile_vars = make_list_vars(makefile_uk)['makefile'] version_var = None for var in makefile_vars: if var.endswith(UNIKRAFT_LIB_MAKEFILE_VERSION_EXT): version_var = var break logger.info('Upgrading library from %s to %s...' % (current_version, version)) for line in fileinput.input(makefile_uk, inplace=1): if line.startswith(version_var) and current_version in line: print('%s = %s' % (version_var, version)) else: print(line, end='') return version