Compare commits
No commits in common. "main" and "v0.2.6" have entirely different histories.
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "pycage"
|
name = "pycage"
|
||||||
version = "0.2.8"
|
version = "0.2.6"
|
||||||
description = "tool to handle standalone Python installations from the CLI"
|
description = "tool to handle standalone Python installations from the CLI"
|
||||||
authors = [
|
authors = [
|
||||||
{name = "Florian Förster", email = "f.foerster@d-opt.com"},
|
{name = "Florian Förster", email = "f.foerster@d-opt.com"},
|
||||||
@ -78,7 +78,7 @@ directory = "reports/coverage"
|
|||||||
|
|
||||||
|
|
||||||
[tool.bumpversion]
|
[tool.bumpversion]
|
||||||
current_version = "0.2.8"
|
current_version = "0.2.6"
|
||||||
parse = """(?x)
|
parse = """(?x)
|
||||||
(?P<major>0|[1-9]\\d*)\\.
|
(?P<major>0|[1-9]\\d*)\\.
|
||||||
(?P<minor>0|[1-9]\\d*)\\.
|
(?P<minor>0|[1-9]\\d*)\\.
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
pdm build -d build/ --no-sdist
|
pdm build -d build/
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import click
|
import click
|
||||||
|
|
||||||
from pycage.helpers import delete_files, print_error
|
from pycage.helpers import get_interpreter, print_error
|
||||||
|
|
||||||
|
|
||||||
@click.group(help="commands to remove specified files")
|
@click.group(help="commands to remove specified files")
|
||||||
@ -8,6 +8,22 @@ def clean() -> None:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def delete_files(
|
||||||
|
glob_pattern: str,
|
||||||
|
) -> None:
|
||||||
|
try:
|
||||||
|
pth_intp = get_interpreter()
|
||||||
|
except RuntimeError:
|
||||||
|
click.echo("Base interpreter path could not be found", err=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
base_folder = pth_intp.parent
|
||||||
|
assert base_folder.is_dir(), "base folder not a directory"
|
||||||
|
files_to_delete = base_folder.glob(glob_pattern)
|
||||||
|
for file in files_to_delete:
|
||||||
|
file.unlink(missing_ok=True)
|
||||||
|
|
||||||
|
|
||||||
@click.command(help="removes all pre-compiled byte code files in the distribution")
|
@click.command(help="removes all pre-compiled byte code files in the distribution")
|
||||||
def precompiled() -> None:
|
def precompiled() -> None:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import subprocess
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from pycage import helpers
|
from pycage import clean
|
||||||
from pycage.helpers import get_interpreter, print_error
|
from pycage.helpers import get_interpreter, print_error
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ def compile(
|
|||||||
|
|
||||||
if delete_existing:
|
if delete_existing:
|
||||||
try:
|
try:
|
||||||
helpers.delete_files(r"**/*.pyc")
|
clean.delete_files(r"**/*.pyc")
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print_error(err)
|
print_error(err)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Final, TypeAlias
|
from typing import Final
|
||||||
|
|
||||||
LIB_ROOT_FOLDER: Final[Path] = Path(__file__).parent
|
LIB_ROOT_FOLDER: Final[Path] = Path(__file__).parent
|
||||||
if not LIB_ROOT_FOLDER.exists():
|
if not LIB_ROOT_FOLDER.exists():
|
||||||
@ -8,10 +8,3 @@ if not LIB_ROOT_FOLDER.exists():
|
|||||||
MSVC_FOLDER: Final[Path] = LIB_ROOT_FOLDER / "_files/msvc-redist"
|
MSVC_FOLDER: Final[Path] = LIB_ROOT_FOLDER / "_files/msvc-redist"
|
||||||
if not MSVC_FOLDER.exists():
|
if not MSVC_FOLDER.exists():
|
||||||
raise FileNotFoundError(f"Folder for MSVC Redist files not found under: >{MSVC_FOLDER}<")
|
raise FileNotFoundError(f"Folder for MSVC Redist files not found under: >{MSVC_FOLDER}<")
|
||||||
|
|
||||||
PyVersionToReleaseTag: TypeAlias = tuple[str, str]
|
|
||||||
PY_VERSION_TO_RELEASE_TAG_PAIRS: Final[tuple[PyVersionToReleaseTag, ...]] = (
|
|
||||||
("3.11.12", "20250409"),
|
|
||||||
("3.11.13", "20250702"),
|
|
||||||
("3.11.14", "20251014"),
|
|
||||||
)
|
|
||||||
|
|||||||
@ -11,13 +11,7 @@ from dopt_basics.io import combine_route
|
|||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
from pycage import config
|
from pycage import config
|
||||||
from pycage.constants import PY_VERSION_TO_RELEASE_TAG_PAIRS
|
from pycage.helpers import delete_folder_recursively, path_verify_existence, print_error
|
||||||
from pycage.helpers import (
|
|
||||||
delete_files,
|
|
||||||
delete_folder_recursively,
|
|
||||||
path_verify_existence,
|
|
||||||
print_error,
|
|
||||||
)
|
|
||||||
from pycage.types import JsonMetadata, RetrievalInfo
|
from pycage.types import JsonMetadata, RetrievalInfo
|
||||||
|
|
||||||
# cfg_path = Path.cwd() / "../config/config.toml"
|
# cfg_path = Path.cwd() / "../config/config.toml"
|
||||||
@ -119,20 +113,6 @@ def extract_archive(
|
|||||||
default=None,
|
default=None,
|
||||||
help="specifiy a different target location, default: current working directory",
|
help="specifiy a different target location, default: current working directory",
|
||||||
)
|
)
|
||||||
@click.option(
|
|
||||||
"-ow",
|
|
||||||
"--overwrite",
|
|
||||||
is_flag=True,
|
|
||||||
show_default=True,
|
|
||||||
default=False,
|
|
||||||
help=(
|
|
||||||
"overwrite installation with specified Python bundle instead of deleting it, any "
|
|
||||||
"pre-compiled files are deleted to force the re-comilation of the code by the new "
|
|
||||||
"Python interpreter. CAUTION: No compatibility checks for the installed packages is "
|
|
||||||
"done. Therefore, it is not guaranteed that the new installation will work. This "
|
|
||||||
"option is primarily intented for patch versions of Python."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@click.option(
|
@click.option(
|
||||||
"-k",
|
"-k",
|
||||||
"--keep",
|
"--keep",
|
||||||
@ -161,7 +141,6 @@ def get(
|
|||||||
release_tag: str | None,
|
release_tag: str | None,
|
||||||
force_reextract: bool,
|
force_reextract: bool,
|
||||||
dl_folder: Path | None,
|
dl_folder: Path | None,
|
||||||
overwrite: bool,
|
|
||||||
keep: bool,
|
keep: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
url_metadata = cast(str, config.CFG["metadata"]["URL"])
|
url_metadata = cast(str, config.CFG["metadata"]["URL"])
|
||||||
@ -185,30 +164,21 @@ def get(
|
|||||||
# destination folder
|
# destination folder
|
||||||
dl_folder = dl_folder if dl_folder is not None else Path.cwd()
|
dl_folder = dl_folder if dl_folder is not None else Path.cwd()
|
||||||
path_verify_existence(dl_folder)
|
path_verify_existence(dl_folder)
|
||||||
|
# folder_extract = prepare_path(dl_folder, None, None, None, create_folder=True)
|
||||||
target_folder = dl_folder / "python"
|
target_folder = dl_folder / "python"
|
||||||
folder_extract = dl_folder
|
folder_extract = dl_folder
|
||||||
src_file = dl_folder / filename
|
src_file = dl_folder / filename
|
||||||
_overwrite: bool = False
|
|
||||||
if target_folder.exists() and overwrite:
|
|
||||||
if click.confirm("Do you really want to overwrite the existing installation?"):
|
|
||||||
_overwrite = True
|
|
||||||
else:
|
|
||||||
click.echo(
|
|
||||||
"Overwrite option ignored. Delete existing installation before extraction."
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not src_file.exists():
|
if not src_file.exists():
|
||||||
click.echo("File not yet available. Download...")
|
click.echo("File not yet available. Download...")
|
||||||
load_file_from_url(url=retrieval_info.url, file_save_path=src_file)
|
load_file_from_url(url=retrieval_info.url, file_save_path=src_file)
|
||||||
if not _overwrite:
|
delete_folder_recursively(target_folder)
|
||||||
delete_folder_recursively(target_folder)
|
|
||||||
extract_archive(src_file, folder_extract)
|
extract_archive(src_file, folder_extract)
|
||||||
click.echo("Download and extraction successfully.")
|
click.echo("Download and extraction successfully.")
|
||||||
elif force_reextract:
|
elif force_reextract:
|
||||||
click.echo("File already downloaded. Re-extract file...")
|
click.echo("File already downloaded. Re-extract file...")
|
||||||
if not _overwrite:
|
delete_folder_recursively(target_folder)
|
||||||
delete_folder_recursively(target_folder)
|
|
||||||
extract_archive(src_file, folder_extract)
|
extract_archive(src_file, folder_extract)
|
||||||
click.echo("Re-extraction successfully.")
|
click.echo("Re-extraction successfully.")
|
||||||
else:
|
else:
|
||||||
@ -219,17 +189,6 @@ def get(
|
|||||||
except Exception as err:
|
except Exception as err:
|
||||||
print_error(err)
|
print_error(err)
|
||||||
|
|
||||||
if _overwrite:
|
|
||||||
click.echo(
|
|
||||||
"Overwrite option was chosen. Delete any existing pre-compiled "
|
|
||||||
"files to force recompilation..."
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
delete_files(r"**/*.pyc")
|
|
||||||
except Exception as err:
|
|
||||||
print_error(err)
|
|
||||||
click.echo("Pre-compiled files were removed successfully.")
|
|
||||||
|
|
||||||
if not keep:
|
if not keep:
|
||||||
try:
|
try:
|
||||||
src_file.unlink()
|
src_file.unlink()
|
||||||
@ -238,17 +197,3 @@ def get(
|
|||||||
"The archive file could not be deleted because of following exception..."
|
"The archive file could not be deleted because of following exception..."
|
||||||
)
|
)
|
||||||
print_error(err)
|
print_error(err)
|
||||||
|
|
||||||
|
|
||||||
@click.command(
|
|
||||||
help=(
|
|
||||||
"show supported Python version and corresponding release tags from the"
|
|
||||||
"standalone repository to have a quick lookup which version can be downloaded "
|
|
||||||
"with which release tag, information can be used with the 'get' command"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
def show_version_release_tag() -> None:
|
|
||||||
click.echo("Known version and release tag pairs are...")
|
|
||||||
click.echo("Python Version --> Release Tag")
|
|
||||||
for pair in PY_VERSION_TO_RELEASE_TAG_PAIRS:
|
|
||||||
click.echo(f"{pair[0]:<8} --> {pair[1]:>9}")
|
|
||||||
|
|||||||
@ -57,19 +57,3 @@ def get_interpreter() -> Path:
|
|||||||
raise RuntimeError("Base interpreter not found") from err
|
raise RuntimeError("Base interpreter not found") from err
|
||||||
|
|
||||||
return pth_int
|
return pth_int
|
||||||
|
|
||||||
|
|
||||||
def delete_files(
|
|
||||||
glob_pattern: str,
|
|
||||||
) -> None:
|
|
||||||
try:
|
|
||||||
pth_intp = get_interpreter()
|
|
||||||
except RuntimeError:
|
|
||||||
click.echo("Base interpreter path could not be found", err=True)
|
|
||||||
return
|
|
||||||
|
|
||||||
base_folder = pth_intp.parent
|
|
||||||
assert base_folder.is_dir(), "base folder not a directory"
|
|
||||||
files_to_delete = base_folder.glob(glob_pattern)
|
|
||||||
for file in files_to_delete:
|
|
||||||
file.unlink(missing_ok=True)
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@ def cli():
|
|||||||
|
|
||||||
|
|
||||||
cli.add_command(pycage.get.get)
|
cli.add_command(pycage.get.get)
|
||||||
cli.add_command(pycage.get.show_version_release_tag)
|
|
||||||
cli.add_command(pycage.venv.venv)
|
cli.add_command(pycage.venv.venv)
|
||||||
cli.add_command(pycage.files.copy)
|
cli.add_command(pycage.files.copy)
|
||||||
cli.add_command(pycage.compile.compile)
|
cli.add_command(pycage.compile.compile)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user