From 0199ad64bb916e3c6b90765bb40f60f2af892ef0 Mon Sep 17 00:00:00 2001 From: konsti Date: Sat, 3 Feb 2024 17:30:01 +0100 Subject: [PATCH] Fix bootstrap install script on windows (#1162) Windows doesn't support symlinks, doesn't use a `bin` directory and all pythons are called `python.exe`. Note that this is still broken, `.\bin\python3.10.13` is missing its .exe extension and renaming it to `.\bin\python3.10.13.exe` makes it complain about not finding python310.dll. --- scripts/bootstrap/install.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/scripts/bootstrap/install.py b/scripts/bootstrap/install.py index 0277e2495..037dafc02 100644 --- a/scripts/bootstrap/install.py +++ b/scripts/bootstrap/install.py @@ -1,4 +1,10 @@ #!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "zstandard==0.22.0", +# ] +# /// # # Download required Python versions and install to `bin` # Uses prebuilt Python distributions from indygreg/python-build-standalone @@ -13,6 +19,10 @@ # # python scripts/bootstrap/install.py # +# Or +# +# pipx run scripts/bootstrap/install.py +# # The Python versions are installed from `.python_versions`. # Python versions are linked in-order such that the _last_ defined version will be the default. # @@ -96,8 +106,8 @@ for version in versions: print(f"No matching download for {key}") sys.exit(1) + filename = url.split("/")[-1] if not install_dir.exists(): - filename = url.split("/")[-1] print(f"Downloading {urllib.parse.unquote(filename)}") download_path = THIS_DIR / filename with urllib.request.urlopen(url) as response: @@ -129,28 +139,30 @@ for version in versions: already_exists = True print("Already available, skipping download") - # Use relative paths for links so if the bin is moved they don't break - executable = "." / install_dir.relative_to(BIN_DIR) / "install" / "bin" / "python3" if PLATFORM == "win32": - executable = executable.with_suffix(".exe") + executable = install_dir / "install" / "python.exe" + else: + # Use relative paths for links so if the bin is moved they don't break + executable = "." / install_dir.relative_to(BIN_DIR) / "install" / "bin" / "python3" major = versions_metadata[key]["major"] minor = versions_metadata[key]["minor"] # Link as all version tuples, later versions in the file will take precedence BIN_DIR.mkdir(parents=True, exist_ok=True) - targets = ( + + targets = [ (BIN_DIR / f"python{version}"), (BIN_DIR / f"python{major}.{minor}"), (BIN_DIR / f"python{major}"), (BIN_DIR / "python"), - ) + ] for target in targets: - if PLATFORM == "win32": - target = target.with_suffix(".exe") - target.unlink(missing_ok=True) - target.symlink_to(executable) + if PLATFORM == "win32": + target.hardlink_to(executable) + else: + target.symlink_to(executable) if already_exists: print(f"Updated executables for python{version}")