mirror of
https://github.com/sortedcord/bootstrap.git
synced 2026-07-23 04:32:49 +05:30
Shifted installers to to tools
This commit is contained in:
147
tools/agy/tool.sh
Normal file
147
tools/agy/tool.sh
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: agy
|
||||
# DisplayName: Antigravity
|
||||
# Description: Install Antigravity CLI
|
||||
# Strategy: binary
|
||||
#
|
||||
# Antigravity CLI Installer Script (Linux Only)
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Constants
|
||||
DOWNLOAD_BASE_URL="https://antigravity-cli-auto-updater-974169037036.us-central1.run.app"
|
||||
TARGET_DIR="$BOOTSTRAP_BIN"
|
||||
BINARY_PATH="$TARGET_DIR/agy"
|
||||
|
||||
install_agy() {
|
||||
if [ -f "$BINARY_PATH" ]; then
|
||||
log_info "Notice: 'agy' is already installed at $BINARY_PATH."
|
||||
log_info "The Antigravity CLI automatically self-updates in the background during regular runs."
|
||||
fi
|
||||
|
||||
# Detect Architecture (map uname -m to amd64 / arm64)
|
||||
local arch
|
||||
local raw_arch
|
||||
raw_arch=$(detect_arch)
|
||||
case "$raw_arch" in
|
||||
x86_64) arch="amd64" ;;
|
||||
arm64) arch="arm64" ;;
|
||||
*) log_error "Unsupported Linux architecture: $raw_arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# musl libc detection on Linux
|
||||
local platform="linux_${arch}"
|
||||
if [ -f /lib/libc.musl-x86_64.so.1 ] || [ -f /lib/libc.musl-aarch64.so.1 ] || ldd /bin/ls 2>&1 | grep -q musl; then
|
||||
platform="linux_${arch}_musl"
|
||||
fi
|
||||
|
||||
log_info "Platform detected: $platform"
|
||||
log_info "Querying release repository..."
|
||||
|
||||
# Construct Platform JSON Manifest URL
|
||||
local manifest_url="$DOWNLOAD_BASE_URL/manifests/$platform.json"
|
||||
local manifest_json=""
|
||||
|
||||
manifest_json=$(curl -fsSL "$manifest_url" 2>/dev/null || true)
|
||||
|
||||
if [ -z "$manifest_json" ]; then
|
||||
log_error "Could not connect to the release server to download the manifest."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local version
|
||||
local url
|
||||
local 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."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Latest available version: $version"
|
||||
|
||||
# Setup temp/staging dir
|
||||
local staging_dir
|
||||
staging_dir="$(make_temp_dir)"
|
||||
|
||||
local is_tar_gz=false
|
||||
if [[ "$url" == *.tar.gz* ]]; then
|
||||
is_tar_gz=true
|
||||
fi
|
||||
|
||||
local staging_payload
|
||||
local extracted_binary
|
||||
if [ "$is_tar_gz" = true ]; then
|
||||
staging_payload="$staging_dir/agy.tar.gz"
|
||||
extracted_binary="$staging_dir/antigravity"
|
||||
else
|
||||
staging_payload="$staging_dir/agy"
|
||||
extracted_binary="$staging_payload"
|
||||
fi
|
||||
|
||||
log_info "Downloading release package..."
|
||||
download_file "$url" "$staging_payload"
|
||||
|
||||
# Verify SHA512 Checksum
|
||||
local actual_hash
|
||||
if has_command sha512sum; then
|
||||
actual_hash=$(sha512sum "$staging_payload" | cut -d' ' -f1 || true)
|
||||
elif has_command shasum; then
|
||||
actual_hash=$(shasum -a 512 "$staging_payload" | cut -d' ' -f1 || true)
|
||||
else
|
||||
log_error "Neither sha512sum nor shasum is available to verify the download."
|
||||
rm -rf "$staging_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$actual_hash" != "$sha512" ]; then
|
||||
log_error "Security Halt: Downloaded payload checksum does not match manifest. Installation aborted."
|
||||
rm -rf "$staging_dir"
|
||||
exit 1
|
||||
fi
|
||||
log_success "Download complete and checksum verified."
|
||||
|
||||
# Direct Binary Extraction & Write Permission Validation
|
||||
mkdir -p "$TARGET_DIR"
|
||||
|
||||
if [ "$is_tar_gz" = true ]; then
|
||||
log_info "Extracting binary from archive..."
|
||||
tar -xzf "$staging_payload" -C "$staging_dir" antigravity
|
||||
else
|
||||
log_info "Copying binary directly to destination..."
|
||||
fi
|
||||
|
||||
cp "$extracted_binary" "$BINARY_PATH"
|
||||
chmod +x "$BINARY_PATH"
|
||||
rm -rf "$staging_dir"
|
||||
|
||||
track_file "$BINARY_PATH"
|
||||
|
||||
log_success "Antigravity CLI successfully installed to $BINARY_PATH."
|
||||
register_tool "agy" "binary" "" "github:sortedcord/agy"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
|
||||
}
|
||||
|
||||
run_handoff() {
|
||||
log_info "Configuring shell environment via agy native setup handoff..."
|
||||
# Run standard configuration and absorb non-fatal soft warning exits
|
||||
"$BINARY_PATH" install || true
|
||||
}
|
||||
|
||||
main() {
|
||||
install_agy
|
||||
configure_shell
|
||||
run_handoff
|
||||
|
||||
echo
|
||||
log_success "Antigravity CLI installation complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
92
tools/asciicinema/tool.sh
Normal file
92
tools/asciicinema/tool.sh
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: asciicinema
|
||||
# DisplayName: asciicinema
|
||||
# Description: Install asciinema terminal recorder
|
||||
# Strategy: binary
|
||||
#
|
||||
# asciinema Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
install_asciicinema() {
|
||||
if has_command curl; then
|
||||
log_info "Fetching latest asciinema version from GitHub..."
|
||||
latest_tag=$(github_get_latest_release "asciinema/asciinema")
|
||||
fi
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v3.2.1" # fallback
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to: $latest_tag"
|
||||
else
|
||||
log_info "Latest asciinema version found: $latest_tag"
|
||||
fi
|
||||
|
||||
|
||||
if has_command asciinema; then
|
||||
local current_version
|
||||
current_version=$(asciinema --version | head -n1 | awk '{print $2}')
|
||||
if [[ "$current_version" != v* ]]; then
|
||||
current_version="v${current_version}"
|
||||
fi
|
||||
|
||||
if [[ "$current_version" == "$latest_tag" ]]; then
|
||||
log_info "asciinema ${latest_tag} is already installed."
|
||||
if ! confirm "Reinstall/Upgrade asciinema?"; then
|
||||
log_info "Skipping asciinema installation."
|
||||
return
|
||||
fi
|
||||
else
|
||||
if ! confirm "Detecting asciinema ${current_version}. Upgrade to ${latest_tag}?"; then
|
||||
log_info "Skipping asciinema installation."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if ! confirm "Install asciinema ${latest_tag}?"; then
|
||||
log_info "Skipping asciinema installation."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local asciinema_arch=""
|
||||
case "$arch" in
|
||||
x86_64) asciinema_arch="x86_64-unknown-linux-gnu" ;;
|
||||
arm64) asciinema_arch="aarch64-unknown-linux-gnu" ;;
|
||||
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
log_info "Downloading asciinema ${latest_tag} for ${arch}..."
|
||||
github_download_asset "asciinema/asciinema" "$latest_tag" "asciinema-${asciinema_arch}" "$TMP_DIR/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..."
|
||||
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() {
|
||||
install_asciicinema
|
||||
|
||||
echo
|
||||
log_success "asciinema installation complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
79
tools/bat/tool.sh
Normal file
79
tools/bat/tool.sh
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: bat
|
||||
# DisplayName: Bat
|
||||
# Description: Install Bat (alternative to cat) and configure alias
|
||||
# Strategy: binary
|
||||
#
|
||||
# Bat Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
install_bat() {
|
||||
if has_command bat; then
|
||||
if ! confirm "Bat is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping Bat installation."
|
||||
return
|
||||
fi
|
||||
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() {
|
||||
|
||||
write_alias_snippet "bat" "alias cat='bat --paging=never -p'"
|
||||
}
|
||||
|
||||
main() {
|
||||
install_bat
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
log_success "Bat installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
69
tools/docker/tool.sh
Normal file
69
tools/docker/tool.sh
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: docker
|
||||
# DisplayName: Docker
|
||||
# Description: Container runtime and orchestration platform
|
||||
# Strategy: system
|
||||
#
|
||||
# Docker Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
|
||||
install_docker() {
|
||||
if has_command docker; then
|
||||
if ! confirm "Docker is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping Docker installation."
|
||||
return
|
||||
fi
|
||||
else
|
||||
if ! confirm "Install Docker?"; then
|
||||
log_info "Skipping Docker installation."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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
|
||||
log_info "Creating docker group..."
|
||||
add_rollback_cmd "sudo groupdel docker || true"
|
||||
sudo groupadd docker
|
||||
fi
|
||||
|
||||
# Configure user group
|
||||
if ! groups "$USER" | grep -q "\bdocker\b"; then
|
||||
log_info "Adding $USER to the docker group..."
|
||||
add_rollback_cmd "sudo gpasswd -d $USER docker || true"
|
||||
sudo usermod -aG docker "$USER"
|
||||
log_warn "You will need to log out and log back in, or run 'newgrp docker' for the group changes to take effect."
|
||||
fi
|
||||
|
||||
# Enable and start systemd services
|
||||
if has_command systemctl; then
|
||||
log_info "Enabling and starting Docker services..."
|
||||
|
||||
# Add rollback cmds for systemd
|
||||
add_rollback_cmd "sudo systemctl disable --now docker.service || true"
|
||||
add_rollback_cmd "sudo systemctl disable --now containerd.service || true"
|
||||
|
||||
sudo systemctl enable --now docker.service || true
|
||||
sudo systemctl enable --now containerd.service || true
|
||||
fi
|
||||
register_tool "docker" "system" "" "os-package-manager"
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────
|
||||
|
||||
main() {
|
||||
install_docker
|
||||
|
||||
echo
|
||||
log_success "Docker installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
72
tools/lazygit/tool.sh
Executable file
72
tools/lazygit/tool.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: lazygit
|
||||
# DisplayName: lazygit
|
||||
# Description: Simple terminal UI for git commands
|
||||
# Strategy: binary
|
||||
#
|
||||
# lazygit Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
|
||||
install_lazygit() {
|
||||
if has_command lazygit; then
|
||||
if ! confirm "lazygit is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping lazygit installation."
|
||||
return
|
||||
fi
|
||||
else
|
||||
if ! confirm "Install lazygit?"; then
|
||||
log_info "Skipping lazygit installation."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
local latest_tag=""
|
||||
latest_tag=$(github_get_latest_release "jesseduffield/lazygit")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.62.2" # fallback
|
||||
log_warn "Failed to fetch latest version. Falling back to: $latest_tag"
|
||||
fi
|
||||
|
||||
local version="${latest_tag#v}"
|
||||
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local arch_str="x86_64"
|
||||
if [ "$arch" = "arm64" ]; then
|
||||
arch_str="arm64"
|
||||
fi
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() { rm -rf "$TMP_DIR"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
local dest="$TMP_DIR/lazygit.tar.gz"
|
||||
|
||||
log_info "Downloading lazygit ${latest_tag}..."
|
||||
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 "$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 ─────────────────────────────────────────────────────────────
|
||||
|
||||
main() {
|
||||
install_lazygit
|
||||
|
||||
echo
|
||||
log_success "lazygit installation complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
108
tools/node/tool.sh
Normal file
108
tools/node/tool.sh
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: node
|
||||
# DisplayName: Node
|
||||
# Description: Install Node.js (LTS) and NVM
|
||||
# Strategy: managed
|
||||
#
|
||||
# Node.js and NVM Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
install_nvm() {
|
||||
if has_command nvm || [ -s "$BOOTSTRAP_RUNTIMES/nvm/nvm.sh" ]; then
|
||||
log_info "NVM is already installed."
|
||||
fi
|
||||
|
||||
# Ensure required commands are installed
|
||||
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=$(github_get_latest_release "nvm-sh/nvm")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="v0.40.5" # Fallback version if API request fails
|
||||
log_warn "Failed to fetch latest version from GitHub. Falling back to hardcoded version: $latest_tag"
|
||||
else
|
||||
log_info "Latest NVM version found: $latest_tag"
|
||||
fi
|
||||
|
||||
local nvm_url="https://github.com/nvm-sh/nvm/archive/refs/tags/${latest_tag}.tar.gz"
|
||||
log_info "Downloading NVM from $nvm_url..."
|
||||
download_file "$nvm_url" "$TMP_DIR/nvm.tar.gz"
|
||||
|
||||
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 "$BOOTSTRAP_RUNTIMES/nvm"
|
||||
|
||||
log_success "NVM source files successfully extracted to $BOOTSTRAP_RUNTIMES/nvm."
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
|
||||
local content
|
||||
content=$(cat << 'EOF'
|
||||
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
|
||||
)
|
||||
|
||||
write_env_snippet "node" "$content"
|
||||
}
|
||||
|
||||
install_node() {
|
||||
# Ensure NVM is loaded in this script context
|
||||
if [ -s "$BOOTSTRAP_RUNTIMES/nvm/nvm.sh" ]; then
|
||||
# Temporarily disable nounset as nvm.sh does not support set -u
|
||||
set +u
|
||||
# shellcheck source=/dev/null
|
||||
. "$BOOTSTRAP_RUNTIMES/nvm/nvm.sh"
|
||||
else
|
||||
log_error "Could not load NVM to install Node.js."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if has_command node; then
|
||||
log_info "Currently installed Node.js version: $(node --version)"
|
||||
fi
|
||||
|
||||
log_info "Installing Node.js LTS version..."
|
||||
nvm install --lts
|
||||
nvm use --lts
|
||||
nvm alias default 'lts/*'
|
||||
log_success "Node.js installed successfully!"
|
||||
set -u
|
||||
register_tool "node" "managed" "$latest_tag" "github:nvm-sh/nvm"
|
||||
}
|
||||
|
||||
main() {
|
||||
install_nvm
|
||||
configure_shell
|
||||
install_node
|
||||
|
||||
echo
|
||||
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 || grep '"version":' "$BOOTSTRAP_RUNTIMES/nvm/package.json" | head -n1 | sed -E 's/.*"version": "([^"]+)".*/\1/' || echo "unknown")"
|
||||
else
|
||||
log_success "Installation complete."
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
138
tools/nvim/tool.sh
Normal file
138
tools/nvim/tool.sh
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: nvim
|
||||
# DisplayName: Neovim
|
||||
# Description: Install Neovim 0.12.0 and configuration
|
||||
# Strategy: binary
|
||||
#
|
||||
# Neovim Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
NVIM_VERSION="0.12.0"
|
||||
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"
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
check_config_dir() {
|
||||
# Skip prompt, handled during config clone
|
||||
return 0
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
log_info "Detecting distribution and installing dependencies..."
|
||||
pkg_install \
|
||||
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" \
|
||||
"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++"
|
||||
|
||||
create_fd_symlink
|
||||
|
||||
log_info "Installing tree-sitter-cli globally..."
|
||||
sudo npm install -g tree-sitter-cli
|
||||
add_rollback_cmd "sudo npm uninstall -g tree-sitter-cli"
|
||||
}
|
||||
|
||||
install_nvim() {
|
||||
local current_version=""
|
||||
|
||||
if has_command nvim; then
|
||||
current_version="$(nvim --version | head -n1 | awk '{print $2}')"
|
||||
|
||||
if [[ "$current_version" == "v${NVIM_VERSION}" ]] || [[ "$current_version" == "${NVIM_VERSION}" ]]; then
|
||||
log_info "Neovim ${current_version} already installed."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Detected Neovim ${current_version}. Upgrading to v${NVIM_VERSION}..."
|
||||
else
|
||||
log_info "Installing Neovim v${NVIM_VERSION}..."
|
||||
fi
|
||||
|
||||
# Detect architecture to resolve the release binary name (Fix 4)
|
||||
local arch
|
||||
arch=$(detect_arch)
|
||||
local nvim_arch=""
|
||||
case "$arch" in
|
||||
x86_64) nvim_arch="linux-x86_64" ;;
|
||||
arm64) nvim_arch="linux-arm64" ;;
|
||||
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
log_info "Downloading Neovim v${NVIM_VERSION} for ${arch}..."
|
||||
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"
|
||||
|
||||
rm -rf "$NVIM_INSTALL_DIR"
|
||||
mkdir -p "$(dirname "$NVIM_INSTALL_DIR")"
|
||||
mv "$TMP_DIR/nvim-${nvim_arch}" "$NVIM_INSTALL_DIR"
|
||||
|
||||
ln -sf "$NVIM_INSTALL_DIR/bin/nvim" "$NVIM_BIN_DIR/nvim"
|
||||
|
||||
track_dir "$NVIM_INSTALL_DIR"
|
||||
track_file "$NVIM_BIN_DIR/nvim"
|
||||
|
||||
log_success "Installed:"
|
||||
nvim --version | head -n1
|
||||
register_tool "nvim" "binary" "$NVIM_VERSION" "github:neovim/neovim"
|
||||
}
|
||||
|
||||
install_config() {
|
||||
if [[ -d "$NVIM_CONFIG_DIR" ]]; then
|
||||
log_info "Neovim configuration directory $NVIM_CONFIG_DIR already exists. Skipping config clone."
|
||||
return
|
||||
fi
|
||||
|
||||
# Ensure parent directory for the chosen config path exists
|
||||
mkdir -p "$(dirname "$NVIM_CONFIG_DIR")"
|
||||
|
||||
log_info "Cloning configuration to $NVIM_CONFIG_DIR..."
|
||||
git clone "$NVIM_CONFIG_REPO" "$NVIM_CONFIG_DIR"
|
||||
track_dir "$NVIM_CONFIG_DIR"
|
||||
log_success "Configuration installed."
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
|
||||
write_alias_snippet "nvim" 'alias vim="nvim"'
|
||||
write_env_snippet "nvim" 'export EDITOR="nvim"'
|
||||
}
|
||||
|
||||
main() {
|
||||
check_config_dir
|
||||
install_packages
|
||||
install_nvim
|
||||
install_config
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
log_success "Installation complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
218
tools/pnpm/tool.sh
Normal file
218
tools/pnpm/tool.sh
Normal file
@@ -0,0 +1,218 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: pnpm
|
||||
# DisplayName: Pnpm
|
||||
# Description: Install pnpm package manager
|
||||
# Strategy: binary
|
||||
#
|
||||
# pnpm Installer Script
|
||||
#
|
||||
# Installs pnpm (fast, disk-space-efficient package manager for Node.js).
|
||||
# Supports glibc and musl (Alpine) Linux on x86_64 and arm64.
|
||||
#
|
||||
# Linux runtime requirements:
|
||||
# - glibc 2.27+ and libatomic.so.1 (for glibc builds)
|
||||
# - Debian/Ubuntu: apt-get install -y libatomic1
|
||||
# - Fedora/RHEL: dnf install -y libatomic
|
||||
#
|
||||
# Docker usage:
|
||||
# curl -fsSL https://get.pnpm.io/install.sh | ENV="$HOME/.bashrc" SHELL="$(which bash)" bash -
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# ─── Helper Functions ─────────────────────────────────────────────────
|
||||
|
||||
download() {
|
||||
if [ -n "${2:-}" ]; then
|
||||
download_file "$1" "$2"
|
||||
else
|
||||
curl -fsSL "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
is_glibc_compatible() {
|
||||
getconf GNU_LIBC_VERSION >/dev/null 2>&1 || ldd --version >/dev/null 2>&1 || return 1
|
||||
}
|
||||
|
||||
# Detect libc suffix — empty for glibc, "-musl" for musl-based distros
|
||||
detect_libc_suffix() {
|
||||
if ! is_glibc_compatible; then
|
||||
printf -- '-musl'
|
||||
fi
|
||||
}
|
||||
|
||||
# pnpm v11.0.0-rc.3 renamed release assets. Older versions use legacy names.
|
||||
use_legacy_assets() {
|
||||
local version="$1"
|
||||
local major
|
||||
major="$(echo "$version" | cut -d. -f1)"
|
||||
if [ "$major" -lt 11 ] 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
case "$version" in
|
||||
11.0.0-rc.1|11.0.0-rc.2) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Legacy asset basename for pre-v11.0.0-rc.3 releases
|
||||
legacy_asset_basename() {
|
||||
local arch libc_suffix
|
||||
arch="$1"
|
||||
libc_suffix="$2"
|
||||
if [ -n "$libc_suffix" ]; then
|
||||
printf 'pnpm-linuxstatic-%s' "$arch"
|
||||
else
|
||||
printf 'pnpm-linux-%s' "$arch"
|
||||
fi
|
||||
}
|
||||
|
||||
# Release-page asset basename (without extension)
|
||||
asset_basename() {
|
||||
local version arch libc_suffix
|
||||
version="$1"
|
||||
arch="$2"
|
||||
libc_suffix="$3"
|
||||
if use_legacy_assets "$version"; then
|
||||
legacy_asset_basename "$arch" "$libc_suffix"
|
||||
else
|
||||
printf 'pnpm-linux-%s%s' "$arch" "$libc_suffix"
|
||||
fi
|
||||
}
|
||||
|
||||
# Map system arch to pnpm's naming (x64 / arm64)
|
||||
detect_pnpm_arch() {
|
||||
local arch
|
||||
arch="$(uname -m | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
case "${arch}" in
|
||||
x86_64 | amd64) arch="x64" ;;
|
||||
arm64 | aarch64) arch="arm64" ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
|
||||
# Double check 32-bit OS reported as 64-bit
|
||||
if [ "${arch}" = "x64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
|
||||
return 1
|
||||
elif [ "${arch}" = "arm64" ] && [ "$(getconf LONG_BIT)" -eq 32 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
printf '%s' "${arch}"
|
||||
}
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
|
||||
install_pnpm() {
|
||||
if has_command pnpm; then
|
||||
log_info "pnpm is already installed ($(pnpm --version))."
|
||||
fi
|
||||
|
||||
local arch libc_suffix version_json version major_version asset_base
|
||||
|
||||
arch="$(detect_pnpm_arch)" || {
|
||||
log_error "pnpm currently only provides pre-built binaries for x86_64/arm64 architectures."
|
||||
return 1
|
||||
}
|
||||
libc_suffix="$(detect_libc_suffix)"
|
||||
|
||||
# Fetch the latest version from GitHub, or use PNPM_VERSION if set
|
||||
if [ -z "${PNPM_VERSION:-}" ]; then
|
||||
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
|
||||
fi
|
||||
else
|
||||
version="${PNPM_VERSION}"
|
||||
fi
|
||||
|
||||
# Normalize major version (strip leading "v", extract digits)
|
||||
major_version="$(printf '%s' "$version" | sed -E 's/^v//; s/^([0-9]+).*/\1/')"
|
||||
if [ -z "$major_version" ]; then
|
||||
log_error "Invalid PNPM_VERSION: $version"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Downloading pnpm v${version} (linux-${arch}${libc_suffix})..."
|
||||
asset_base="$(asset_basename "$version" "$arch" "$libc_suffix")"
|
||||
|
||||
if [ "$major_version" -ge 11 ]; then
|
||||
# v11+: distributed as tarballs containing the binary and dist/ directory
|
||||
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
|
||||
}
|
||||
tar -xzf "$TMP_DIR/pnpm.tar.gz" -C "$TMP_DIR" || {
|
||||
log_error "Failed to extract pnpm tarball."
|
||||
return 1
|
||||
}
|
||||
chmod +x "$TMP_DIR/pnpm"
|
||||
SHELL="${SHELL:-/bin/bash}" "$TMP_DIR/pnpm" setup --force || {
|
||||
log_error "pnpm setup failed."
|
||||
return 1
|
||||
}
|
||||
else
|
||||
# Older versions: distributed as a single executable binary
|
||||
github_download_asset "pnpm/pnpm" "v${version}" "${asset_base}" "$TMP_DIR/pnpm" || {
|
||||
log_error "Failed to download pnpm binary."
|
||||
return 1
|
||||
}
|
||||
chmod +x "$TMP_DIR/pnpm"
|
||||
SHELL="${SHELL:-/bin/bash}" "$TMP_DIR/pnpm" setup --force || {
|
||||
log_error "pnpm setup failed."
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
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() {
|
||||
|
||||
# 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="$BOOTSTRAP_RUNTIMES/pnpm"
|
||||
case ":$PATH:" in
|
||||
*":$PNPM_HOME:"*) ;;
|
||||
*) export PATH="$PNPM_HOME:$PATH" ;;
|
||||
esac
|
||||
EOF
|
||||
)
|
||||
|
||||
write_env_snippet "pnpm" "$content"
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────
|
||||
|
||||
main() {
|
||||
install_pnpm
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
if has_command pnpm; then
|
||||
log_success "pnpm installation and configuration complete."
|
||||
log_info "Installed pnpm version: $(pnpm --version 2>/dev/null || echo 'unknown')"
|
||||
else
|
||||
log_success "Installation complete."
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
104
tools/rust/tool.sh
Normal file
104
tools/rust/tool.sh
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/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)
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
detect_target_triple() {
|
||||
local ostype
|
||||
ostype="$(uname -s)"
|
||||
if [ "$ostype" != "Linux" ]; then
|
||||
log_error "This simplified installer only supports Linux."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local clibtype="gnu"
|
||||
if ldd --version 2>&1 | grep -q 'musl'; then
|
||||
clibtype="musl"
|
||||
fi
|
||||
|
||||
local raw_arch
|
||||
raw_arch="$(uname -m)"
|
||||
local cputype
|
||||
case "$raw_arch" in
|
||||
x86_64) cputype="x86_64" ;;
|
||||
aarch64|arm64) cputype="aarch64" ;;
|
||||
armv7l|armv8l|armv7) cputype="armv7" ;;
|
||||
i386|i486|i686|x86) cputype="i686" ;;
|
||||
*) cputype="$raw_arch" ;;
|
||||
esac
|
||||
|
||||
local target="${cputype}-unknown-linux-${clibtype}"
|
||||
if [ "$cputype" = "armv7" ]; then
|
||||
target="${cputype}-unknown-linux-gnueabihf"
|
||||
fi
|
||||
|
||||
echo "$target"
|
||||
}
|
||||
|
||||
install_rust() {
|
||||
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
|
||||
|
||||
|
||||
|
||||
local target
|
||||
target=$(detect_target_triple)
|
||||
log_info "Detected target triple: $target"
|
||||
|
||||
local url="https://static.rust-lang.org/rustup/dist/${target}/rustup-init"
|
||||
|
||||
local dest="$TMP_DIR/rustup-init"
|
||||
|
||||
log_info "Downloading rustup-init..."
|
||||
download_file "$url" "$dest"
|
||||
|
||||
chmod +x "$dest"
|
||||
|
||||
log_info "Running rustup-init..."
|
||||
# Run the downloaded binary
|
||||
# -y: skip prompts (we already confirmed)
|
||||
# --no-modify-path: let bootstrap manage the shell paths
|
||||
"$dest" -y --no-modify-path
|
||||
|
||||
add_rollback_cmd "rustup self uninstall -y"
|
||||
register_tool "rust" "managed" "" "rustup"
|
||||
}
|
||||
|
||||
configure_shell() {
|
||||
|
||||
|
||||
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() {
|
||||
install_rust
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
log_success "Rust (rustup) installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
76
tools/starship/tool.sh
Normal file
76
tools/starship/tool.sh
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: starship
|
||||
# DisplayName: Starship
|
||||
# Description: Install Starship shell prompt
|
||||
# Strategy: binary
|
||||
#
|
||||
# Starship Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
install_starship() {
|
||||
if has_command starship || [ -f "$HOME/.local/bin/starship" ]; then
|
||||
log_info "Starship is already installed."
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
local raw_arch
|
||||
raw_arch=$(detect_arch)
|
||||
local arch=""
|
||||
case "$raw_arch" in
|
||||
x86_64) arch="x86_64" ;;
|
||||
arm64) arch="aarch64" ;;
|
||||
*) log_error "Unsupported Linux architecture: $raw_arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
local target="${arch}-unknown-linux-musl"
|
||||
|
||||
log_info "Fetching latest Starship version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(github_get_latest_release "starship/starship")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="latest"
|
||||
fi
|
||||
|
||||
log_info "Downloading Starship ${latest_tag}..."
|
||||
local archive="$TMP_DIR/starship.tar.gz"
|
||||
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="$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() {
|
||||
|
||||
|
||||
write_env_snippet "starship" 'eval "$(starship init bash)"'
|
||||
}
|
||||
|
||||
main() {
|
||||
install_starship
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
log_success "Starship installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
87
tools/uv/tool.sh
Normal file
87
tools/uv/tool.sh
Normal file
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: uv
|
||||
# DisplayName: uv
|
||||
# Description: Fast Python package installer and resolver
|
||||
# Strategy: binary
|
||||
#
|
||||
# uv Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
install_uv() {
|
||||
if has_command uv || [ -f "$HOME/.local/bin/uv" ]; then
|
||||
if ! confirm "uv is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping uv installation."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
local raw_arch
|
||||
raw_arch=$(detect_arch)
|
||||
local arch=""
|
||||
case "$raw_arch" in
|
||||
x86_64) arch="x86_64" ;;
|
||||
arm64) arch="aarch64" ;;
|
||||
*) log_error "Unsupported Linux architecture: $raw_arch"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Determine target based on libc
|
||||
local target=""
|
||||
if ldd --version 2>&1 | grep -q "GLIBC"; then
|
||||
target="${arch}-unknown-linux-gnu"
|
||||
else
|
||||
target="${arch}-unknown-linux-musl"
|
||||
fi
|
||||
|
||||
log_info "Fetching latest uv version from GitHub..."
|
||||
local latest_tag=""
|
||||
latest_tag=$(github_get_latest_release "astral-sh/uv")
|
||||
|
||||
if [ -z "$latest_tag" ]; then
|
||||
latest_tag="latest"
|
||||
fi
|
||||
|
||||
log_info "Downloading uv ${latest_tag}..."
|
||||
local archive="$TMP_DIR/uv.tar.gz"
|
||||
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="$BOOTSTRAP_BIN"
|
||||
mkdir -p "$target_dir"
|
||||
log_info "Installing uv and uvx to $target_dir..."
|
||||
cp "$TMP_DIR/uv" "$target_dir/uv"
|
||||
cp "$TMP_DIR/uvx" "$target_dir/uvx"
|
||||
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() {
|
||||
|
||||
|
||||
write_env_snippet "uv" 'eval "$(uv generate-shell-completion bash)"'
|
||||
}
|
||||
|
||||
main() {
|
||||
install_uv
|
||||
configure_shell
|
||||
|
||||
echo
|
||||
log_success "uv installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
77
tools/yay/tool.sh
Executable file
77
tools/yay/tool.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: yay
|
||||
# DisplayName: Yay
|
||||
# Description: Install Yay AUR helper
|
||||
# Strategy: system
|
||||
#
|
||||
# Yay Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Installation Logic ──────────────────────────────────────────────
|
||||
|
||||
install_yay() {
|
||||
local distro
|
||||
distro=$(detect_distro)
|
||||
|
||||
if [ "$distro" != "arch" ]; then
|
||||
log_error "This installer only supports Arch Linux."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if has_command yay; then
|
||||
log_info "Yay is already installed."
|
||||
fi
|
||||
|
||||
local needs_install=false
|
||||
if ! pkg_check git; then
|
||||
needs_install=true
|
||||
fi
|
||||
if ! pkg_check base-devel && ! pacman -Qg base-devel &>/dev/null; then
|
||||
needs_install=true
|
||||
fi
|
||||
|
||||
if [ "$needs_install" = "true" ]; then
|
||||
log_info "Installing missing dependencies (git, base-devel)..."
|
||||
pkg_install git base-devel
|
||||
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
|
||||
clone_dir="$(pwd)/yay-bin"
|
||||
|
||||
# Remove any pre-existing clone directory to avoid git clone failure
|
||||
rm -rf "$clone_dir"
|
||||
|
||||
git clone https://aur.archlinux.org/yay-bin.git "$clone_dir"
|
||||
|
||||
# Store original directory to go back to it
|
||||
local orig_dir
|
||||
orig_dir="$(pwd)"
|
||||
|
||||
cd "$clone_dir"
|
||||
|
||||
log_info "Building and installing yay..."
|
||||
makepkg -si
|
||||
add_rollback_cmd "sudo pacman -R --noconfirm yay"
|
||||
|
||||
cd "$orig_dir"
|
||||
log_info "Cleaning up installer directory..."
|
||||
rm -rf "$clone_dir"
|
||||
register_tool "yay" "system" "" "aur:yay-bin"
|
||||
}
|
||||
|
||||
# ─── Main ─────────────────────────────────────────────────────────────
|
||||
|
||||
main() {
|
||||
install_yay
|
||||
|
||||
echo
|
||||
log_success "Yay installation complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
105
tools/yazi/tool.sh
Executable file
105
tools/yazi/tool.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tool: yazi
|
||||
# DisplayName: Yazi
|
||||
# Description: Install Yazi terminal file manager and dependencies
|
||||
# Strategy: binary
|
||||
#
|
||||
# Yazi Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TMP_DIR="$(make_temp_dir)"
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
add_y_wrapper() {
|
||||
|
||||
local wrapper_content
|
||||
wrapper_content=$(cat << 'EOF'
|
||||
# Shell wrapper for yazi to change directory on exit
|
||||
y() {
|
||||
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
|
||||
yazi "$@" --cwd-file="$tmp"
|
||||
if cwd="$(command cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
|
||||
builtin cd -- "$cwd"
|
||||
fi
|
||||
rm -f -- "$tmp"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
write_alias_snippet "yazi" "$wrapper_content"
|
||||
}
|
||||
|
||||
install_yazi() {
|
||||
if has_command yazi; then
|
||||
if ! confirm "Yazi is already installed. Reinstall/Upgrade?"; then
|
||||
log_info "Skipping Yazi installation."
|
||||
return
|
||||
fi
|
||||
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() {
|
||||
install_yazi
|
||||
add_y_wrapper
|
||||
echo
|
||||
log_success "Yazi installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
53
tools/zoxide/tool.sh
Executable file
53
tools/zoxide/tool.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2016
|
||||
# Tool: zoxide
|
||||
# DisplayName: Zoxide
|
||||
# Description: Install Zoxide directory jumper
|
||||
# Strategy: managed
|
||||
#
|
||||
# Zoxide Installer Script
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
install_fzf() {
|
||||
if has_command fzf; then
|
||||
log_info "fzf is already installed."
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "fzf not found. Installing fzf..."
|
||||
pkg_install fzf
|
||||
registry_add_sys_deps "zoxide" "fzf"
|
||||
}
|
||||
|
||||
install_zoxide() {
|
||||
if has_command zoxide || [ -f "$HOME/.local/bin/zoxide" ]; then
|
||||
log_info "Zoxide is already installed."
|
||||
fi
|
||||
|
||||
|
||||
|
||||
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() {
|
||||
|
||||
|
||||
write_env_snippet "zoxide" 'eval "$(zoxide init --cmd cd bash)"'
|
||||
}
|
||||
|
||||
main() {
|
||||
install_zoxide
|
||||
configure_shell
|
||||
install_fzf
|
||||
|
||||
echo
|
||||
log_success "Zoxide installation and configuration complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user