mirror of
https://github.com/sortedcord/bootstrap.git
synced 2026-07-23 04:32:49 +05:30
merge
This commit is contained in:
@@ -2,21 +2,16 @@
|
||||
# Tool: agy
|
||||
# DisplayName: Antigravity
|
||||
# Description: Install Antigravity CLI
|
||||
# Strategy: binary
|
||||
#
|
||||
# Antigravity CLI Installer Script (Linux Only)
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Constants
|
||||
DOWNLOAD_BASE_URL="https://antigravity-cli-auto-updater-974169037036.us-central1.run.app"
|
||||
TARGET_DIR="$HOME/.local/bin"
|
||||
TARGET_DIR="$BOOTSTRAP_BIN"
|
||||
BINARY_PATH="$TARGET_DIR/agy"
|
||||
|
||||
install_agy() {
|
||||
@@ -55,19 +50,12 @@ install_agy() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# POSIX-compliant JSON parser (no jq dependencies)
|
||||
parse_json_key() {
|
||||
local payload="$1"
|
||||
local key="$2"
|
||||
echo "$payload" | sed -n 's/.*"'"$key"'"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p'
|
||||
}
|
||||
|
||||
local version
|
||||
local url
|
||||
local sha512
|
||||
version=$(parse_json_key "$manifest_json" "version")
|
||||
url=$(parse_json_key "$manifest_json" "url")
|
||||
sha512=$(parse_json_key "$manifest_json" "sha512")
|
||||
version=$(echo "$manifest_json" | jq -r '.version // empty')
|
||||
url=$(echo "$manifest_json" | jq -r '.url // empty')
|
||||
sha512=$(echo "$manifest_json" | jq -r '.sha512 // empty')
|
||||
|
||||
if [ -z "$url" ] || [ -z "$sha512" ]; then
|
||||
log_error "Failed to parse release manifest."
|
||||
@@ -134,16 +122,11 @@ install_agy() {
|
||||
track_file "$BINARY_PATH"
|
||||
|
||||
log_success "Antigravity CLI successfully installed to $BINARY_PATH."
|
||||
register_tool "agy" "binary" "" "github:sortedcord/agy"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "local-bin path"
|
||||
done
|
||||
|
||||
write_env_snippet "local-bin" 'export PATH="$HOME/.local/bin:$PATH"'
|
||||
}
|
||||
|
||||
run_handoff() {
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: asciicinema
|
||||
# DisplayName: asciicinema
|
||||
# Description: Install asciinema terminal recorder
|
||||
# Strategy: binary
|
||||
#
|
||||
# asciinema Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -21,12 +16,9 @@ cleanup() {
|
||||
trap cleanup EXIT
|
||||
|
||||
install_asciicinema() {
|
||||
local latest_tag=""
|
||||
if has_command curl; then
|
||||
log_info "Fetching latest asciinema version from GitHub..."
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/asciinema/asciinema/releases/latest \
|
||||
| grep '"tag_name":' | head -n1 \
|
||||
| sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
latest_tag=$(github_get_latest_release "asciinema/asciinema")
|
||||
fi
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
@@ -73,22 +65,21 @@ install_asciicinema() {
|
||||
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
local download_url="https://github.com/asciinema/asciinema/releases/download/${latest_tag}/asciinema-${asciinema_arch}"
|
||||
|
||||
log_info "Downloading asciinema ${latest_tag} for ${arch}..."
|
||||
download_file "$download_url" "$TMP_DIR/asciinema"
|
||||
github_download_asset "asciinema/asciinema" "$latest_tag" "asciinema-${asciinema_arch}" "$TMP_DIR/asciinema"
|
||||
|
||||
log_info "Installing asciinema to /usr/local/bin..."
|
||||
sudo cp "$TMP_DIR/asciinema" /usr/local/bin/asciinema
|
||||
sudo chmod +x /usr/local/bin/asciinema
|
||||
track_file "/usr/local/bin/asciinema"
|
||||
log_info "Installing asciinema to $BOOTSTRAP_BIN..."
|
||||
cp "$TMP_DIR/asciinema" "$BOOTSTRAP_BIN/asciinema"
|
||||
chmod +x "$BOOTSTRAP_BIN/asciinema"
|
||||
track_file "$BOOTSTRAP_BIN/asciinema"
|
||||
|
||||
# Create compatibility symlink matching the installer name spelling
|
||||
log_info "Creating compatibility symlink for asciicinema..."
|
||||
sudo ln -sf /usr/local/bin/asciinema /usr/local/bin/asciicinema
|
||||
ln -sf "$BOOTSTRAP_BIN/asciinema" /usr/local/bin/asciicinema
|
||||
track_file "/usr/local/bin/asciicinema"
|
||||
|
||||
log_success "asciinema ${latest_tag} installed."
|
||||
register_tool "asciicinema" "binary" "$latest_tag" "github:asciinema/asciinema"
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: bat
|
||||
# DisplayName: Bat
|
||||
# Description: Install Bat (alternative to cat) and configure alias
|
||||
# Strategy: binary
|
||||
#
|
||||
# Bat Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -21,69 +16,54 @@ cleanup() {
|
||||
trap cleanup EXIT
|
||||
|
||||
install_bat() {
|
||||
local distro
|
||||
distro=$(detect_distro)
|
||||
|
||||
if [ "$distro" = "arch" ]; then
|
||||
log_info "Arch Linux detected"
|
||||
log_info "Installing Bat..."
|
||||
pkg_install bat
|
||||
|
||||
elif [ "$distro" = "fedora" ]; then
|
||||
log_info "Fedora detected"
|
||||
log_info "Installing Bat..."
|
||||
pkg_install bat
|
||||
|
||||
elif [ "$distro" = "debian" ]; then
|
||||
log_info "Debian/Ubuntu detected"
|
||||
|
||||
pkg_install curl
|
||||
|
||||
log_info "Fetching latest Bat version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/sharkdp/bat/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.26.1"
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to: $latest_tag"
|
||||
else
|
||||
log_info "Latest Bat version found: $latest_tag"
|
||||
if has_command bat; then
|
||||
if ! confirm "Bat is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping Bat installation."
|
||||
return
|
||||
fi
|
||||
|
||||
# Remove leading 'v' for file name version
|
||||
local version="${latest_tag#v}"
|
||||
|
||||
# Detect architecture mapping
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local deb_arch="amd64"
|
||||
if [ "$arch" = "arm64" ]; then
|
||||
deb_arch="arm64"
|
||||
fi
|
||||
|
||||
local deb_url="https://github.com/sharkdp/bat/releases/download/${latest_tag}/bat_${version}_${deb_arch}.deb"
|
||||
log_info "Downloading Bat from ${deb_url}..."
|
||||
download_file "$deb_url" "$TMP_DIR/bat.deb"
|
||||
|
||||
log_info "Installing Bat package..."
|
||||
sudo apt install -y "$TMP_DIR/bat.deb"
|
||||
add_rollback_cmd "sudo apt remove -y bat"
|
||||
|
||||
else
|
||||
log_error "Unsupported distribution."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local target=""
|
||||
case "$arch" in
|
||||
x86_64) target="x86_64-unknown-linux-gnu" ;;
|
||||
arm64) target="aarch64-unknown-linux-gnu" ;;
|
||||
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
log_info "Fetching latest Bat version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(github_get_latest_release "sharkdp/bat")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.26.1"
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to: $latest_tag"
|
||||
else
|
||||
log_info "Latest Bat version found: $latest_tag"
|
||||
fi
|
||||
|
||||
log_info "Downloading Bat ${latest_tag}..."
|
||||
local archive="$TMP_DIR/bat.tar.gz"
|
||||
github_download_asset "sharkdp/bat" "$latest_tag" "bat-${latest_tag}-${target}\.tar\.gz" "$archive"
|
||||
|
||||
log_info "Extracting Bat binary..."
|
||||
tar -xzf "$archive" -C "$TMP_DIR"
|
||||
|
||||
local extract_dir="$TMP_DIR/bat-${latest_tag}-${target}"
|
||||
|
||||
local target_dir="$BOOTSTRAP_BIN"
|
||||
mkdir -p "$target_dir"
|
||||
|
||||
log_info "Installing Bat to $target_dir/bat..."
|
||||
cp "$extract_dir/bat" "$target_dir/bat"
|
||||
chmod +x "$target_dir/bat"
|
||||
track_file "$target_dir/bat"
|
||||
|
||||
register_tool "bat" "binary" "$latest_tag" "github:sharkdp/bat"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "bat alias"
|
||||
done
|
||||
if [ -f "$HOME/.bash_aliases" ]; then
|
||||
remove_block "$HOME/.bash_aliases" "bat alias"
|
||||
fi
|
||||
|
||||
write_alias_snippet "bat" "alias cat='bat --paging=never -p'"
|
||||
}
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: docker
|
||||
# DisplayName: Docker
|
||||
# Description: Container runtime and orchestration platform
|
||||
# Strategy: system
|
||||
#
|
||||
# Docker Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
@@ -29,8 +24,9 @@ install_docker() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Use pkg_install for distro packages (it automatically handles rollback hooks for the packages!)
|
||||
# Use pkg_install for distro packages and explicitly register them for reference-counted rollback
|
||||
pkg_install "arch:docker|debian:docker.io|fedora:docker"
|
||||
registry_add_sys_deps "docker" "arch:docker|debian:docker.io|fedora:docker"
|
||||
|
||||
# Ensure docker group exists (some distros might not create it immediately)
|
||||
if ! getent group docker >/dev/null 2>&1; then
|
||||
@@ -58,6 +54,7 @@ install_docker() {
|
||||
sudo systemctl enable --now docker.service || true
|
||||
sudo systemctl enable --now containerd.service || true
|
||||
fi
|
||||
register_tool "docker" "system" "" "os-package-manager"
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -2,15 +2,8 @@
|
||||
# Tool: hyperfine
|
||||
# DisplayName: Hyperfine
|
||||
# Description: Command-line benchmarking tool
|
||||
# Strategy: binary
|
||||
#
|
||||
# Hyperfine Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -21,7 +14,7 @@ cleanup() {
|
||||
trap cleanup EXIT
|
||||
|
||||
install_hyperfine() {
|
||||
if has_command hyperfine || [ -f "$HOME/.local/bin/hyperfine" ]; then
|
||||
if has_command hyperfine; then
|
||||
if ! confirm "Hyperfine is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping Hyperfine installation."
|
||||
return
|
||||
@@ -33,12 +26,6 @@ install_hyperfine() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure curl is installed
|
||||
if ! has_command curl; then
|
||||
log_info "curl not found. Installing curl..."
|
||||
pkg_install curl
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
local raw_arch
|
||||
raw_arch=$(detect_arch)
|
||||
@@ -51,21 +38,17 @@ install_hyperfine() {
|
||||
|
||||
log_info "Fetching latest Hyperfine version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/sharkdp/hyperfine/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
latest_tag=$(github_get_latest_release "sharkdp/hyperfine")
|
||||
|
||||
local download_url
|
||||
if [ -n "$latest_tag" ]; then
|
||||
log_info "Latest Hyperfine version found: $latest_tag"
|
||||
download_url="https://github.com/sharkdp/hyperfine/releases/download/${latest_tag}/hyperfine-${latest_tag}-${arch}-unknown-linux-gnu.tar.gz"
|
||||
else
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v1.20.0"
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to: $latest_tag"
|
||||
download_url="https://github.com/sharkdp/hyperfine/releases/download/${latest_tag}/hyperfine-${latest_tag}-${arch}-unknown-linux-gnu.tar.gz"
|
||||
else
|
||||
log_info "Latest Hyperfine version found: $latest_tag"
|
||||
fi
|
||||
|
||||
log_info "Downloading Hyperfine from ${download_url}..."
|
||||
local archive="$TMP_DIR/hyperfine.tar.gz"
|
||||
download_file "$download_url" "$archive"
|
||||
github_download_asset "sharkdp/hyperfine" "$latest_tag" "hyperfine-${latest_tag}-${arch}-unknown-linux-gnu.tar.gz" "$archive"
|
||||
|
||||
# Extract the archive
|
||||
log_info "Extracting Hyperfine archive..."
|
||||
@@ -73,7 +56,7 @@ install_hyperfine() {
|
||||
|
||||
local extract_dir="$TMP_DIR/hyperfine-${latest_tag}-${arch}-unknown-linux-gnu"
|
||||
if [ ! -d "$extract_dir" ]; then
|
||||
# Handle case where directory name might differ (e.g. without leading v in directory name or tag)
|
||||
# Handle case where directory name might differ
|
||||
extract_dir=$(find "$TMP_DIR" -maxdepth 1 -type d -name "hyperfine-*" | head -n1)
|
||||
fi
|
||||
|
||||
@@ -82,8 +65,8 @@ install_hyperfine() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install binary to ~/.local/bin
|
||||
local target_dir="$HOME/.local/bin"
|
||||
# Install binary to $BOOTSTRAP_BIN
|
||||
local target_dir="$BOOTSTRAP_BIN"
|
||||
mkdir -p "$target_dir"
|
||||
log_info "Installing Hyperfine to $target_dir/hyperfine..."
|
||||
cp "$extract_dir/hyperfine" "$target_dir/hyperfine"
|
||||
@@ -106,27 +89,15 @@ install_hyperfine() {
|
||||
comp_content=$(cat "$extract_dir/autocomplete/hyperfine.bash")
|
||||
write_completion_snippet "hyperfine" "$comp_content"
|
||||
fi
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Add ~/.local/bin to PATH for the current process
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "local-bin path"
|
||||
done
|
||||
|
||||
write_env_snippet "local-bin" 'export PATH="$HOME/.local/bin:$PATH"'
|
||||
register_tool "hyperfine" "binary" "$latest_tag" "github:sharkdp/hyperfine"
|
||||
}
|
||||
|
||||
main() {
|
||||
install_hyperfine
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
log_success "Hyperfine installation and configuration complete."
|
||||
log_success "Hyperfine installation complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: lazygit
|
||||
# DisplayName: lazygit
|
||||
# Description: Simple terminal UI for git commands
|
||||
# Strategy: binary
|
||||
#
|
||||
# lazygit Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
@@ -30,11 +25,7 @@ install_lazygit() {
|
||||
fi
|
||||
|
||||
local latest_tag=""
|
||||
if has_command curl; then
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/jesseduffield/lazygit/releases/latest \
|
||||
| grep '"tag_name":' | head -n1 \
|
||||
| sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
fi
|
||||
latest_tag=$(github_get_latest_release "jesseduffield/lazygit")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.62.2" # fallback
|
||||
@@ -43,14 +34,13 @@ install_lazygit() {
|
||||
|
||||
local version="${latest_tag#v}"
|
||||
|
||||
local arch=$(detect_arch)
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local arch_str="x86_64"
|
||||
if [ "$arch" = "arm64" ]; then
|
||||
arch_str="arm64"
|
||||
fi
|
||||
|
||||
local url="https://github.com/jesseduffield/lazygit/releases/download/${latest_tag}/lazygit_${version}_linux_${arch_str}.tar.gz"
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() { rm -rf "$TMP_DIR"; }
|
||||
trap cleanup EXIT
|
||||
@@ -58,15 +48,16 @@ install_lazygit() {
|
||||
local dest="$TMP_DIR/lazygit.tar.gz"
|
||||
|
||||
log_info "Downloading lazygit ${latest_tag}..."
|
||||
download_file "$url" "$dest"
|
||||
github_download_asset "jesseduffield/lazygit" "$latest_tag" "lazygit_${version}_linux_${arch_str}\.tar\.gz" "$dest"
|
||||
|
||||
log_info "Extracting..."
|
||||
tar -xzf "$dest" -C "$TMP_DIR"
|
||||
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
mkdir -p "$BOOTSTRAP_BIN"
|
||||
cp "$TMP_DIR/lazygit" "$HOME/.local/bin/lazygit"
|
||||
chmod +x "$HOME/.local/bin/lazygit"
|
||||
track_file "$HOME/.local/bin/lazygit"
|
||||
register_tool "lazygit" "binary" "$latest_tag" "github:jesseduffield/lazygit"
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: node
|
||||
# DisplayName: Node
|
||||
# Description: Install Node.js (LTS) and NVM
|
||||
# Strategy: managed
|
||||
#
|
||||
# Node.js and NVM Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -21,7 +16,7 @@ cleanup() {
|
||||
trap cleanup EXIT
|
||||
|
||||
install_nvm() {
|
||||
if has_command nvm || [ -s "$HOME/.nvm/nvm.sh" ]; then
|
||||
if has_command nvm || [ -s "$BOOTSTRAP_RUNTIMES/nvm/nvm.sh" ]; then
|
||||
log_info "NVM is already installed."
|
||||
fi
|
||||
|
||||
@@ -29,12 +24,13 @@ install_nvm() {
|
||||
if ! has_command tar; then
|
||||
log_info "tar not found. Installing tar..."
|
||||
pkg_install tar
|
||||
registry_add_sys_deps "node" "tar"
|
||||
fi
|
||||
|
||||
# Try to fetch the latest version of NVM from GitHub API
|
||||
log_info "Fetching the latest NVM version..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
latest_tag=$(github_get_latest_release "nvm-sh/nvm")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.40.5" # Fallback version if API request fails
|
||||
@@ -47,25 +43,20 @@ install_nvm() {
|
||||
log_info "Downloading NVM from $nvm_url..."
|
||||
download_file "$nvm_url" "$TMP_DIR/nvm.tar.gz"
|
||||
|
||||
log_info "Extracting NVM archive directly to $HOME/.nvm (stripping versioned subfolder to keep config generic)..."
|
||||
mkdir -p "$HOME/.nvm"
|
||||
tar -xzf "$TMP_DIR/nvm.tar.gz" -C "$HOME/.nvm" --strip-components=1
|
||||
log_info "Extracting NVM archive directly to $BOOTSTRAP_RUNTIMES/nvm (stripping versioned subfolder to keep config generic)..."
|
||||
mkdir -p "$BOOTSTRAP_RUNTIMES/nvm"
|
||||
tar -xzf "$TMP_DIR/nvm.tar.gz" -C "$BOOTSTRAP_RUNTIMES/nvm" --strip-components=1
|
||||
|
||||
track_dir "$HOME/.nvm"
|
||||
track_dir "$BOOTSTRAP_RUNTIMES/nvm"
|
||||
|
||||
log_success "NVM source files successfully extracted to $HOME/.nvm."
|
||||
log_success "NVM source files successfully extracted to $BOOTSTRAP_RUNTIMES/nvm."
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "nvm setup"
|
||||
done
|
||||
|
||||
local content
|
||||
content=$(cat << 'EOF'
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
export NVM_DIR="$BOOTSTRAP_RUNTIMES/nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # Load NVM
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # Load NVM bash completion
|
||||
EOF
|
||||
@@ -76,10 +67,11 @@ EOF
|
||||
|
||||
install_node() {
|
||||
# Ensure NVM is loaded in this script context
|
||||
if [ -s "$HOME/.nvm/nvm.sh" ]; then
|
||||
if [ -s "$BOOTSTRAP_RUNTIMES/nvm/nvm.sh" ]; then
|
||||
# Temporarily disable nounset as nvm.sh does not support set -u
|
||||
set +u
|
||||
. "$HOME/.nvm/nvm.sh"
|
||||
# shellcheck source=/dev/null
|
||||
. "$BOOTSTRAP_RUNTIMES/nvm/nvm.sh"
|
||||
else
|
||||
log_error "Could not load NVM to install Node.js."
|
||||
return 1
|
||||
@@ -95,6 +87,7 @@ install_node() {
|
||||
nvm alias default 'lts/*'
|
||||
log_success "Node.js installed successfully!"
|
||||
set -u
|
||||
register_tool "node" "managed" "$latest_tag" "github:nvm-sh/nvm"
|
||||
}
|
||||
|
||||
main() {
|
||||
@@ -106,7 +99,7 @@ main() {
|
||||
if has_command node; then
|
||||
log_success "Node.js (via NVM) installation and configuration complete."
|
||||
log_info "Installed Node version: $(node --version)"
|
||||
log_info "Installed NVM version: $(nvm --version 2>/dev/null || cat "$HOME/.nvm/package.json" | grep '"version":' | head -n1 | sed -E 's/.*"version": "([^"]+)".*/\1/' || echo "unknown")"
|
||||
log_info "Installed NVM version: $(nvm --version 2>/dev/null || grep '"version":' "$BOOTSTRAP_RUNTIMES/nvm/package.json" | head -n1 | sed -E 's/.*"version": "([^"]+)".*/\1/' || echo "unknown")"
|
||||
else
|
||||
log_success "Installation complete."
|
||||
fi
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: nvim
|
||||
# DisplayName: Neovim
|
||||
# Description: Install Neovim 0.12.0 and configuration
|
||||
# Strategy: binary
|
||||
#
|
||||
# Neovim Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
NVIM_VERSION="0.12.0"
|
||||
NVIM_INSTALL_DIR="/opt/nvim"
|
||||
NVIM_INSTALL_DIR="$BOOTSTRAP_OPT/nvim"
|
||||
NVIM_BIN_DIR="$BOOTSTRAP_BIN"
|
||||
NVIM_CONFIG_REPO="https://git.adityagupta.dev/sortedcord/editor.git"
|
||||
NVIM_CONFIG_DIR="$HOME/.config/nvim"
|
||||
|
||||
@@ -33,7 +30,18 @@ check_config_dir() {
|
||||
install_packages() {
|
||||
log_info "Detecting distribution and installing dependencies..."
|
||||
pkg_install \
|
||||
git tar curl unzip ripgrep fzf nodejs npm xclip wl-clipboard \
|
||||
git tar unzip ripgrep fzf nodejs npm xclip wl-clipboard \
|
||||
"arch:fd|debian:fd-find|fedora:fd-find" \
|
||||
"arch:cmake|debian:cmake|fedora:cmake" \
|
||||
"arch:make|debian:build-essential|fedora:make" \
|
||||
"arch:gcc|debian:build-essential|fedora:gcc" \
|
||||
"arch:python|debian:python3|fedora:python3" \
|
||||
"debian:python3-pip|fedora:python3-pip" \
|
||||
"debian:python3-venv" \
|
||||
"fedora:gcc-c++"
|
||||
|
||||
registry_add_sys_deps "nvim" \
|
||||
git tar unzip ripgrep fzf nodejs npm xclip wl-clipboard \
|
||||
"arch:fd|debian:fd-find|fedora:fd-find" \
|
||||
"arch:cmake|debian:cmake|fedora:cmake" \
|
||||
"arch:make|debian:build-essential|fedora:make" \
|
||||
@@ -76,23 +84,23 @@ install_nvim() {
|
||||
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
local nvim_url="https://github.com/neovim/neovim/releases/download/v${NVIM_VERSION}/nvim-${nvim_arch}.tar.gz"
|
||||
|
||||
log_info "Downloading Neovim v${NVIM_VERSION} for ${arch}..."
|
||||
download_file "$nvim_url" "$TMP_DIR/nvim.tar.gz"
|
||||
github_download_asset "neovim/neovim" "v${NVIM_VERSION}" "nvim-${nvim_arch}\.tar\.gz" "$TMP_DIR/nvim.tar.gz"
|
||||
|
||||
tar -xzf "$TMP_DIR/nvim.tar.gz" -C "$TMP_DIR"
|
||||
|
||||
sudo rm -rf "$NVIM_INSTALL_DIR"
|
||||
sudo mv "$TMP_DIR/nvim-${nvim_arch}" "$NVIM_INSTALL_DIR"
|
||||
rm -rf "$NVIM_INSTALL_DIR"
|
||||
mkdir -p "$(dirname "$NVIM_INSTALL_DIR")"
|
||||
mv "$TMP_DIR/nvim-${nvim_arch}" "$NVIM_INSTALL_DIR"
|
||||
|
||||
sudo ln -sf "$NVIM_INSTALL_DIR/bin/nvim" /usr/local/bin/nvim
|
||||
ln -sf "$NVIM_INSTALL_DIR/bin/nvim" "$NVIM_BIN_DIR/nvim"
|
||||
|
||||
track_dir "$NVIM_INSTALL_DIR"
|
||||
track_file "/usr/local/bin/nvim"
|
||||
track_file "$NVIM_BIN_DIR/nvim"
|
||||
|
||||
log_success "Installed:"
|
||||
nvim --version | head -n1
|
||||
register_tool "nvim" "binary" "$NVIM_VERSION" "github:neovim/neovim"
|
||||
}
|
||||
|
||||
install_config() {
|
||||
@@ -111,24 +119,6 @@ install_config() {
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Clean up legacy inline edits from bashrc and bash_aliases
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
if [ -f "$config_file" ]; then
|
||||
local tmp_file
|
||||
tmp_file=$(mktemp)
|
||||
sed '/^export EDITOR="nvim"/d' "$config_file" > "$tmp_file"
|
||||
cat "$tmp_file" > "$config_file"
|
||||
rm -f "$tmp_file"
|
||||
fi
|
||||
done
|
||||
if [ -f "$HOME/.bash_aliases" ]; then
|
||||
local tmp_file
|
||||
tmp_file=$(mktemp)
|
||||
sed '/^alias vim="nvim"/d' "$HOME/.bash_aliases" > "$tmp_file"
|
||||
cat "$tmp_file" > "$HOME/.bash_aliases"
|
||||
rm -f "$tmp_file"
|
||||
fi
|
||||
|
||||
write_alias_snippet "nvim" 'alias vim="nvim"'
|
||||
write_env_snippet "nvim" 'export EDITOR="nvim"'
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Tool: pnpm
|
||||
# DisplayName: Pnpm
|
||||
# Description: Install pnpm package manager
|
||||
# Strategy: binary
|
||||
#
|
||||
# pnpm Installer Script
|
||||
#
|
||||
@@ -17,12 +18,6 @@
|
||||
# curl -fsSL https://get.pnpm.io/install.sh | ENV="$HOME/.bashrc" SHELL="$(which bash)" bash -
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -127,14 +122,17 @@ install_pnpm() {
|
||||
}
|
||||
libc_suffix="$(detect_libc_suffix)"
|
||||
|
||||
# Fetch the latest version from the npm registry, or use PNPM_VERSION if set
|
||||
# Fetch the latest version from GitHub, or use PNPM_VERSION if set
|
||||
if [ -z "${PNPM_VERSION:-}" ]; then
|
||||
log_info "Fetching latest pnpm version from npm registry..."
|
||||
version_json="$(download "https://registry.npmjs.org/@pnpm/exe")" || {
|
||||
log_error "Failed to fetch pnpm version info from npm registry."
|
||||
log_info "Fetching latest pnpm version from GitHub..."
|
||||
local tag
|
||||
tag=$(github_get_latest_release "pnpm/pnpm")
|
||||
if [ -n "$tag" ]; then
|
||||
version="${tag#v}"
|
||||
else
|
||||
log_error "Failed to fetch pnpm version info from GitHub."
|
||||
return 1
|
||||
}
|
||||
version="$(echo "$version_json" | grep -o '"latest":[[:space:]]*"[0-9.]*"' | grep -o '[0-9.]*')"
|
||||
fi
|
||||
else
|
||||
version="${PNPM_VERSION}"
|
||||
fi
|
||||
@@ -151,7 +149,7 @@ install_pnpm() {
|
||||
|
||||
if [ "$major_version" -ge 11 ]; then
|
||||
# v11+: distributed as tarballs containing the binary and dist/ directory
|
||||
download "https://github.com/pnpm/pnpm/releases/download/v${version}/${asset_base}.tar.gz" "$TMP_DIR/pnpm.tar.gz" || {
|
||||
github_download_asset "pnpm/pnpm" "v${version}" "${asset_base}\.tar\.gz" "$TMP_DIR/pnpm.tar.gz" || {
|
||||
log_error "Failed to download pnpm tarball."
|
||||
return 1
|
||||
}
|
||||
@@ -166,7 +164,7 @@ install_pnpm() {
|
||||
}
|
||||
else
|
||||
# Older versions: distributed as a single executable binary
|
||||
download "https://github.com/pnpm/pnpm/releases/download/v${version}/${asset_base}" "$TMP_DIR/pnpm" || {
|
||||
github_download_asset "pnpm/pnpm" "v${version}" "${asset_base}" "$TMP_DIR/pnpm" || {
|
||||
log_error "Failed to download pnpm binary."
|
||||
return 1
|
||||
}
|
||||
@@ -179,23 +177,19 @@ install_pnpm() {
|
||||
|
||||
track_dir "$HOME/.local/share/pnpm"
|
||||
log_success "pnpm v${version} installed successfully!"
|
||||
register_tool "pnpm" "binary" "$version" "github:pnpm/pnpm"
|
||||
}
|
||||
|
||||
# ─── Shell Configuration ─────────────────────────────────────────────
|
||||
|
||||
configure_shell() {
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "pnpm setup"
|
||||
done
|
||||
|
||||
# pnpm's `setup --force` configures PNPM_HOME and PATH automatically,
|
||||
# but we also add an env block to ensure PNPM_HOME is set consistently.
|
||||
local content
|
||||
content=$(cat << 'EOF'
|
||||
# pnpm
|
||||
export PNPM_HOME="$HOME/.local/share/pnpm"
|
||||
export PNPM_HOME="$BOOTSTRAP_RUNTIMES/pnpm"
|
||||
case ":$PATH:" in
|
||||
*":$PNPM_HOME:"*) ;;
|
||||
*) export PATH="$PNPM_HOME:$PATH" ;;
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: rust
|
||||
# DisplayName: Rust
|
||||
# Description: Install Rustup and Rust compiler/toolchain
|
||||
# Strategy: managed
|
||||
#
|
||||
# Rust Installer Script (Simplified Local Rustup Init)
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -20,14 +16,6 @@ cleanup() {
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Ensure we have curl
|
||||
install_downloader() {
|
||||
if ! has_command curl; then
|
||||
log_info "curl not found. Installing curl..."
|
||||
pkg_install curl
|
||||
fi
|
||||
}
|
||||
|
||||
detect_target_triple() {
|
||||
local ostype
|
||||
ostype="$(uname -s)"
|
||||
@@ -61,11 +49,14 @@ detect_target_triple() {
|
||||
}
|
||||
|
||||
install_rust() {
|
||||
if has_command rustup || [ -f "$HOME/.cargo/bin/rustup" ]; then
|
||||
export CARGO_HOME="$BOOTSTRAP_RUNTIMES/cargo"
|
||||
export RUSTUP_HOME="$BOOTSTRAP_RUNTIMES/rustup"
|
||||
|
||||
if has_command rustup || [ -f "$BOOTSTRAP_RUNTIMES/cargo/bin/rustup" ]; then
|
||||
log_info "Rust (rustup) is already installed."
|
||||
fi
|
||||
|
||||
install_downloader
|
||||
|
||||
|
||||
local target
|
||||
target=$(detect_target_triple)
|
||||
@@ -87,19 +78,19 @@ install_rust() {
|
||||
"$dest" -y --no-modify-path
|
||||
|
||||
add_rollback_cmd "rustup self uninstall -y"
|
||||
register_tool "rust" "managed" "" "rustup"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Add ~/.cargo/bin to PATH for the current process
|
||||
export PATH="$HOME/.cargo/bin:$PATH"
|
||||
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "rust init"
|
||||
done
|
||||
|
||||
write_env_snippet "rust" '. "$HOME/.cargo/env"'
|
||||
local snippet_content=$(cat << 'EOF'
|
||||
export CARGO_HOME="$BOOTSTRAP_RUNTIMES/cargo"
|
||||
export RUSTUP_HOME="$BOOTSTRAP_RUNTIMES/rustup"
|
||||
. "$CARGO_HOME/env"
|
||||
EOF
|
||||
)
|
||||
write_env_snippet "rust" "$snippet_content"
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: starship
|
||||
# DisplayName: Starship
|
||||
# Description: Install Starship shell prompt
|
||||
# Strategy: binary
|
||||
#
|
||||
# Starship Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -25,12 +21,6 @@ install_starship() {
|
||||
log_info "Starship is already installed."
|
||||
fi
|
||||
|
||||
# Ensure curl is installed
|
||||
if ! has_command curl; then
|
||||
log_info "curl not found. Installing curl..."
|
||||
pkg_install curl
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
local raw_arch
|
||||
raw_arch=$(detect_arch)
|
||||
@@ -45,47 +35,33 @@ install_starship() {
|
||||
|
||||
log_info "Fetching latest Starship version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/starship/starship/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
|
||||
local download_url
|
||||
if [ -n "$latest_tag" ]; then
|
||||
log_info "Latest Starship version found: $latest_tag"
|
||||
download_url="https://github.com/starship/starship/releases/download/${latest_tag}/starship-${target}.tar.gz"
|
||||
else
|
||||
latest_tag=$(github_get_latest_release "starship/starship")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="latest"
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to downloading latest release directly."
|
||||
download_url="https://github.com/starship/starship/releases/latest/download/starship-${target}.tar.gz"
|
||||
fi
|
||||
|
||||
log_info "Downloading Starship from ${download_url}..."
|
||||
log_info "Downloading Starship ${latest_tag}..."
|
||||
local archive="$TMP_DIR/starship.tar.gz"
|
||||
download_file "$download_url" "$archive"
|
||||
github_download_asset "starship/starship" "$latest_tag" "starship-${target}\.tar\.gz" "$archive"
|
||||
|
||||
# Extract the binary
|
||||
log_info "Extracting Starship binary..."
|
||||
tar -xzf "$archive" -C "$TMP_DIR"
|
||||
|
||||
# Install to ~/.local/bin
|
||||
local target_dir="$HOME/.local/bin"
|
||||
local target_dir="$BOOTSTRAP_BIN"
|
||||
mkdir -p "$target_dir"
|
||||
log_info "Installing Starship to $target_dir/starship..."
|
||||
cp "$TMP_DIR/starship" "$target_dir/starship"
|
||||
chmod +x "$target_dir/starship"
|
||||
track_file "$target_dir/starship"
|
||||
register_tool "starship" "binary" "$latest_tag" "github:starship/starship"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Add ~/.local/bin to PATH for the current process
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "local-bin path"
|
||||
remove_block "$config_file" "starship init"
|
||||
done
|
||||
|
||||
write_env_snippet "local-bin" 'export PATH="$HOME/.local/bin:$PATH"'
|
||||
write_env_snippet "starship" 'eval "$(starship init bash)"'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: uv
|
||||
# DisplayName: uv
|
||||
# Description: Fast Python package installer and resolver
|
||||
# Strategy: binary
|
||||
#
|
||||
# uv Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -28,12 +24,6 @@ install_uv() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure curl is installed
|
||||
if ! has_command curl; then
|
||||
log_info "curl not found. Installing curl..."
|
||||
pkg_install curl
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
local raw_arch
|
||||
raw_arch=$(detect_arch)
|
||||
@@ -54,28 +44,22 @@ install_uv() {
|
||||
|
||||
log_info "Fetching latest uv version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/astral-sh/uv/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
latest_tag=$(github_get_latest_release "astral-sh/uv")
|
||||
|
||||
local download_url
|
||||
if [ -n "$latest_tag" ]; then
|
||||
log_info "Latest uv version found: $latest_tag"
|
||||
download_url="https://github.com/astral-sh/uv/releases/download/${latest_tag}/uv-${target}.tar.gz"
|
||||
else
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="latest"
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to downloading latest release directly."
|
||||
download_url="https://github.com/astral-sh/uv/releases/latest/download/uv-${target}.tar.gz"
|
||||
fi
|
||||
|
||||
log_info "Downloading uv from ${download_url}..."
|
||||
log_info "Downloading uv ${latest_tag}..."
|
||||
local archive="$TMP_DIR/uv.tar.gz"
|
||||
download_file "$download_url" "$archive"
|
||||
github_download_asset "astral-sh/uv" "$latest_tag" "uv-${target}\.tar\.gz" "$archive"
|
||||
|
||||
# Extract the binaries
|
||||
log_info "Extracting uv binaries..."
|
||||
tar -xzf "$archive" --strip-components 1 -C "$TMP_DIR"
|
||||
|
||||
# Install to ~/.local/bin
|
||||
local target_dir="$HOME/.local/bin"
|
||||
local target_dir="$BOOTSTRAP_BIN"
|
||||
mkdir -p "$target_dir"
|
||||
log_info "Installing uv and uvx to $target_dir..."
|
||||
cp "$TMP_DIR/uv" "$target_dir/uv"
|
||||
@@ -83,20 +67,12 @@ install_uv() {
|
||||
chmod +x "$target_dir/uv" "$target_dir/uvx"
|
||||
track_file "$target_dir/uv"
|
||||
track_file "$target_dir/uvx"
|
||||
register_tool "uv" "binary" "$latest_tag" "github:astral-sh/uv"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Add ~/.local/bin to PATH for the current process
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "local-bin path"
|
||||
remove_block "$config_file" "uv completion"
|
||||
done
|
||||
|
||||
write_env_snippet "local-bin" 'export PATH="$HOME/.local/bin:$PATH"'
|
||||
write_env_snippet "uv" 'eval "$(uv generate-shell-completion bash)"'
|
||||
}
|
||||
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: yay
|
||||
# DisplayName: Yay
|
||||
# Description: Install Yay AUR helper
|
||||
# Strategy: system
|
||||
#
|
||||
# Yay Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
@@ -43,6 +38,7 @@ install_yay() {
|
||||
else
|
||||
log_info "Dependencies (git and base-devel) are already present. Skipping package installation."
|
||||
fi
|
||||
registry_add_sys_deps "yay" "git" "base-devel"
|
||||
|
||||
log_info "Cloning yay-bin repository..."
|
||||
local clone_dir
|
||||
@@ -66,6 +62,7 @@ install_yay() {
|
||||
cd "$orig_dir"
|
||||
log_info "Cleaning up installer directory..."
|
||||
rm -rf "$clone_dir"
|
||||
register_tool "yay" "system" "" "aur:yay-bin"
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
# Tool: yazi
|
||||
# DisplayName: Yazi
|
||||
# Description: Install Yazi terminal file manager and dependencies
|
||||
# Strategy: binary
|
||||
#
|
||||
# Yazi Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
@@ -21,11 +16,6 @@ cleanup() {
|
||||
trap cleanup EXIT
|
||||
|
||||
add_y_wrapper() {
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "yazi wrapper"
|
||||
done
|
||||
|
||||
local wrapper_content
|
||||
wrapper_content=$(cat << 'EOF'
|
||||
@@ -40,77 +30,69 @@ y() {
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
write_alias_snippet "yazi" "$wrapper_content"
|
||||
}
|
||||
|
||||
install_yazi() {
|
||||
local distro
|
||||
distro=$(detect_distro)
|
||||
|
||||
if [ "$distro" = "arch" ]; then
|
||||
log_info "Arch Linux detected"
|
||||
if has_command yazi; then
|
||||
log_info "Yazi is already installed."
|
||||
if has_command yazi; then
|
||||
if ! confirm "Yazi is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping Yazi installation."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Installing Yazi..."
|
||||
pkg_install yazi
|
||||
log_info "Installing dependencies subsequently..."
|
||||
pkg_install ffmpeg 7zip jq poppler fd ripgrep fzf zoxide resvg imagemagick
|
||||
|
||||
elif [ "$distro" = "debian" ]; then
|
||||
log_info "Debian/Ubuntu detected"
|
||||
if has_command yazi; then
|
||||
log_info "Yazi is already installed."
|
||||
fi
|
||||
|
||||
pkg_install curl git
|
||||
|
||||
log_info "Fetching latest Yazi version from GitHub..."
|
||||
local latest_tag
|
||||
latest_tag=$(curl -sL https://api.github.com/repos/sxyazi/yazi/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true)
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v26.5.6"
|
||||
fi
|
||||
|
||||
local deb_url="https://github.com/sxyazi/yazi/releases/download/${latest_tag}/yazi-x86_64-unknown-linux-gnu.deb"
|
||||
log_info "Downloading Yazi ${latest_tag} from ${deb_url}..."
|
||||
download_file "$deb_url" "$TMP_DIR/yazi.deb"
|
||||
|
||||
log_info "Installing Yazi package..."
|
||||
sudo apt install -y "$TMP_DIR/yazi.deb"
|
||||
add_rollback_cmd "sudo apt remove -y yazi"
|
||||
|
||||
log_info "Installing dependencies subsequently..."
|
||||
pkg_install ffmpeg jq poppler-utils fd-find ripgrep fzf zoxide resvg imagemagick 7zip || \
|
||||
pkg_install ffmpeg jq poppler-utils fd-find ripgrep fzf zoxide resvg imagemagick p7zip-full
|
||||
|
||||
create_fd_symlink
|
||||
|
||||
elif [ "$distro" = "fedora" ]; then
|
||||
log_info "Fedora detected"
|
||||
if has_command yazi; then
|
||||
log_info "Yazi is already installed."
|
||||
fi
|
||||
|
||||
log_info "Installing dnf-plugins-core..."
|
||||
pkg_install dnf-plugins-core
|
||||
|
||||
log_info "Enabling lihaohong/yazi copr repo..."
|
||||
sudo dnf copr enable -y lihaohong/yazi
|
||||
|
||||
log_info "Installing Yazi (without weak dependencies first)..."
|
||||
sudo dnf install -y yazi --setopt=install_weak_deps=False
|
||||
add_rollback_cmd "sudo dnf remove -y yazi"
|
||||
|
||||
log_info "Installing weak dependencies subsequently..."
|
||||
pkg_install yazi
|
||||
|
||||
else
|
||||
log_error "Unsupported distribution."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure required extraction tools are installed
|
||||
if ! has_command unzip; then
|
||||
log_info "unzip not found. Installing unzip..."
|
||||
pkg_install unzip
|
||||
registry_add_sys_deps "yazi" "unzip"
|
||||
fi
|
||||
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local target=""
|
||||
case "$arch" in
|
||||
x86_64) target="x86_64-unknown-linux-gnu" ;;
|
||||
arm64) target="aarch64-unknown-linux-gnu" ;;
|
||||
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
log_info "Fetching latest Yazi version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(github_get_latest_release "sxyazi/yazi")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.3.3"
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to: $latest_tag"
|
||||
fi
|
||||
|
||||
log_info "Downloading Yazi ${latest_tag}..."
|
||||
local archive="$TMP_DIR/yazi.zip"
|
||||
github_download_asset "sxyazi/yazi" "$latest_tag" "yazi-${target}\.zip" "$archive"
|
||||
|
||||
log_info "Extracting Yazi binaries..."
|
||||
unzip -q "$archive" -d "$TMP_DIR"
|
||||
|
||||
local extract_dir="$TMP_DIR/yazi-${target}"
|
||||
local target_dir="$BOOTSTRAP_BIN"
|
||||
mkdir -p "$target_dir"
|
||||
|
||||
log_info "Installing Yazi to $target_dir..."
|
||||
cp "$extract_dir/yazi" "$target_dir/yazi"
|
||||
cp "$extract_dir/ya" "$target_dir/ya"
|
||||
chmod +x "$target_dir/yazi" "$target_dir/ya"
|
||||
track_file "$target_dir/yazi"
|
||||
track_file "$target_dir/ya"
|
||||
|
||||
log_info "Installing system dependencies for Yazi..."
|
||||
pkg_install ffmpeg jq ripgrep fzf zoxide resvg imagemagick "arch:7zip|debian:7zip|fedora:p7zip" "arch:poppler|debian:poppler-utils|fedora:poppler-utils" "arch:fd|debian:fd-find|fedora:fd-find"
|
||||
|
||||
create_fd_symlink
|
||||
|
||||
register_tool "yazi" "binary" "$latest_tag" "github:sxyazi/yazi"
|
||||
|
||||
# Add the system dependencies to the registry for uninstallation tracking
|
||||
registry_add_sys_deps "yazi" ffmpeg jq ripgrep fzf zoxide resvg imagemagick "arch:7zip|debian:7zip|fedora:p7zip" "arch:poppler|debian:poppler-utils|fedora:poppler-utils" "arch:fd|debian:fd-find|fedora:fd-find"
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
@@ -1,25 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: zoxide
|
||||
# DisplayName: Zoxide
|
||||
# Description: Install Zoxide directory jumper
|
||||
# Strategy: managed
|
||||
#
|
||||
# Zoxide Installer Script
|
||||
#
|
||||
|
||||
# Prevent standalone execution
|
||||
if [ -z "${_LIB_COMMON_SOURCED:-}" ]; then
|
||||
echo "Error: This script must be run through the 'b' CLI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
install_curl() {
|
||||
if ! has_command curl; then
|
||||
log_info "curl not found. Installing curl..."
|
||||
pkg_install curl
|
||||
fi
|
||||
}
|
||||
|
||||
install_fzf() {
|
||||
if has_command fzf; then
|
||||
@@ -29,6 +19,7 @@ install_fzf() {
|
||||
|
||||
log_info "fzf not found. Installing fzf..."
|
||||
pkg_install fzf
|
||||
registry_add_sys_deps "zoxide" "fzf"
|
||||
}
|
||||
|
||||
install_zoxide() {
|
||||
@@ -36,24 +27,17 @@ install_zoxide() {
|
||||
log_info "Zoxide is already installed."
|
||||
fi
|
||||
|
||||
install_curl
|
||||
|
||||
|
||||
log_info "Downloading and running the official zoxide installer..."
|
||||
curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh
|
||||
track_file "$HOME/.local/bin/zoxide"
|
||||
register_tool "zoxide" "managed" "" "github:ajeetdsouza/zoxide"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
# Add ~/.local/bin to PATH for the current process
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# Clean up legacy in-place configuration blocks
|
||||
IFS=' ' read -ra target_files <<< "$(get_shell_configs)"
|
||||
for config_file in "${target_files[@]}"; do
|
||||
remove_block "$config_file" "zoxide init"
|
||||
done
|
||||
|
||||
write_env_snippet "local-bin" 'export PATH="$HOME/.local/bin:$PATH"'
|
||||
write_env_snippet "zoxide" 'eval "$(zoxide init --cmd cd bash)"'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user