Add Linux self-extracting archives (SFX) for Bun installation

This commit is contained in:
Cursor Agent
2025-06-05 22:13:12 +00:00
parent 26f7fcbbb0
commit f7b221b3bd
4 changed files with 734 additions and 12 deletions

View File

@@ -49,7 +49,7 @@ on:
type: boolean
default: false
use-sfx:
description: Should macOS SFX archives be generated?
description: Should self-extracting archives be generated?
type: boolean
default: false
@@ -440,6 +440,129 @@ jobs:
--clobber \
--repo "${{ github.repository }}"
linux-sfx:
name: Generate Linux SFX Archives
runs-on: ubuntu-latest
needs: sign
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.use-sfx == 'true') }}
permissions:
contents: write
strategy:
matrix:
include:
- arch: x64
zip_name: bun-linux-x64
display: x64
- arch: x64
zip_name: bun-linux-x64-baseline
display: x64-baseline
baseline: true
- arch: aarch64
zip_name: bun-linux-aarch64
display: aarch64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Environment
run: |
echo "Creating working directory..."
mkdir -p sfx-build
- name: Download Bun Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd sfx-build
# Download the zip file from GitHub releases
echo "Downloading ${{ matrix.zip_name }}.zip..."
if [[ "${{ env.BUN_VERSION }}" == "canary" ]]; then
DOWNLOAD_URL="https://github.com/oven-sh/bun/releases/download/canary/${{ matrix.zip_name }}.zip"
else
DOWNLOAD_URL="https://github.com/oven-sh/bun/releases/download/${{ env.BUN_VERSION }}/${{ matrix.zip_name }}.zip"
fi
curl -L -o "${{ matrix.zip_name }}.zip" "$DOWNLOAD_URL"
# Extract the zip file
unzip -q "${{ matrix.zip_name }}.zip"
# Find the bun executable
BUN_EXEC=$(find . -name "bun" -type f | head -n 1)
if [[ -z "$BUN_EXEC" ]]; then
echo "Error: Could not find bun executable in the archive"
exit 1
fi
# Move it to a known location
mv "$BUN_EXEC" "./bun"
chmod +x ./bun
# Clean up
rm -rf bun-linux-*/ ${{ matrix.zip_name }}.zip
- name: Create Self-Extracting Archive
run: |
cd sfx-build
# Create the self-extracting script header
cat > extract-header.sh << 'SCRIPT_EOF'
#!/bin/sh
set -e
DEFAULT_INSTALL_DIR="$HOME/.bun/bin"
INSTALL_DIR="${BUN_INSTALL_DIR:-$DEFAULT_INSTALL_DIR}"
ARCH="$(uname -m)"
EXPECTED_ARCH="ARCH_PLACEHOLDER"
EXPECTED_DISPLAY="DISPLAY_PLACEHOLDER"
case "$ARCH" in
x86_64) ARCH_NORM="x64" ;;
aarch64|arm64) ARCH_NORM="aarch64" ;;
*) ARCH_NORM="$ARCH" ;;
esac
ARCH_MISMATCH=0
case "$EXPECTED_ARCH" in
x64) [ "$ARCH_NORM" != "x64" ] && ARCH_MISMATCH=1 ;;
aarch64) [ "$ARCH_NORM" != "aarch64" ] && ARCH_MISMATCH=1 ;;
esac
if [ "$ARCH_MISMATCH" = "1" ]; then
echo "Warning: This installer is for $EXPECTED_DISPLAY but you're running on $ARCH"
fi
mkdir -p "$INSTALL_DIR"
ARCHIVE_LINE=$(awk '/^__ARCHIVE_BELOW__/ { print NR + 1; exit }' "$0")
echo "Extracting Bun to $INSTALL_DIR..."
tail -n +"$ARCHIVE_LINE" "$0" | base64 -d | tar -xzf - -C "$INSTALL_DIR"
chmod +x "$INSTALL_DIR/bun"
BUN_VERSION=$("$INSTALL_DIR/bun" --version 2>/dev/null || echo "unknown")
echo "Bun $BUN_VERSION has been installed to $INSTALL_DIR/bun"
echo "Run 'export PATH=\"\$PATH:$INSTALL_DIR\"' to add it to your PATH"
exit 0
__ARCHIVE_BELOW__
SCRIPT_EOF
# Replace placeholders
sed -i "s/ARCH_PLACEHOLDER/${{ matrix.arch }}/g" extract-header.sh
sed -i "s/DISPLAY_PLACEHOLDER/${{ matrix.display }}/g" extract-header.sh
# Create the SFX archive
tar -czf bun.tar.gz bun
base64 < bun.tar.gz > bun.tar.gz.b64
cat extract-header.sh bun.tar.gz.b64 > "${{ matrix.zip_name }}-sfx.sh"
chmod +x "${{ matrix.zip_name }}-sfx.sh"
# Generate checksum
sha256sum "${{ matrix.zip_name }}-sfx.sh" > "${{ matrix.zip_name }}-sfx.sh.sha256"
- name: Upload to Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd sfx-build
# Upload the SFX to the release
gh release upload "${{ env.BUN_VERSION }}" \
"${{ matrix.zip_name }}-sfx.sh" \
"${{ matrix.zip_name }}-sfx.sh.sha256" \
--clobber \
--repo "${{ github.repository }}"
notify-sentry:
name: Notify Sentry
runs-on: ubuntu-latest

455
.github/workflows/sfx-linux.yml vendored Normal file
View File

@@ -0,0 +1,455 @@
name: Generate Linux SFX Archives
concurrency: sfx-linux
on:
release:
types:
- published
workflow_dispatch:
inputs:
tag:
description: 'Release tag (e.g., "bun-v1.0.2", "canary")'
required: true
default: "canary"
upload-to-release:
description: "Upload SFX files to the release?"
type: boolean
default: false
env:
BUN_VERSION: ${{ github.event.inputs.tag || github.event.release.tag_name || 'canary' }}
jobs:
create-linux-sfx:
name: Create Linux Self-Extracting Archives
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'oven-sh' }}
permissions:
contents: write
strategy:
matrix:
include:
- arch: x64
zip_name: bun-linux-x64
display: x64
- arch: x64
zip_name: bun-linux-x64-baseline
display: x64-baseline
baseline: true
- arch: aarch64
zip_name: bun-linux-aarch64
display: aarch64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Environment
run: |
echo "Creating working directory..."
mkdir -p sfx-build
cd sfx-build
- name: Download Bun Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd sfx-build
# Download the zip file from GitHub releases
echo "Downloading ${{ matrix.zip_name }}.zip..."
if [[ "${{ env.BUN_VERSION }}" == "canary" ]]; then
DOWNLOAD_URL="https://github.com/oven-sh/bun/releases/download/canary/${{ matrix.zip_name }}.zip"
else
DOWNLOAD_URL="https://github.com/oven-sh/bun/releases/download/${{ env.BUN_VERSION }}/${{ matrix.zip_name }}.zip"
fi
curl -L -o "${{ matrix.zip_name }}.zip" "$DOWNLOAD_URL"
# Extract the zip file using unzip (available on GitHub runners)
unzip -q "${{ matrix.zip_name }}.zip"
# Find the bun executable
BUN_EXEC=$(find . -name "bun" -type f | head -n 1)
if [[ -z "$BUN_EXEC" ]]; then
echo "Error: Could not find bun executable in the archive"
exit 1
fi
# Move it to a known location
mv "$BUN_EXEC" "./bun"
chmod +x ./bun
# Clean up
rm -rf bun-linux-*/ ${{ matrix.zip_name }}.zip
- name: Create SFX Script
run: |
cd sfx-build
# Create the self-extracting script
cat > extract-header.sh << 'SCRIPT_EOF'
#!/bin/sh
# Bun Self-Extracting Archive for Linux
# This is a self-extracting archive. Run it to install Bun.
# No external dependencies required (no unzip needed!)
set -e
# Default installation directory
DEFAULT_INSTALL_DIR="$HOME/.bun/bin"
INSTALL_DIR="${BUN_INSTALL_DIR:-$DEFAULT_INSTALL_DIR}"
# ANSI color codes (only if terminal supports it)
if [ -t 1 ] && [ -n "${TERM-}" ] && [ "${TERM-}" != "dumb" ]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
else
RED=''
GREEN=''
YELLOW=''
NC=''
fi
error() {
printf "${RED}error: %s${NC}\n" "$1" >&2
exit 1
}
info() {
printf "${GREEN}%s${NC}\n" "$1"
}
warn() {
printf "${YELLOW}warning: %s${NC}\n" "$1"
}
# Check if running on Linux
if [ "$(uname -s)" != "Linux" ]; then
error "This installer is for Linux only. Please download the correct version for your platform."
fi
# Check architecture
ARCH="$(uname -m)"
EXPECTED_ARCH="ARCH_PLACEHOLDER"
EXPECTED_DISPLAY="DISPLAY_PLACEHOLDER"
case "$ARCH" in
x86_64)
ARCH_NORM="x64"
;;
aarch64|arm64)
ARCH_NORM="aarch64"
;;
*)
ARCH_NORM="$ARCH"
;;
esac
# Check if architecture matches (allow x64 baseline on x64)
ARCH_MISMATCH=0
case "$EXPECTED_ARCH" in
x64)
if [ "$ARCH_NORM" != "x64" ]; then
ARCH_MISMATCH=1
fi
;;
aarch64)
if [ "$ARCH_NORM" != "aarch64" ]; then
ARCH_MISMATCH=1
fi
;;
esac
if [ "$ARCH_MISMATCH" = "1" ]; then
warn "This installer is for $EXPECTED_DISPLAY but you're running on $ARCH"
if [ -t 0 ]; then
printf "Continue anyway? [y/N] "
read -r REPLY
case "$REPLY" in
[Yy]*)
;;
*)
exit 1
;;
esac
else
error "Architecture mismatch and no TTY to confirm"
fi
fi
# Create installation directory
mkdir -p "$INSTALL_DIR" || error "Failed to create installation directory: $INSTALL_DIR"
# Find where the payload starts
ARCHIVE_MARKER="__ARCHIVE_BELOW__"
ARCHIVE_LINE=$(awk "/$ARCHIVE_MARKER/ { print NR + 1; exit }" "$0")
if [ -z "$ARCHIVE_LINE" ]; then
error "Could not find archive marker"
fi
# Extract the payload
info "Extracting Bun to $INSTALL_DIR..."
# Use tail to skip the script part, then decode and extract
# We use base64 to ensure binary safety across all systems
if ! tail -n +"$ARCHIVE_LINE" "$0" | base64 -d | tar -xzf - -C "$INSTALL_DIR" 2>/dev/null; then
error "Failed to extract Bun. The archive may be corrupted."
fi
# Make it executable
chmod +x "$INSTALL_DIR/bun" || error "Failed to make bun executable"
# Verify installation
if [ -x "$INSTALL_DIR/bun" ]; then
BUN_VERSION=$("$INSTALL_DIR/bun" --version 2>/dev/null || echo "unknown")
info "✓ Bun $BUN_VERSION has been installed to $INSTALL_DIR/bun"
else
error "Installation verification failed"
fi
# Check if bun is in PATH
if ! echo "$PATH" | grep -q "$INSTALL_DIR"; then
info ""
info "To get started, add Bun to your PATH:"
info " export PATH=\"\$PATH:$INSTALL_DIR\""
info ""
info "To make this permanent, add it to your shell configuration file:"
case "${SHELL##*/}" in
bash)
info " echo 'export PATH=\"\$PATH:$INSTALL_DIR\"' >> ~/.bashrc"
;;
zsh)
info " echo 'export PATH=\"\$PATH:$INSTALL_DIR\"' >> ~/.zshrc"
;;
fish)
info " echo 'set -gx PATH \$PATH $INSTALL_DIR' >> ~/.config/fish/config.fish"
;;
*)
info " echo 'export PATH=\"\$PATH:$INSTALL_DIR\"' >> ~/.profile"
;;
esac
fi
exit 0
# DO NOT REMOVE THE FOLLOWING LINE
__ARCHIVE_BELOW__
SCRIPT_EOF
# Replace placeholders
sed -i "s/ARCH_PLACEHOLDER/${{ matrix.arch }}/g" extract-header.sh
sed -i "s/DISPLAY_PLACEHOLDER/${{ matrix.display }}/g" extract-header.sh
- name: Create Self-Extracting Archive
run: |
cd sfx-build
# Create a tar.gz of the bun executable
tar -czf bun.tar.gz bun
# Encode it as base64 (for binary safety)
base64 < bun.tar.gz > bun.tar.gz.b64
# Combine header and payload
cat extract-header.sh bun.tar.gz.b64 > "${{ matrix.zip_name }}-sfx.sh"
# Make it executable
chmod +x "${{ matrix.zip_name }}-sfx.sh"
# Test the SFX
echo "Testing self-extraction..."
TEST_DIR="$(mktemp -d)"
BUN_INSTALL_DIR="$TEST_DIR" ./${{ matrix.zip_name }}-sfx.sh
if [ -x "$TEST_DIR/bun" ]; then
echo "✓ Self-extraction test passed"
"$TEST_DIR/bun" --version
rm -rf "$TEST_DIR"
else
echo "✗ Self-extraction test failed"
exit 1
fi
- name: Create Quick Install Script
run: |
cd sfx-build
# Also create a simple download-and-run script
cat > "${{ matrix.zip_name }}-install.sh" << 'INSTALLER_EOF'
#!/bin/sh
# Quick installer script for Bun on Linux
set -e
VERSION="VERSION_PLACEHOLDER"
ARCHIVE_NAME="ARCHIVE_PLACEHOLDER"
echo "Downloading Bun $VERSION for Linux..."
if [ "$VERSION" = "canary" ]; then
URL="https://github.com/oven-sh/bun/releases/download/canary/${ARCHIVE_NAME}-sfx.sh"
else
URL="https://github.com/oven-sh/bun/releases/download/$VERSION/${ARCHIVE_NAME}-sfx.sh"
fi
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$URL" | sh
elif command -v wget >/dev/null 2>&1; then
wget -qO- "$URL" | sh
else
echo "Error: Neither curl nor wget found. Please install one of them."
exit 1
fi
INSTALLER_EOF
# Replace placeholders
sed -i "s/VERSION_PLACEHOLDER/${{ env.BUN_VERSION }}/g" "${{ matrix.zip_name }}-install.sh"
sed -i "s/ARCHIVE_PLACEHOLDER/${{ matrix.zip_name }}/g" "${{ matrix.zip_name }}-install.sh"
chmod +x "${{ matrix.zip_name }}-install.sh"
- name: Generate Checksums
run: |
cd sfx-build
# Generate SHA256 checksums
sha256sum "${{ matrix.zip_name }}-sfx.sh" > "${{ matrix.zip_name }}-sfx.sh.sha256"
sha256sum "${{ matrix.zip_name }}-install.sh" > "${{ matrix.zip_name }}-install.sh.sha256"
echo "Generated files:"
ls -la *.sh *.sha256
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.zip_name }}-sfx
path: |
sfx-build/${{ matrix.zip_name }}-sfx.sh
sfx-build/${{ matrix.zip_name }}-sfx.sh.sha256
sfx-build/${{ matrix.zip_name }}-install.sh
sfx-build/${{ matrix.zip_name }}-install.sh.sha256
- name: Upload to Release
if: ${{ (github.event_name == 'release' || github.event.inputs.upload-to-release == 'true') && env.BUN_VERSION != 'canary' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd sfx-build
# Upload the SFX and installer scripts to the release
gh release upload "${{ env.BUN_VERSION }}" \
"${{ matrix.zip_name }}-sfx.sh" \
"${{ matrix.zip_name }}-sfx.sh.sha256" \
"${{ matrix.zip_name }}-install.sh" \
"${{ matrix.zip_name }}-install.sh.sha256" \
--clobber \
--repo "${{ github.repository }}"
create-universal-linux-installer:
name: Create Universal Linux Installer
runs-on: ubuntu-latest
needs: create-linux-sfx
if: ${{ github.repository_owner == 'oven-sh' }}
permissions:
contents: write
steps:
- name: Download SFX Artifacts
uses: actions/download-artifact@v4
with:
pattern: bun-linux-*-sfx
merge-multiple: true
path: sfx-files
- name: Create Universal Installer
run: |
cd sfx-files
# Create a universal installer that detects architecture
cat > bun-linux-install.sh << 'UNIVERSAL_EOF'
#!/bin/sh
# Universal Bun installer for Linux (detects architecture automatically)
set -e
VERSION="VERSION_PLACEHOLDER"
# Detect architecture
ARCH="$(uname -m)"
case "$ARCH" in
x86_64)
# Check CPU features for baseline support
if [ -f /proc/cpuinfo ]; then
# Check for AVX2 support (non-baseline requirement)
if grep -q "avx2" /proc/cpuinfo 2>/dev/null; then
ARCHIVE_NAME="bun-linux-x64"
echo "Detected: x64 (with AVX2 support)"
else
ARCHIVE_NAME="bun-linux-x64-baseline"
echo "Detected: x64 (baseline - no AVX2)"
fi
else
# Default to baseline if we can't detect
ARCHIVE_NAME="bun-linux-x64-baseline"
echo "Detected: x64 (defaulting to baseline)"
fi
;;
aarch64|arm64)
ARCHIVE_NAME="bun-linux-aarch64"
echo "Detected: ARM64/AArch64"
;;
*)
echo "Error: Unsupported architecture: $ARCH"
echo "Bun supports x64 and aarch64 on Linux"
exit 1
;;
esac
echo "Downloading Bun $VERSION for Linux..."
if [ "$VERSION" = "canary" ]; then
URL="https://github.com/oven-sh/bun/releases/download/canary/${ARCHIVE_NAME}-sfx.sh"
else
URL="https://github.com/oven-sh/bun/releases/download/$VERSION/${ARCHIVE_NAME}-sfx.sh"
fi
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$URL" | sh
elif command -v wget >/dev/null 2>&1; then
wget -qO- "$URL" | sh
else
echo "Error: Neither curl nor wget found. Please install one of them."
exit 1
fi
UNIVERSAL_EOF
# Replace version placeholder
sed -i "s/VERSION_PLACEHOLDER/${{ env.BUN_VERSION }}/g" bun-linux-install.sh
chmod +x bun-linux-install.sh
# Generate checksum
sha256sum bun-linux-install.sh > bun-linux-install.sh.sha256
- name: Upload Universal Installer
uses: actions/upload-artifact@v4
with:
name: bun-linux-universal-sfx
path: |
sfx-files/bun-linux-install.sh
sfx-files/bun-linux-install.sh.sha256
- name: Upload to Release
if: ${{ (github.event_name == 'release' || github.event.inputs.upload-to-release == 'true') && env.BUN_VERSION != 'canary' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd sfx-files
gh release upload "${{ env.BUN_VERSION }}" \
"bun-linux-install.sh" \
"bun-linux-install.sh.sha256" \
--clobber \
--repo "${{ github.repository }}"

102
docs/install/sfx.md Normal file
View File

@@ -0,0 +1,102 @@
# Self-Extracting Archives (SFX) for Bun
Self-extracting archives provide a convenient way to install Bun without requiring external tools like `unzip`. These are shell scripts that contain the Bun binary embedded within them.
## Linux
### Quick Install
For automatic architecture detection:
```bash
curl -fsSL https://github.com/oven-sh/bun/releases/latest/download/bun-linux-install.sh | sh
```
### Manual Installation
Choose the appropriate version for your system:
**x64 (with AVX2 support):**
```bash
curl -fsSL https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64-sfx.sh | sh
```
**x64 (baseline - no AVX2):**
```bash
curl -fsSL https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64-baseline-sfx.sh | sh
```
**ARM64/AArch64:**
```bash
curl -fsSL https://github.com/oven-sh/bun/releases/latest/download/bun-linux-aarch64-sfx.sh | sh
```
### Download and Run Later
You can also download the SFX file and run it later:
```bash
# Download
curl -LO https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64-sfx.sh
# Make executable
chmod +x bun-linux-x64-sfx.sh
# Run
./bun-linux-x64-sfx.sh
```
### Custom Installation Directory
By default, Bun installs to `$HOME/.bun/bin`. You can override this:
```bash
BUN_INSTALL_DIR=/usr/local/bin ./bun-linux-x64-sfx.sh
```
## How It Works
The self-extracting archives are shell scripts with these components:
1. **Shell Script Header**: A POSIX-compliant shell script that:
- Checks system compatibility
- Creates the installation directory
- Extracts the embedded binary
- Sets proper permissions
- Provides PATH setup instructions
2. **Embedded Binary**: The Bun executable is:
- Compressed with gzip
- Encoded in base64 for text safety
- Appended to the shell script
3. **No External Dependencies**: Only uses standard POSIX tools:
- `sh` (POSIX shell)
- `tar`, `gzip` (for extraction)
- `base64` (for decoding)
- `awk`, `tail` (for payload extraction)
## Advantages
- **No `unzip` Required**: Works on minimal Linux systems
- **Single File**: Everything in one downloadable script
- **Secure**: Checksums provided for verification
- **Portable**: POSIX-compliant, works on most Linux distributions
- **Architecture Detection**: Universal installer automatically selects the right binary
## Verification
Always verify downloads using the provided checksums:
```bash
# Download checksum
curl -LO https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64-sfx.sh.sha256
# Verify
sha256sum -c bun-linux-x64-sfx.sh.sha256
```

View File

@@ -53,8 +53,18 @@ success() {
echo -e "${Green}$@ ${Color_Off}"
}
command -v unzip >/dev/null ||
error 'unzip is required to install bun'
# Check for unzip and offer SFX alternative if not available
use_sfx=0
if ! command -v unzip >/dev/null 2>&1; then
echo -e "${Dim}unzip is not available. Using self-extracting archive instead.${Color_Off}"
use_sfx=1
# Check for required tools for SFX
for tool in sh tar gzip base64 awk tail; do
command -v "$tool" >/dev/null 2>&1 ||
error "$tool is required for self-extracting archive installation"
done
fi
if [[ $# -gt 2 ]]; then
error 'Too many arguments, only 2 are allowed. The first can be a specific tag of bun to install. (e.g. "bun-v0.1.4") The second can be a build variant of bun to install. (e.g. "debug-info")'
@@ -140,19 +150,51 @@ if [[ ! -d $bin_dir ]]; then
error "Failed to create install directory \"$bin_dir\""
fi
curl --fail --location --progress-bar --output "$exe.zip" "$bun_uri" ||
error "Failed to download bun from \"$bun_uri\""
# Use SFX if unzip is not available
if [[ $use_sfx -eq 1 ]]; then
# Map target to SFX filename
sfx_name=""
case "$target" in
linux-x64) sfx_name="bun-linux-x64" ;;
linux-x64-baseline) sfx_name="bun-linux-x64-baseline" ;;
linux-aarch64) sfx_name="bun-linux-aarch64" ;;
linux-x64-musl) sfx_name="bun-linux-x64-musl" ;;
linux-x64-musl-baseline) sfx_name="bun-linux-x64-musl-baseline" ;;
linux-aarch64-musl) sfx_name="bun-linux-aarch64-musl" ;;
*) error "Self-extracting archives are not available for $target. Please install unzip." ;;
esac
if [[ $# = 0 ]]; then
sfx_uri=$github_repo/releases/latest/download/$sfx_name-sfx.sh
else
sfx_uri=$github_repo/releases/download/$1/$sfx_name-sfx.sh
fi
info "Downloading self-extracting archive..."
# Download and run the SFX with custom install directory
export BUN_INSTALL_DIR="$bin_dir"
curl --fail --location --progress-bar "$sfx_uri" | sh ||
error "Failed to download and run self-extracting archive from \"$sfx_uri\""
# The SFX installs directly to bin_dir, so we're done with extraction
exe=$bin_dir/bun
else
# Original unzip-based installation
curl --fail --location --progress-bar --output "$exe.zip" "$bun_uri" ||
error "Failed to download bun from \"$bun_uri\""
unzip -oqd "$bin_dir" "$exe.zip" ||
error 'Failed to extract bun'
unzip -oqd "$bin_dir" "$exe.zip" ||
error 'Failed to extract bun'
mv "$bin_dir/bun-$target/$exe_name" "$exe" ||
error 'Failed to move extracted bun to destination'
mv "$bin_dir/bun-$target/$exe_name" "$exe" ||
error 'Failed to move extracted bun to destination'
chmod +x "$exe" ||
error 'Failed to set permissions on bun executable'
chmod +x "$exe" ||
error 'Failed to set permissions on bun executable'
rm -r "$bin_dir/bun-$target" "$exe.zip"
rm -r "$bin_dir/bun-$target" "$exe.zip"
fi
tildify() {
if [[ $1 = $HOME/* ]]; then