diff --git a/rust2rpm/__main__.py b/rust2rpm/__main__.py index 60ff217..fea8717 100644 --- a/rust2rpm/__main__.py +++ b/rust2rpm/__main__.py @@ -53,6 +53,10 @@ TARGET_DEPENDENCY_LINE = re.compile( ) +class NoVersionsError(Exception): + pass + + def sortify(func): """Return a sorted list from a generator""" @@ -122,22 +126,34 @@ def local_crate(crate, version): return crate, cratename, version -def query_newest_version(crate): +def query_newest_version(crate) -> str: url = requests.compat.urljoin(API_URL, f"crates/{crate}/versions") req = requests.get(url, headers={"User-Agent": "rust2rpm"}) req.raise_for_status() versions = req.json()["versions"] - for struct in versions: - version = struct["num"] - if struct["yanked"]: - log.info(f"Ignoring yanked version {version!r}.") - elif re.search("alpha|beta|rc|pre", version): - log.info(f"Ignoring pre-release version {version!r}.") - else: - log.success(f"Using latest stable version {version!r}.") - return version - raise ValueError("Couldn't find any release versions. Specify a version explicitly.") + is_stable = lambda s: not re.search("alpha|beta|rc|pre", s["num"]) + is_not_yanked = lambda s: not s["yanked"] + + # return the most recent, non-yanked stable version + + is_not_yanked_and_stable = lambda s: is_stable(s) and is_not_yanked(s) + not_yanked_and_stable = [*filter(is_not_yanked_and_stable, versions)] + if len(not_yanked_and_stable) > 0: + version = not_yanked_and_stable[0]["num"] + return version + + # there are no non-yanked stable versions: + # fall back to the latest pre-release + + not_yanked = [*filter(is_not_yanked, versions)] + if len(not_yanked) > 0: + version = not_yanked[0]["num"] + log.warn(f"No stable versions available. Falling back to the latest pre-release version {version!r}.") + return version + + # there are no non-yanked versions: fatal + raise NoVersionsError() def download(crate, version): @@ -637,7 +653,11 @@ def main(): if args.crate is None: parser.error("crate/path argument missing and autodetection failed") - crate, diffs, metadata, doc_files, license_files = make_diff_metadata(args, args.crate, args.version) + try: + crate, diffs, metadata, doc_files, license_files = make_diff_metadata(args, args.crate, args.version) + except NoVersionsError: + log.error(f"No versions are available for crate {args.crate!r}.") + sys.exit(1) pkg_name = package_name_suffixed(metadata.name, args.suffix)