Last active
March 12, 2024 21:58
-
-
Save metcalfc/a3972c13134cce93ee344d60ce689789 to your computer and use it in GitHub Desktop.
Get a version of Zig for Windows.
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
<# | |
.SYNOPSIS | |
This script downloads and installs the specified version of zig. | |
.DESCRIPTION | |
The script downloads the specified version of zig from https://ziglang.org, extracts it into the user's home directory, and optionally adds it to the PATH. | |
.PARAMETER version | |
The version of zig to download. If not specified, the script downloads the master version. | |
.PARAMETER filename | |
The path to a file containing a JSON object with a "required_zig" field. If specified, the script reads the version from the file. | |
.PARAMETER updatepath | |
If specified, the script adds the zig directory to the PATH. | |
.EXAMPLE | |
.\ziggy.ps1 -updatepath | |
.\ziggy.ps1 -version "0.12.0-dev.2741+d7563a775" | |
.\ziggy.ps1 -filename $HOME\src\ghostty\build.zig | |
#> | |
param ( | |
[Parameter(Mandatory=$false)] | |
[ValidatePattern('^(\d+\.\d+\.\d+)(-dev\.\d+\+\w+)?$')] | |
[string]$version = "", | |
[switch]$updatepath = $false, | |
[Parameter(Mandatory=$false)] | |
[string]$filename = "" | |
) | |
# If a version string is not provided, check the filename | |
if ($version -eq "") { | |
if ($filename -ne "") { | |
$fileContent = Get-Content -Path "$filename" -Raw | |
try { | |
$json = ConvertFrom-Json -InputObject $fileContent | |
$version = $json.version | |
} catch { | |
Write-Error "Failed to parse the file content as JSON." | |
return | |
} | |
} else { | |
$jsonUrl = "https://ziglang.org/download/index.json" | |
$jsonContent = Invoke-WebRequest -Uri $jsonUrl -UseBasicParsing | |
$jsonData = ConvertFrom-Json -InputObject $jsonContent.Content | |
$version = $jsonData.master.version | |
} | |
} | |
# Construct the tarball URL | |
$tarballUrl = "https://ziglang.org/builds/zig-windows-x86_64-$version.zip" | |
# Define the path to zig.exe | |
$zigExePath = "$HOME\zig\zig.exe" | |
# Check if zig.exe exists | |
if (Test-Path $zigExePath) { | |
# Get the output of "zig.exe version" | |
$zigVersion = & $zigExePath version | |
# Compare the version string to the output of "zig.exe version" | |
if ($version -eq $zigVersion) { | |
Write-Output "The specified version is already installed." | |
return | |
} | |
} | |
# Download the tarball | |
$tarballPath = "$HOME\zig.zip" | |
try { | |
Invoke-WebRequest -Uri $tarballUrl -OutFile $tarballPath | |
} catch { | |
Write-Error "Failed to download the tarball from $tarballUrl" | |
return | |
} | |
# Define the "zig" directory in the user's home directory | |
$zigDir = "$HOME\zig" | |
# Check if the "zig" directory exists and remove it if it does | |
if (Test-Path $zigDir) { | |
Remove-Item -Path $zigDir -Recurse -Force | |
} | |
# Extract the tarball into the "zig" directory | |
try { | |
# Exppand-Archive doesn't have the ability to strip components like tar. | |
# So we need to extract the contents of the tarball into a temporary | |
# directory and then move the contents to the "zig" directory. | |
$tempPath = "$HOME\zig\tmp" | |
Expand-Archive -Path $tarballPath -DestinationPath $tempPath | |
$contentInsideBogusFolder = Get-Item -Path "$tempPath\zig-windows-*" | |
Move-Item -Path "$contentInsideBogusFolder\*" -Destination "$HOME\zig" -Force | |
Remove-Item -Path $tempPath -Recurse -Force | |
} catch { | |
Write-Error "Failed to extract the tarball" | |
return | |
} | |
# Clean up the downloaded zip file | |
Remove-Item -Path $tarballPath -Force | |
# Check if $updatePath is true | |
if ($updatePath) { | |
# Add the "zig" directory to the PATH | |
$envPath = [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::User) | |
$newEnvPath = $envPath + ";" + $zigDir | |
[Environment]::SetEnvironmentVariable("Path", $newEnvPath, [EnvironmentVariableTarget]::User) | |
# Remind the user to restart their shell | |
Write-Output "Please restart your shell for the updated PATH to take effect." | |
} |
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 -o errexit # abort on nonzero exitstatus | |
set -o nounset # abort on unbound variable | |
set -o pipefail # don't hide errors within pipes | |
ZIG_DOWNLOAD_URL="https://ziglang.org/download/index.json" | |
ZIG_TMP_FILE=$(mktemp /tmp/zig_version.json.XXXXXX) | |
ZIG_VERSION="" | |
FILENAME="" # File name to parse for version | |
UNINSTALL="false" # Uninstall flag | |
ZIG_DIR="$HOME/.zig" | |
BIN_DIR="$HOME/bin" | |
ZIG_EXE_BIN="$BIN_DIR/zig" | |
TMP_ZIG_TAR=$(mktemp /tmp/zig.tar.xz.XXXXXX) | |
OS="" | |
ARCH="" | |
check_os_and_arch() { | |
# Identify the OS | |
if [[ "$OSTYPE" == "linux-gnu"* ]]; then | |
OS="linux" | |
elif [[ "$OSTYPE" == "darwin"* ]]; then | |
OS="macos" | |
else | |
echo "Unsupported operating system. This script works on Linux and macOS." | |
exit 1 | |
fi | |
# Identify the architecture | |
if [[ "$(uname -m)" == "x86_64" ]]; then | |
ARCH="x86_64" | |
elif [[ "$(uname -m)" == "arm64" ]]; then | |
ARCH="aarch64" | |
else | |
echo "Unsupported architecture. This script works on x86_64 and ARM." | |
exit 1 | |
fi | |
} | |
# Check if jq, curl, and tar are installed | |
for cmd in jq curl tar; do | |
if ! command -v "$cmd" &> /dev/null; then | |
printf "%s could not be found. Please install it.\n" "$cmd" | |
exit 1 | |
fi | |
done | |
download_file() { | |
local url="$1" | |
local dest="$2" | |
printf "Downloading file from %s...\n" "$url" | |
curl -sL "$url" -o "$dest" | |
if [ $? -ne 0 ]; then | |
printf "Failed to download file from %s\n" "$url" | |
exit 1 | |
fi | |
} | |
check_master() { | |
# Fetch the latest Zig version | |
# The latest version of zig is the default without any arguments | |
download_file $ZIG_DOWNLOAD_URL $ZIG_TMP_FILE | |
ZIG_VERSION="$(jq -r .master.version $ZIG_TMP_FILE)" | |
if [ $? -ne 0 ]; then | |
echo "Failed to parse Zig version info" | |
exit 1 | |
fi | |
} | |
check_file() { | |
# If FILENAME is set parse it to get the version | |
if [ -n "$FILENAME" ]; then | |
if [ -f "$FILENAME" ]; then | |
echo "Using file: $FILENAME" | |
ZIG_VERSION=$(cat "$FILENAME" | grep "const required_zig" | cut -d'=' -f2 | tr -d ' ";') | |
else | |
echo "File not found: $FILENAME" | |
exit 1 | |
fi | |
fi | |
} | |
check_install () { | |
if [ -d "$ZIG_DIR" ]; then | |
if [ "$( $ZIG_DIR/zig version )" == "$ZIG_VERSION" ]; then | |
echo "$ZIG_VERSION already installed." | |
exit 0 | |
else | |
remove_install | |
fi | |
fi | |
} | |
install_zig() { | |
# Download Zig | |
echo "Downloading Zig version $ZIG_VERSION..." | |
ZIG_URL="https://ziglang.org/builds/zig-${OS}-${ARCH}-${ZIG_VERSION}.tar.xz" | |
download_file $ZIG_URL $TMP_ZIG_TAR | |
# Extract Zig | |
echo "Extracting Zig..." | |
mkdir -p "$ZIG_DIR" | |
if [ $? -ne 0 ]; then | |
echo "Failed to create directory $ZIG_DIR" | |
exit 1 | |
fi | |
tar -xf "$TMP_ZIG_TAR" -C "$ZIG_DIR" --strip-components=1 | |
if [ $? -ne 0 ]; then | |
echo "Failed to extract Zig" | |
exit 1 | |
fi | |
# Add Zig to PATH | |
echo "Adding Zig to PATH..." | |
ln -sf "$ZIG_DIR/zig" "$ZIG_EXE_BIN" | |
if [ $? -ne 0 ]; then | |
echo "Failed to create symbolic link" | |
exit 1 | |
fi | |
} | |
remove_install () { | |
# Check if Zig is already installed and remove it | |
if [ -d "$ZIG_DIR" ]; then | |
echo "Removing existing Zig installation: $("$ZIG_DIR/zig" version)" | |
rm -rf "$ZIG_DIR" | |
fi | |
} | |
finish() { | |
result=$? | |
rm -f "$TMP_ZIG_TAR" | |
rm -f "$ZIG_TMP_FILE" | |
exit ${result} | |
} | |
trap finish EXIT ERR | |
function usage () { | |
echo "Usage: $0 [options] <file_name>" | |
echo "Options:" | |
echo " -b A directory in your PATH to link the Zig binary" | |
echo " -v Specific version of Zig" | |
echo " -f Use a different file name" | |
echo " -u Uninstall Zig" | |
echo " -h This help" | |
} | |
# Parse command line arguments | |
while getopts ":b:v:f:uh" opt; do | |
case $opt in | |
b) BIN_DIR="$OPTARG";; | |
v) ZIG_VERSION="$OPTARG";; | |
f) FILENAME="$(realpath "$OPTARG")";; | |
u) UNINSTALL="true";; | |
h) usage; exit 0;; | |
\?) echo "Invalid flag: -$OPTARG"; usage; exit 1;; | |
esac | |
done | |
if [ "$UNINSTALL" == "true" ]; then | |
echo "Uninstalling zig" | |
rm -f "$ZIG_EXE_BIN" | |
remove_install | |
exit 0 | |
fi | |
# Check if we need to get the version from a file | |
if [ -z "$ZIG_VERSION" ] && [ -n "$FILENAME" ]; then | |
check_file | |
fi | |
check_os_and_arch | |
# Otherwise Check if we need to get the version from the master branch | |
if [ -z "$ZIG_VERSION" ]; then | |
check_master | |
fi | |
# Check if we've already got the version | |
check_install | |
# Download Zig | |
install_zig | |
echo "Zig installation complete." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment