Skip to content

Improve Installation Script Robustness and Compliance #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
329 changes: 159 additions & 170 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,200 +1,189 @@
#!/usr/bin/env bash
set -euo pipefail

# --- Helper Functions ---
error() { echo -e "[ERROR] $*" >&2; exit 1; }
info() { echo -e "[INFO] $*"; }
info_bold() { echo -e "\e[1m$*\e[0m"; }

# --- Dependency Check ---
for cmd in bun curl tar uname mkdir mv rm; do
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is contradictory with line 18 no? you check bun here but will never reach line 18 (installing bun)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My fault. Fixing it.

command -v "$cmd" >/dev/null 2>&1 || error "The command '$cmd' is required but not installed."
done

# --- Initial Definitions ---
VERSION="v0.6.1"

if ! bun &>/dev/null; then
curl -fsSL https://bun.sh/install | bash
# Install Bun if not available
if ! command -v bun &>/dev/null; then
info "Bun not found. Installing Bun..."
curl -fsSL https://bun.sh/install | bash || error "Failed to install Bun."
fi

# Detect system architecture
arch=$(uname -ms)

case $arch in
'Darwin x86_64')
target=x86_64-apple-darwin
;;
'Darwin arm64')
target=aarch64-apple-darwin
;;
'Linux aarch64' | 'Linux arm64')
target=aarch64-unknown-linux-gnu
;;
'Linux x86_64' | *)
target=x86_64-unknown-linux-gnu
;;
case "$arch" in
"Darwin x86_64")
target="x86_64-apple-darwin"
;;
"Darwin arm64")
target="aarch64-apple-darwin"
;;
"Linux aarch64" | "Linux arm64")
target="aarch64-unknown-linux-gnu"
;;
"Linux x86_64" | *)
target="x86_64-unknown-linux-gnu"
;;
esac

GITHUB=${GITHUB-"https://github.com"}

# Define GitHub repository variables
GITHUB="${GITHUB:-https://github.com}"
github_repo="$GITHUB/owenizedd/bum"

bum_folder_name="bum-$VERSION-$target"

bum_uri=$github_repo/releases/download/$VERSION/bum-$VERSION-"$target".tar.gz

install_env=BUM_INSTALL
bin_env=\$$install_env/bin

install_dir=${!install_env:-$HOME/.bum}
bin_dir=$install_dir/bin
exe=$bin_dir/bum
exe_compressed=$bin_dir/bum.tar.gz

if [[ ! -d $bin_dir ]]; then
mkdir -p "$bin_dir" ||
error "Failed to create install directory \"$bin_dir\""
bum_uri="$github_repo/releases/download/$VERSION/bum-$VERSION-$target.tar.gz"

# Installation variables
install_env="BUM_INSTALL"
bin_env="\$$install_env/bin"
install_dir="${!install_env:-$HOME/.bum}"
bin_dir="$install_dir/bin"
exe="$bin_dir/bum"
exe_compressed="$bin_dir/bum.tar.gz"

# Create installation directory if needed
if [[ ! -d "$bin_dir" ]]; then
mkdir -p "$bin_dir" || error "Failed to create directory \"$bin_dir\""
fi

curl --fail --location --progress-bar --output "$exe_compressed" "$bum_uri" ||
error "Failed to download bum from \"$bum_uri\""
# --- Download and Installation ---
info "Downloading bum from: $bum_uri"
curl --fail --location --progress-bar --output "$exe_compressed" "$bum_uri" \
|| error "Failed to download bum from \"$bum_uri\""

tar -xvf "$exe_compressed" || error "Failed on decompress the executable"
# Extract the tarball to a temporary directory
temp_dir=$(mktemp -d)
trap 'rm -rf "${temp_dir:?}"' EXIT

tar -xvf "$exe_compressed" -C "$temp_dir" \
|| error "Failed to extract the archive."
rm "$exe_compressed"

mv "$bum_folder_name/bum" $exe

rm -r $bum_folder_name
# Move the executable to the destination directory
if [[ -f "$temp_dir/$bum_folder_name/bum" ]]; then
mv "$temp_dir/$bum_folder_name/bum" "$exe" \
|| error "Failed to move the executable to \"$exe\""
else
error "Executable not found in the temporary directory."
fi

# Remove the extracted folder; use parameter expansion guards to avoid dangerous expansion
rm -rf "${temp_dir:?}/${bum_folder_name:?}"
mkdir -p "$install_dir/bun-versions"

chmod +x "$exe" ||
error 'Failed to set permissions on bum executable'
chmod +x "$exe" || error "Failed to set execute permission on bum"

# Function to convert paths to use tilde notation when applicable
tildify() {
if [[ $1 = $HOME/* ]]; then
local replacement=\~/

echo "${1/$HOME\//$replacement}"
else
echo "$1"
fi
if [[ "$1" == "$HOME/"* ]]; then
echo "~/${1#"$HOME"/}"
else
echo "$1"
fi
}

echo "bum was installed successfully to "$exe""
info "bum was successfully installed to \"$exe\""

# --- Environment Configuration ---
refresh_command=''

tilde_bin_dir="$bin_dir"
quoted_install_dir=\"${install_dir//\"/\\\"}\"

if [[ $quoted_install_dir = \"$HOME/* ]]; then
quoted_install_dir=${quoted_install_dir/$HOME\//\$HOME/}
tilde_bin_dir="$(tildify "$bin_dir")"
quoted_install_dir="\"${install_dir//\"/\\\"}\""
if [[ "$quoted_install_dir" == "\"$HOME/"* ]]; then
quoted_install_dir=${quoted_install_dir/"$HOME"/"\$HOME"}
fi

echo

case $(basename "$SHELL") in
fish)
commands=(
"set --export $install_env $quoted_install_dir"
"set --export PATH $bin_env \$PATH"
)

fish_config=$HOME/.config/fish/config.fish
tilde_fish_config=$(tildify "$fish_config")

if [[ -w $fish_config ]]; then
{
echo -e '\n# bum'

for command in "${commands[@]}"; do
echo "$command"
done
} >>"$fish_config"

info "Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_fish_config\""

refresh_command="source $tilde_fish_config"
else
echo "Manually add the directory to $tilde_fish_config (or similar):"

for command in "${commands[@]}"; do
info_bold " $command"
done
fi
;;
zsh)

commands=(
"export $install_env=$quoted_install_dir"
"export PATH=\"$bin_env:\$PATH\""
)

zsh_config=$HOME/.zshrc
tilde_zsh_config=$(tildify "$zsh_config")

if [[ -w $zsh_config ]]; then
{
echo -e '\n# bum'

for command in "${commands[@]}"; do
echo "$command"
done
} >>"$zsh_config"

refresh_command="exec $SHELL"
else
echo "Manually add the directory to $tilde_zsh_config (or similar):"

for command in "${commands[@]}"; do
info_bold " $command"
done
fi
;;
bash)

commands=(
"export $install_env=$quoted_install_dir"
"export PATH=$bin_env:\$PATH"
)

bash_configs=(
"$HOME/.bashrc"
"$HOME/.bash_profile"
)

if [[ ${XDG_CONFIG_HOME:-} ]]; then
bash_configs+=(
"$XDG_CONFIG_HOME/.bash_profile"
"$XDG_CONFIG_HOME/.bashrc"
"$XDG_CONFIG_HOME/bash_profile"
"$XDG_CONFIG_HOME/bashrc"
)
fi

set_manually=true
for bash_config in "${bash_configs[@]}"; do
tilde_bash_config=$(tildify "$bash_config")

if [[ -w $bash_config ]]; then
{
echo -e '\n# bum'

for command in "${commands[@]}"; do
echo "$command"
done
} >>"$bash_config"

info "Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_bash_config\""

refresh_command="source $bash_config"
set_manually=false
break
fi
done

if [[ $set_manually = true ]]; then
echo "Manually add the directory to $tilde_bash_config (or similar):"

for command in "${commands[@]}"; do
info_bold " $command"
done
fi
;;
*)
echo 'Manually add the directory to ~/.bashrc (or similar):'
info_bold " export $install_env=$quoted_install_dir"
info_bold " export PATH=\"$bin_env:\$PATH\""
;;
echo ""

# Function to add commands to a shell configuration file
add_commands_to_file() {
local file="$1"
shift
local commands=("$@")
if [[ -w "$file" ]]; then
{
echo -e "\n# bum"
for command in "${commands[@]}"; do
echo "$command"
done
} >> "$file"
info "Added \"$tilde_bin_dir\" to PATH in \"$(tildify "$file")\""
refresh_command="source $(tildify "$file")"
return 0
else
info "Please add the following lines manually to $(tildify "$file"):"
for command in "${commands[@]}"; do
info_bold " $command"
done
return 1
fi
}

case "$(basename "$SHELL")" in
fish)
commands=(
"set --export $install_env $quoted_install_dir"
"set --export PATH $bin_env \$PATH"
)
fish_config="$HOME/.config/fish/config.fish"
add_commands_to_file "$fish_config" "${commands[@]}"
;;
zsh)
commands=(
"export $install_env=$quoted_install_dir"
"export PATH=\"$bin_env:\$PATH\""
)
zsh_config="$HOME/.zshrc"
add_commands_to_file "$zsh_config" "${commands[@]}"
;;
bash)
commands=(
"export $install_env=$quoted_install_dir"
"export PATH=$bin_env:\$PATH"
)
bash_configs=(
"$HOME/.bashrc"
"$HOME/.bash_profile"
)
if [[ -n "${XDG_CONFIG_HOME:-}" ]]; then
bash_configs+=(
"$XDG_CONFIG_HOME/.bash_profile"
"$XDG_CONFIG_HOME/.bashrc"
"$XDG_CONFIG_HOME/bash_profile"
"$XDG_CONFIG_HOME/bashrc"
)
fi
set_manually=true
for bash_config in "${bash_configs[@]}"; do
if add_commands_to_file "$bash_config" "${commands[@]}"; then
set_manually=false
break
fi
done
if $set_manually; then
info "Please add the following lines manually to $(tildify "${bash_configs[0]}") (or similar):"
for command in "${commands[@]}"; do
info_bold " $command"
done
fi
;;
*)
echo "Please add the following lines manually to your shell configuration file (e.g., ~/.bashrc):"
info_bold " export $install_env=$quoted_install_dir"
info_bold " export PATH=\"$bin_env:\$PATH\""
;;
esac

if [[ -n "$refresh_command" ]]; then
info "To update your shell environment, run:"
info_bold " $refresh_command"
fi