import json
import re
import subprocess
import requests
from semantic_version import Version
CARGO_TREE_RE = re.compile(
r"^[|`]-- (?P<crate>[a-z0-9_\-]+) v(?P<version>[0-9\.]+)( \(.*\))?$"
)
KOJI_RE = re.compile(
r"^toplink/packages/rust-(?P<name>[^\/]*?)/(?P<version>[^\/]*?)/[^]*)]*"
)
VERSION_RE = re.compile(
r"^\^(?P<major>[0-9]+)(\.(?P<minor>[0-9]+))?(\.(?P<patch>[0-9]+))?$"
)
def build_cargo_tree_dict():
command = ["cargo", "tree", "--charset=ascii", "--all-features"]
proc = subprocess.Popen(command, stdout=subprocess.PIPE)
stream = proc.stdout
version_dict = dict()
line = stream.readline()
while line != b"":
line_str = line.decode("utf-8").rstrip()
cargo_tree_match = CARGO_TREE_RE.search(line_str)
if cargo_tree_match is not None:
version_dict[cargo_tree_match.group("crate")] = Version(
cargo_tree_match.group("version")
)
line = stream.readline()
return version_dict
def build_koji_repo_dict(crates):
koji_repo_dict = {}
requests_var = requests.get(
"https://kojipkgs.fedoraproject.org/repos/rawhide/latest/x86_64/pkglist"
)
packages = requests_var.text
for line in packages.splitlines():
matches = KOJI_RE.match(line)
if matches is None:
continue
name = matches.group("name")
if name in crates:
version = matches.group("version").replace("~", "-")
koji_repo_dict[name] = Version(version)
return koji_repo_dict
def build_cargo_metadata():
command = [
"cargo",
"metadata",
"--format-version=1",
"--no-deps",
"--all-features",
]
proc = subprocess.Popen(command, stdout=subprocess.PIPE)
stream = proc.stdout
metadata_str = stream.readline()
metadata = json.loads(metadata_str)
packages = metadata["packages"]
assert len(packages) == 1
package = packages[0]
dependencies = package["dependencies"]
result = dict()
for item in dependencies:
matches = VERSION_RE.match(item["req"])
major = int(matches["major"] or 0)
minor = int(matches["minor"] or 0)
patch = int(matches["patch"] or 0)
result[item["name"]] = Version(major=major, minor=minor, patch=patch)
return result