* feature: allow local runs on windows/macOS Cache python installations to a user cache folder using platformdirs. The build environment is now a virtual environment to allow proper isolation. Allows to run tests in parallel. Co-authored-by: Joe Rickerby <joerick@mac.com>
121 lines
3.5 KiB
Python
Executable File
121 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from __future__ import annotations
|
|
|
|
import difflib
|
|
import logging
|
|
import subprocess
|
|
from pathlib import Path
|
|
from typing import NamedTuple
|
|
|
|
import click
|
|
import rich
|
|
import tomli
|
|
from packaging.version import InvalidVersion, Version
|
|
from rich.logging import RichHandler
|
|
from rich.syntax import Syntax
|
|
|
|
from cibuildwheel.typing import Final
|
|
|
|
log = logging.getLogger("cibw")
|
|
|
|
# Looking up the dir instead of using utils.resources_dir
|
|
# since we want to write to it.
|
|
DIR: Final[Path] = Path(__file__).parent.parent.resolve()
|
|
RESOURCES_DIR: Final[Path] = DIR / "cibuildwheel/resources"
|
|
|
|
GET_VIRTUALENV_GITHUB: Final[str] = "https://github.com/pypa/get-virtualenv"
|
|
GET_VIRTUALENV_URL_TEMPLATE: Final[
|
|
str
|
|
] = f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
|
|
|
|
|
|
class VersionTuple(NamedTuple):
|
|
version: Version
|
|
version_string: str
|
|
|
|
|
|
def git_ls_remote_versions(url) -> list[VersionTuple]:
|
|
versions: list[VersionTuple] = []
|
|
tags = subprocess.run(
|
|
["git", "ls-remote", "--tags", url], check=True, text=True, capture_output=True
|
|
).stdout.splitlines()
|
|
for tag in tags:
|
|
_, ref = tag.split()
|
|
assert ref.startswith("refs/tags/")
|
|
version_string = ref[10:]
|
|
try:
|
|
version = Version(version_string)
|
|
if version.is_devrelease:
|
|
log.info(f"Ignoring development release '{version}'")
|
|
continue
|
|
if version.is_prerelease:
|
|
log.info(f"Ignoring pre-release '{version}'")
|
|
continue
|
|
versions.append(VersionTuple(version, version_string))
|
|
except InvalidVersion:
|
|
log.warning(f"Ignoring ref '{ref}'")
|
|
versions.sort(reverse=True)
|
|
return versions
|
|
|
|
|
|
@click.command()
|
|
@click.option("--force", is_flag=True)
|
|
@click.option(
|
|
"--level", default="INFO", type=click.Choice(["WARNING", "INFO", "DEBUG"], case_sensitive=False)
|
|
)
|
|
def update_virtualenv(force: bool, level: str) -> None:
|
|
|
|
logging.basicConfig(
|
|
level="INFO",
|
|
format="%(message)s",
|
|
datefmt="[%X]",
|
|
handlers=[RichHandler(rich_tracebacks=True, markup=True)],
|
|
)
|
|
log.setLevel(level)
|
|
|
|
toml_file_path = RESOURCES_DIR / "virtualenv.toml"
|
|
|
|
original_toml = toml_file_path.read_text()
|
|
with toml_file_path.open("rb") as f:
|
|
loaded_file = tomli.load(f)
|
|
version = str(loaded_file["version"])
|
|
versions = git_ls_remote_versions(GET_VIRTUALENV_GITHUB)
|
|
if versions[0].version > Version(version):
|
|
version = versions[0].version_string
|
|
|
|
result_toml = (
|
|
f'version = "{version}"\n'
|
|
f'url = "{GET_VIRTUALENV_URL_TEMPLATE.format(version=version)}"\n'
|
|
)
|
|
|
|
rich.print() # spacer
|
|
|
|
if original_toml == result_toml:
|
|
rich.print("[green]Check complete, virtualenv version unchanged.")
|
|
return
|
|
|
|
rich.print("virtualenv version updated.")
|
|
rich.print("Changes:")
|
|
rich.print()
|
|
|
|
toml_relpath = toml_file_path.relative_to(DIR).as_posix()
|
|
diff_lines = difflib.unified_diff(
|
|
original_toml.splitlines(keepends=True),
|
|
result_toml.splitlines(keepends=True),
|
|
fromfile=toml_relpath,
|
|
tofile=toml_relpath,
|
|
)
|
|
rich.print(Syntax("".join(diff_lines), "diff", theme="ansi_light"))
|
|
rich.print()
|
|
|
|
if force:
|
|
toml_file_path.write_text(result_toml)
|
|
rich.print("[green]TOML file updated.")
|
|
else:
|
|
rich.print("[yellow]File left unchanged. Use --force flag to update.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
update_virtualenv()
|