accept "partial" version arguments; resolve to latest matching version
This commit is contained in:
parent
2f1505daf2
commit
52e2482019
4 changed files with 59 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
|||
cargo2rpm>=0.1.8
|
||||
cargo2rpm>=0.1.11
|
||||
jinja2
|
||||
jsonschema
|
||||
pyparsing
|
||||
|
|
|
@ -6,9 +6,9 @@ import tarfile
|
|||
import tempfile
|
||||
from typing import Optional
|
||||
|
||||
from cargo2rpm.metadata import Metadata
|
||||
from cargo2rpm.metadata import Metadata, Version, VersionReq
|
||||
|
||||
from rust2rpm.cratesio import download_crate
|
||||
from rust2rpm.cratesio import download_crate, query_available_versions
|
||||
from rust2rpm import log
|
||||
from rust2rpm.patching import make_patches
|
||||
|
||||
|
@ -196,6 +196,36 @@ def process_project_local(
|
|||
return name, version, diffs, metadata, doc_files, license_files
|
||||
|
||||
|
||||
def resolve_version(crate: str, version: str) -> Optional[str]:
|
||||
# try parsing version as actual version
|
||||
try:
|
||||
resolved_version = Version.parse(version)
|
||||
return str(resolved_version)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# try parsing version as partial version
|
||||
try:
|
||||
parsed_version = VersionReq.parse(version)
|
||||
log.info("Resolving partial version ...")
|
||||
|
||||
available_versions = query_available_versions(crate)
|
||||
resolved_version = max(filter(lambda x: x in parsed_version, available_versions), default=None)
|
||||
|
||||
if resolved_version is None:
|
||||
log.warn("Partial version does not match any available version.")
|
||||
log.info("Falling back to latest version.")
|
||||
return None
|
||||
|
||||
log.info(f"Partial version matched with available version: {resolved_version}")
|
||||
return str(resolved_version)
|
||||
|
||||
except ValueError:
|
||||
log.error(f"Invalid version: {version}")
|
||||
log.info("Falling back to latest version.")
|
||||
return None
|
||||
|
||||
|
||||
def process_project(
|
||||
project: str,
|
||||
version: Optional[str],
|
||||
|
@ -220,8 +250,14 @@ def process_project(
|
|||
else:
|
||||
# project is just a crate name
|
||||
name = project
|
||||
# download .crate from crates.io;
|
||||
# set version to the latest stable version if it was not specified
|
||||
|
||||
# download .crate from crates.io
|
||||
if version:
|
||||
# version or partial version was specified
|
||||
resolved_version = resolve_version(project, version)
|
||||
crate_file_path, version = download_crate(project, resolved_version)
|
||||
else:
|
||||
# no version was specified: download latest
|
||||
crate_file_path, version = download_crate(project, version)
|
||||
|
||||
if store_crate:
|
||||
|
|
|
@ -6,6 +6,8 @@ from urllib.parse import urljoin
|
|||
import requests
|
||||
import tqdm
|
||||
|
||||
from cargo2rpm.semver import Version
|
||||
|
||||
from rust2rpm import log
|
||||
from rust2rpm.utils import remove_on_error
|
||||
|
||||
|
@ -18,6 +20,20 @@ class NoVersionsError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
def query_available_versions(crate: str, stable: bool = True) -> list[Version]:
|
||||
url = urljoin(CRATES_IO_API_URL, f"crates/{crate}/versions")
|
||||
req = requests.get(url, headers={"User-Agent": "rust2rpm"})
|
||||
req.raise_for_status()
|
||||
versions = req.json()["versions"]
|
||||
|
||||
parsed_versions = map(lambda x: Version.parse(x["num"]), filter(lambda x: not x["yanked"], versions))
|
||||
|
||||
if stable:
|
||||
return list(filter(lambda x: x.pre is None, parsed_versions))
|
||||
else:
|
||||
return list(parsed_versions)
|
||||
|
||||
|
||||
def query_newest_version(crate: str) -> str:
|
||||
url = urljoin(CRATES_IO_API_URL, f"crates/{crate}/versions")
|
||||
req = requests.get(url, headers={"User-Agent": "rust2rpm"})
|
||||
|
|
|
@ -24,7 +24,7 @@ classifiers =
|
|||
include_package_data = True
|
||||
packages = rust2rpm
|
||||
install_requires =
|
||||
cargo2rpm>=0.1.8
|
||||
cargo2rpm>=0.1.11
|
||||
jinja2
|
||||
jsonschema
|
||||
pyparsing
|
||||
|
|
Loading…
Reference in a new issue