Created
June 6, 2025 06:54
-
-
Save FalconNL93/7b243e2daeac66c8edc9755114a94b76 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
# Constants | |
DOTNET_DIR="$HOME/.dotnet" | |
INSTALL_SCRIPT="$HOME/dotnet-install.sh" | |
DEPENDENCIES_MARKER="$HOME/.dotnet_deps_installed" | |
# Ensure the "dialog" package is installed | |
ensure_dialog_installed() { | |
if ! command -v dialog &> /dev/null; then | |
echo "The 'dialog' package is not installed. Installing it now..." | |
if [ -f /etc/os-release ]; then | |
. /etc/os-release | |
if [[ "$ID" =~ ^(ubuntu|debian)$ || "$ID_LIKE" == *"debian"* || "$ID_LIKE" == *"ubuntu"* ]]; then | |
sudo apt update && sudo apt install -y dialog | |
elif [[ "$ID" =~ ^(fedora|rhel|centos)$ || "$ID_LIKE" == *"rhel"* || "$ID_LIKE" == *"fedora"* ]]; then | |
sudo dnf install -y dialog | |
elif [[ "$ID" == "arch" || "$ID_LIKE" == *"arch"* ]]; then | |
sudo pacman -Sy --noconfirm dialog | |
else | |
echo "Unsupported OS. Please install 'dialog' manually." | |
exit 1 | |
fi | |
else | |
echo "Unable to detect OS. Please install 'dialog' manually." | |
exit 1 | |
fi | |
fi | |
} | |
# Install required dependencies | |
install_dependencies() { | |
[ -f "$DEPENDENCIES_MARKER" ] && return | |
echo "Installing required system dependencies..." | |
if [ -f /etc/os-release ]; then | |
. /etc/os-release | |
if [[ "$ID" =~ ^(ubuntu|debian)$ || "$ID_LIKE" == *"debian"* || "$ID_LIKE" == *"ubuntu"* ]]; then | |
sudo apt update && sudo apt install -y --no-install-recommends \ | |
libc6 libgcc1 libgssapi-krb5-2 libicu70 libssl3 libstdc++6 \ | |
zlib1g libcurl4 libkrb5-3 libunwind8 | |
elif [[ "$ID" =~ ^(fedora|rhel|centos)$ || "$ID_LIKE" == *"rhel"* || "$ID_LIKE" == *"fedora"* ]]; then | |
sudo dnf install -y \ | |
glibc libgcc krb5-libs libicu openssl libstdc++ zlib libcurl libunwind | |
elif [[ "$ID" == "arch" || "$ID_LIKE" == *"arch"* ]]; then | |
sudo pacman -Sy --noconfirm \ | |
glibc gcc krb5 icu openssl libstdc++ zlib curl libunwind | |
else | |
echo "Unsupported OS. Please install dependencies manually." | |
exit 1 | |
fi | |
else | |
echo "Unable to detect OS. Please install dependencies manually." | |
exit 1 | |
fi | |
touch "$DEPENDENCIES_MARKER" | |
} | |
# Retrieve all major .NET SDK versions dynamically, including preview versions | |
get_dotnet_versions() { | |
curl -s https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json \ | |
| grep -oP '"channel-version":\s*"\K[0-9]+\.[0-9]+(\.[0-9]+(-[a-zA-Z0-9.]+)?)?' \ | |
| sort -uV | |
} | |
# Display the latest release per channel from releases-index.json | |
show_versions() { | |
echo "Fetching the latest .NET SDK releases per channel..." | |
curl -s https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json | \ | |
jq -r '."releases-index"[] | "\(.["channel-version"]): \(.["latest-release"])"' | |
exit 0 | |
} | |
# Select .NET SDK versions to install | |
select_versions() { | |
if [ "$UPDATE_ALL" = true ]; then return; fi | |
echo "Select the .NET SDK versions you want to install:" | |
echo "(Use arrow keys and space to select, enter to confirm.)" | |
# Get already installed full versions | |
INSTALLED=$(ls "$DOTNET_DIR/sdk" | awk -F. '{print $1"."$2}' | sort -u) | |
# Build dialog checklist options: version "on"/"off" | |
OPTIONS=() | |
for version in "${VERSIONS[@]}"; do | |
if echo "$INSTALLED" | grep -qx "$version"; then | |
OPTIONS+=("$version" "$version" "on") | |
else | |
OPTIONS+=("$version" "$version" "off") | |
fi | |
done | |
TMPFILE=$(mktemp) | |
dialog --clear --no-tags --checklist "Select .NET SDK versions to install:" 20 60 10 \ | |
"${OPTIONS[@]}" 2> "$TMPFILE" | |
if [ $? -ne 0 ]; then | |
echo "No versions selected. Exiting." | |
rm -f "$TMPFILE" | |
exit 1 | |
fi | |
SELECTED=$(cat "$TMPFILE" | tr -d '"') | |
rm -f "$TMPFILE" | |
if [ -z "$SELECTED" ]; then | |
echo "No versions selected. Exiting." | |
exit 1 | |
fi | |
SELECTED_VERSIONS=($SELECTED) | |
# Uninstall deselected versions | |
for full_version in $(ls "$DOTNET_DIR/sdk"); do | |
major_minor=$(echo "$full_version" | awk -F. '{print $1"."$2}') | |
if ! echo "${SELECTED_VERSIONS[@]}" | grep -qw "$major_minor"; then | |
echo "Uninstalling .NET SDK version $full_version..." | |
SDK_DIR="$DOTNET_DIR/sdk/$full_version" | |
if [ -d "$SDK_DIR" ]; then | |
rm -rf "$SDK_DIR" | |
echo "Removed $SDK_DIR" | |
else | |
echo "SDK version $full_version not found in $DOTNET_DIR/sdk" | |
fi | |
fi | |
done | |
} | |
# Download the dotnet-install.sh script | |
download_install_script() { | |
[ -f "$INSTALL_SCRIPT" ] && return | |
echo "Downloading dotnet-install.sh..." | |
curl -SL https://dot.net/v1/dotnet-install.sh -o "$INSTALL_SCRIPT" | |
chmod +x "$INSTALL_SCRIPT" | |
} | |
# Install or update selected .NET SDK versions | |
install_dotnet_sdks() { | |
mkdir -p "$DOTNET_DIR" | |
for version in "${SELECTED_VERSIONS[@]}"; do | |
echo "Installing or updating .NET SDK version $version..." | |
"$INSTALL_SCRIPT" --channel "$version" --install-dir "$DOTNET_DIR" | |
done | |
} | |
# Update PATH permanently | |
update_path() { | |
if ! grep -q 'DOTNET_ROOT' "$HOME/.bashrc" && ! grep -q 'DOTNET_ROOT' "$HOME/.zshrc"; then | |
echo "Updating shell configuration files..." | |
{ | |
echo -e "\n# .NET SDK setup" | |
echo "export DOTNET_ROOT=\"$DOTNET_DIR\"" | |
echo "export PATH=\"$DOTNET_DIR:\$HOME/.dotnet/tools:\$PATH\"" | |
} >> "$HOME/.bashrc" | |
{ | |
echo -e "\n# .NET SDK setup" | |
echo "export DOTNET_ROOT=\"$DOTNET_DIR\"" | |
echo "export PATH=\"$DOTNET_DIR:\$HOME/.dotnet/tools:\$PATH\"" | |
} >> "$HOME/.zshrc" | |
fi | |
# Ensure $HOME/.dotnet/tools is in PATH for the current session | |
if ! echo "$PATH" | grep -q "$HOME/.dotnet/tools"; then | |
export PATH="$HOME/.dotnet/tools:$PATH" | |
fi | |
} | |
# Main execution | |
if [[ "$1" == "versions" ]]; then | |
show_versions | |
fi | |
ensure_dialog_installed | |
VERSIONS=($(get_dotnet_versions)) | |
SELECTED_VERSIONS=("${VERSIONS[@]}") | |
select_versions | |
install_dependencies | |
download_install_script | |
install_dotnet_sdks | |
update_path | |
echo -e "\nAll requested .NET SDKs have been installed or updated successfully!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment