mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-08 19:44:57 -05:00
chore: Move to the mono repo layout
This commit is contained in:
222
frontends/concrete-python/script/make_utils/version_utils.py
Normal file
222
frontends/concrete-python/script/make_utils/version_utils.py
Normal file
@@ -0,0 +1,222 @@
|
||||
"""Tool to manage version in the project"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
import tomlkit
|
||||
from semver import VersionInfo
|
||||
|
||||
|
||||
def strip_leading_v(version_str: str):
|
||||
"""Strip leading v of a version which is not SemVer compatible."""
|
||||
return version_str[1:] if version_str.startswith("v") else version_str
|
||||
|
||||
|
||||
def islatest(args):
|
||||
"""islatest command entry point."""
|
||||
print(args, file=sys.stderr)
|
||||
|
||||
# This is the safest default
|
||||
result = {"is_latest": False, "is_prerelease": True}
|
||||
|
||||
new_version_str = strip_leading_v(args.new_version)
|
||||
if VersionInfo.isvalid(new_version_str):
|
||||
new_version_info = VersionInfo.parse(new_version_str)
|
||||
if new_version_info.prerelease is None:
|
||||
# If it's an actual release
|
||||
all_versions_str = (
|
||||
strip_leading_v(version_str) for version_str in args.existing_versions
|
||||
)
|
||||
|
||||
# Keep versions that are not release candidate
|
||||
version_infos = [
|
||||
VersionInfo.parse(version_str)
|
||||
for version_str in all_versions_str
|
||||
if VersionInfo.isvalid(version_str)
|
||||
]
|
||||
all_non_prerelease_version_infos = [
|
||||
version_info for version_info in version_infos if version_info.prerelease is None
|
||||
]
|
||||
|
||||
all_non_prerelease_version_infos.append(new_version_info)
|
||||
|
||||
new_version_is_latest = max(all_non_prerelease_version_infos) == new_version_info
|
||||
result["is_latest"] = new_version_is_latest
|
||||
result["is_prerelease"] = False
|
||||
|
||||
print(json.dumps(result))
|
||||
|
||||
|
||||
def update_variable_in_py_file(file_path: Path, var_name: str, version_str: str):
|
||||
"""Update the version in a .py file."""
|
||||
|
||||
file_content = None
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
file_content = f.read()
|
||||
|
||||
updated_file_content = re.sub(
|
||||
rf'{var_name} *[:=] *["\'](.+)["\']',
|
||||
rf'{var_name} = "{version_str}"',
|
||||
file_content,
|
||||
)
|
||||
|
||||
with open(file_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(updated_file_content)
|
||||
|
||||
|
||||
def update_variable_in_toml_file(file_path: Path, var_name: str, version_str: str):
|
||||
"""Update the version in a .toml file."""
|
||||
toml_content = None
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
toml_content = tomlkit.loads(f.read())
|
||||
|
||||
toml_keys = var_name.split(".")
|
||||
current_content = toml_content
|
||||
for toml_key in toml_keys[:-1]:
|
||||
current_content = current_content[toml_key]
|
||||
last_toml_key = toml_keys[-1]
|
||||
current_content[last_toml_key] = version_str
|
||||
|
||||
with open(file_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(tomlkit.dumps(toml_content))
|
||||
|
||||
|
||||
def load_file_vars_set(pyproject_path: os.PathLike, cli_file_vars: Optional[List[str]]):
|
||||
"""Load files and their version variables set-up in pyproject.toml and passed as arguments."""
|
||||
|
||||
file_vars_set = set()
|
||||
if cli_file_vars is not None:
|
||||
file_vars_set.update(cli_file_vars)
|
||||
|
||||
pyproject_path = Path(pyproject_path).resolve()
|
||||
|
||||
# Check if there is a semantic release configuration
|
||||
if pyproject_path.exists():
|
||||
pyproject_content = None
|
||||
with open(pyproject_path, encoding="utf-8") as f:
|
||||
pyproject_content = tomlkit.loads(f.read())
|
||||
|
||||
try:
|
||||
sr_conf = pyproject_content["tool"]["semantic_release"]
|
||||
sr_version_toml: str = sr_conf.get("version_toml", "")
|
||||
file_vars_set.update(sr_version_toml.split(","))
|
||||
sr_version_variable: str = sr_conf.get("version_variable", "")
|
||||
file_vars_set.update(sr_version_variable.split(","))
|
||||
except KeyError:
|
||||
print("No configuration for semantic release in pyproject.toml")
|
||||
|
||||
return file_vars_set
|
||||
|
||||
|
||||
def set_version(args):
|
||||
"""set-version command entry point."""
|
||||
|
||||
version_str = strip_leading_v(args.version)
|
||||
if not VersionInfo.isvalid(version_str):
|
||||
message = f"Unable to validate version: {args.version}"
|
||||
raise RuntimeError(message)
|
||||
|
||||
file_vars_set = load_file_vars_set(args.pyproject_file, args.file_vars)
|
||||
|
||||
for file_var_str in sorted(file_vars_set):
|
||||
print(f"Processing {file_var_str}")
|
||||
file, var_name = file_var_str.split(":", 1)
|
||||
file_path = Path(file).resolve()
|
||||
|
||||
if file_path.suffix == ".py":
|
||||
update_variable_in_py_file(file_path, var_name, version_str)
|
||||
elif file_path.suffix == ".toml":
|
||||
update_variable_in_toml_file(file_path, var_name, version_str)
|
||||
else:
|
||||
message = f"Unsupported file extension: {file_path.suffix}"
|
||||
raise RuntimeError(message)
|
||||
|
||||
|
||||
def get_variable_from_py_file(file_path: Path, var_name: str):
|
||||
"""Read variable value from a .py file."""
|
||||
file_content = None
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
file_content = f.read()
|
||||
|
||||
variable_values_set = set()
|
||||
|
||||
start_pos = 0
|
||||
while True:
|
||||
file_content = file_content[start_pos:]
|
||||
match = re.search(
|
||||
rf'{var_name} *[:=] *["\'](.+)["\']',
|
||||
file_content,
|
||||
)
|
||||
if match is None:
|
||||
break
|
||||
|
||||
variable_values_set.add(match.group(1))
|
||||
start_pos = match.end()
|
||||
|
||||
return variable_values_set
|
||||
|
||||
|
||||
def get_variable_from_toml_file(file_path: Path, var_name: str):
|
||||
"""Read variable value from a .toml file."""
|
||||
|
||||
toml_content = None
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
toml_content = tomlkit.loads(f.read())
|
||||
|
||||
toml_keys = var_name.split(".")
|
||||
current_content = toml_content
|
||||
for toml_key in toml_keys:
|
||||
current_content = current_content[toml_key]
|
||||
|
||||
return current_content
|
||||
|
||||
|
||||
def main(args):
|
||||
"""Entry point"""
|
||||
args.entry_point(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main_parser = argparse.ArgumentParser("Version utils", allow_abbrev=False)
|
||||
|
||||
sub_parsers = main_parser.add_subparsers(dest="sub-command", required=True)
|
||||
|
||||
parser_islatest = sub_parsers.add_parser("islatest")
|
||||
parser_islatest.add_argument(
|
||||
"--new-version", type=str, required=True, help="The new version to compare"
|
||||
)
|
||||
parser_islatest.add_argument(
|
||||
"--existing-versions",
|
||||
type=str,
|
||||
nargs="+",
|
||||
required=True,
|
||||
help="The list of existing versions",
|
||||
)
|
||||
parser_islatest.set_defaults(entry_point=islatest)
|
||||
|
||||
parser_set_version = sub_parsers.add_parser("set-version")
|
||||
parser_set_version.add_argument("--version", type=str, required=True, help="The version to set")
|
||||
parser_set_version.add_argument(
|
||||
"--pyproject-file",
|
||||
type=str,
|
||||
default="pyproject.toml",
|
||||
help="The path to a project's pyproject.toml file, defaults to $pwd/pyproject.toml",
|
||||
)
|
||||
parser_set_version.add_argument(
|
||||
"--file-vars",
|
||||
type=str,
|
||||
nargs="+",
|
||||
help=(
|
||||
"A space separated list of file/path.{py, toml}:variable to update with the new version"
|
||||
),
|
||||
)
|
||||
parser_set_version.set_defaults(entry_point=set_version)
|
||||
|
||||
cli_args = main_parser.parse_args()
|
||||
|
||||
main(cli_args)
|
||||
Reference in New Issue
Block a user