Do not re-download already installed Python versions (#1133)

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!
```
This commit is contained in:
Zanie Blue 2024-01-27 12:46:21 -06:00 committed by GitHub
parent 15ca17a68d
commit cb73b724cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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/"