mirror of
https://github.com/frida/releng.git
synced 2026-11-07 09:36:02 -10:00
Builds from release tarballs have no git metadata and reported 0.0.0. Let packaging pass the version it already knows.
120 lines
2.9 KiB
Python
Executable File
120 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
from dataclasses import dataclass
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from typing import List
|
|
|
|
|
|
RELENG_DIR = Path(__file__).resolve().parent
|
|
ROOT_DIR = RELENG_DIR.parent
|
|
|
|
|
|
@dataclass
|
|
class FridaVersion:
|
|
name: str
|
|
major: int
|
|
minor: int
|
|
micro: int
|
|
nano: int
|
|
commit: str
|
|
|
|
|
|
def main(argv: List[str]):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("repo", nargs="?", type=Path, default=ROOT_DIR)
|
|
args = parser.parse_args()
|
|
|
|
version = detect(args.repo)
|
|
print(version.name)
|
|
|
|
|
|
def detect(repo: Path) -> FridaVersion:
|
|
override = os.environ.get("FRIDA_VERSION")
|
|
if override is not None:
|
|
return parse(override)
|
|
|
|
version_name = "0.0.0"
|
|
major = 0
|
|
minor = 0
|
|
micro = 0
|
|
nano = 0
|
|
commit = ""
|
|
|
|
if not (repo / ".git").exists():
|
|
return FridaVersion(version_name, major, minor, micro, nano, commit)
|
|
|
|
proc = subprocess.run(
|
|
["git", "describe", "--tags", "--always", "--long"],
|
|
cwd=repo,
|
|
capture_output=True,
|
|
encoding="utf-8",
|
|
check=False,
|
|
)
|
|
description = proc.stdout.strip()
|
|
|
|
if "-" not in description:
|
|
commit = description
|
|
return FridaVersion(version_name, major, minor, micro, nano, commit)
|
|
|
|
parts = description.rsplit("-", 2)
|
|
if len(parts) != 3:
|
|
raise VersionParseError(f"Unexpected format from git describe: {description!r}")
|
|
|
|
tag_part, distance_str, commit_part = parts
|
|
commit = commit_part.lstrip("g")
|
|
|
|
try:
|
|
distance = int(distance_str)
|
|
except ValueError as exc:
|
|
raise VersionParseError(f"Invalid distance in {description!r}") from exc
|
|
|
|
nano = distance
|
|
|
|
m = VERSION_PATTERN.match(tag_part)
|
|
if m is None:
|
|
raise VersionParseError(
|
|
f"Tag does not match expected semver pattern: {tag_part!r}"
|
|
)
|
|
|
|
major = int(m.group(1))
|
|
minor = int(m.group(2))
|
|
micro = int(m.group(3))
|
|
suffix = m.group(4)
|
|
|
|
if suffix is None:
|
|
if distance == 0:
|
|
version_name = f"{major}.{minor}.{micro}"
|
|
else:
|
|
micro += 1
|
|
version_name = f"{major}.{minor}.{micro}-dev.{distance - 1}"
|
|
else:
|
|
base = f"{major}.{minor}.{micro}-{suffix}"
|
|
if distance == 0:
|
|
version_name = base
|
|
else:
|
|
version_name = f"{base}-dev.{distance - 1}"
|
|
|
|
return FridaVersion(version_name, major, minor, micro, nano, commit)
|
|
|
|
|
|
def parse(name: str) -> FridaVersion:
|
|
m = VERSION_PATTERN.match(name)
|
|
if m is None:
|
|
raise VersionParseError(f"Version does not match expected semver pattern: {name!r}")
|
|
return FridaVersion(name, int(m.group(1)), int(m.group(2)), int(m.group(3)), 0, "")
|
|
|
|
|
|
class VersionParseError(Exception):
|
|
pass
|
|
|
|
|
|
VERSION_PATTERN = re.compile(r"^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$")
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv)
|