From cb73b724cb2c77828076a555aa9db597be1b797c Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Sat, 27 Jan 2024 12:46:21 -0600 Subject: [PATCH] Do not re-download already installed Python versions (#1133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A minor usability improvement cherry-picked from https://github.com/astral-sh/puffin/pull/1131 e.g. ``` ❯ scripts/bootstrap/install.sh Installing cpython-3.8.12-darwin-arm64 Already available, skipping download Updated executables for python3.8.12 Installing cpython-3.8.18-darwin-arm64 Already available, skipping download Updated executables for python3.8.18 Installing cpython-3.9.18-darwin-arm64 Already available, skipping download Updated executables for python3.9.18 Installing cpython-3.10.13-darwin-arm64 Already available, skipping download Updated executables for python3.10.13 Installing cpython-3.11.7-darwin-arm64 Already available, skipping download Updated executables for python3.11.7 Installing cpython-3.12.1-darwin-arm64 Already available, skipping download Updated executables for python3.12.1 Done! ``` --- scripts/bootstrap/install.sh | 37 ++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/scripts/bootstrap/install.sh b/scripts/bootstrap/install.sh index ff1cb0fb8..3c12c6b80 100755 --- a/scripts/bootstrap/install.sh +++ b/scripts/bootstrap/install.sh @@ -63,14 +63,39 @@ interpreter='cpython' # On macOS, we need a newer version of `realpath` for `--relative-to` support realpath="$(which grealpath || which realpath)" + +# Utility for linking executables for the version being installed +# We need to update executables even if the version is already downloaded and extracted +# to ensure that changes to the precedence of versions are respected +link_executables() { + # Use relative paths for links so if the bin is moved they don't break + local link=$($realpath --relative-to="$bin_dir" "$install_key/install/bin/python3") + local minor=$(jq --arg key "$key" '.[$key] | .minor' -r < "$versions_metadata") + + # Link as all version tuples, later versions in the file will take precedence + ln -sf "./$link" "$bin_dir/python$version" + ln -sf "./$link" "$bin_dir/python3.$minor" + ln -sf "./$link" "$bin_dir/python3" + ln -sf "./$link" "$bin_dir/python" +} + # Read requested versions into an array readarray -t versions < "$versions_file" # Install each version for version in "${versions[@]}"; do key="$interpreter-$version-$os-$arch" + install_key="$install_dir/$interpreter@$version" echo "Installing $key" + if [ -d "$install_key" ]; then + echo "Already available, skipping download" + link_executables + echo "Updated executables for python$version" + continue + fi + + url=$(jq --arg key "$key" '.[$key] | .url' -r < "$versions_metadata") if [ "$url" == 'null' ]; then @@ -91,7 +116,6 @@ for version in "${versions[@]}"; do echo " OK" fi - install_key="$install_dir/$interpreter@$version" rm -rf "$install_key" echo "Extracting to $($realpath --relative-to="$root_dir" "$install_key")" mkdir -p "$install_key" @@ -99,16 +123,9 @@ for version in "${versions[@]}"; do # Setup the installation mv "$install_key/python/"* "$install_key" - # Use relative paths for links so if the bin is moved they don't break - link=$($realpath --relative-to="$bin_dir" "$install_key/install/bin/python3") - minor=$(jq --arg key "$key" '.[$key] | .minor' -r < "$versions_metadata") - # Link as all version tuples, later versions in the file will take precedence - ln -sf "./$link" "$bin_dir/python$version" - ln -sf "./$link" "$bin_dir/python3.$minor" - ln -sf "./$link" "$bin_dir/python3" - ln -sf "./$link" "$bin_dir/python" - echo "Installed as python$version" + link_executables + echo "Installed executables for python$version" # Cleanup rmdir "$install_key/python/"