From 004946f4b2c0322ceae48d69fc6fb58c5d5182b2 Mon Sep 17 00:00:00 2001 From: Aditya Gupta Date: Sat, 20 Jun 2026 22:15:09 +0530 Subject: [PATCH] feat: Add uv --- .agents/skills/add_installer/SKILL.md | 7 ++ VERSION | 2 +- installers/install_uv.sh | 139 ++++++++++++++++++++++++++ lib/registry.sh | 4 +- readme.md | 20 +++- 5 files changed, 165 insertions(+), 7 deletions(-) create mode 100644 installers/install_uv.sh diff --git a/.agents/skills/add_installer/SKILL.md b/.agents/skills/add_installer/SKILL.md index 04fe3d1..44fd7d4 100644 --- a/.agents/skills/add_installer/SKILL.md +++ b/.agents/skills/add_installer/SKILL.md @@ -38,6 +38,12 @@ When adding a new installer named ``: Create `installers/install_.sh` using the template below. +If the user provides an official install or curl script in the prompt: +- Read and analyze the script. +- Remove redundant parts like macOS and Windows compatibility. +- Strip unnecessary shell boilerplate, self-update logic, and other bloat. +- Implement only the essential Linux installation logic inside the `install_` function. + ### Step 2: Add metadata comments to the top of your installer script At the top of your new installer script, right below `#!/usr/bin/env bash`, add the following three metadata headers: @@ -262,3 +268,4 @@ inject_block "$config_file" " init" 'eval "$(tool init bash)"' 6. **Error handling**: Use `set -euo pipefail` after sourcing `bootstrap.sh`. 7. **Metascript boilerplate**: The first 22 lines of every installer are identical — always copy them verbatim. 8. **`main "$@"`**: Always end with this pattern to pass through CLI arguments. +9. **Clean Official Scripts**: When implementing official curl/install scripts provided in the prompt, strip them of bloat, macOS/Windows support, and redundant shell setups before writing the script. diff --git a/VERSION b/VERSION index 65087b4..0664a8f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.4 +1.1.6 diff --git a/installers/install_uv.sh b/installers/install_uv.sh new file mode 100644 index 0000000..8c4c2c6 --- /dev/null +++ b/installers/install_uv.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +# Tool: uv +# DisplayName: uv +# Description: Fast Python package installer and resolver +# +# uv Installer Script +# + +# Run metascript to check if the shell is bash and load libraries +PARENT_DIR="$(dirname "$0")/.." +METASCRIPT_LOCAL="$PARENT_DIR/bootstrap.sh" +METASCRIPT_URL="https://git.adityagupta.dev/sortedcord/bootstrap/raw/branch/master/bootstrap.sh" + +if [ -f "$METASCRIPT_LOCAL" ]; then + . "$METASCRIPT_LOCAL" +else + if command -v wget >/dev/null 2>&1; then + eval "$(wget -qO- "$METASCRIPT_URL")" + elif command -v curl >/dev/null 2>&1; then + eval "$(curl -fsSL "$METASCRIPT_URL")" + else + echo "Error: Neither wget nor curl is installed to fetch bootstrap.sh." >&2 + exit 1 + fi +fi + +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 + + # Ensure curl or wget is installed + if ! has_command curl && ! has_command wget; then + log_info "curl or wget not found. Installing curl..." + pkg_install curl + 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="" + if has_command curl; then + 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) + elif has_command wget; then + latest_tag=$(wget -qO- https://api.github.com/repos/astral-sh/uv/releases/latest | grep '"tag_name":' | head -n1 | sed -E 's/.*"tag_name": "([^"]+)".*/\1/' || true) + fi + + 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 + 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}..." + local archive="$TMP_DIR/uv.tar.gz" + if has_command curl; then + curl -fsSL "$download_url" -o "$archive" + else + wget -qO "$archive" "$download_url" + fi + + # 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" + 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" +} + +configure_shell() { + # Add ~/.local/bin to PATH for the current process + export PATH="$HOME/.local/bin:$PATH" + + IFS=' ' read -ra target_files <<< "$(get_shell_configs)" + + for config_file in "${target_files[@]}"; do + # Ensure ~/.local/bin is in PATH for this file if not already present + if ! grep -q '\.local/bin' "$config_file" 2>/dev/null; then + log_info "Adding ~/.local/bin to PATH in $config_file..." + local path_content='export PATH="$HOME/.local/bin:$PATH"' + inject_block "$config_file" "local-bin path" "$path_content" + fi + + log_info "Adding uv completion to $config_file..." + local content='eval "$(uv generate-shell-completion bash)"' + inject_block "$config_file" "uv completion" "$content" + + # Source to apply changes in the current context + if [ "$config_file" = "$HOME/.bashrc" ]; then + . "$config_file" 2>/dev/null || true + fi + done +} + +main() { + install_uv + configure_shell + + echo + log_success "uv installation and configuration complete." +} + +main "$@" diff --git a/lib/registry.sh b/lib/registry.sh index 50aec76..c338b82 100644 --- a/lib/registry.sh +++ b/lib/registry.sh @@ -8,6 +8,7 @@ declare -A INSTALLERS=( [pnpm]="Install pnpm package manager" [rust]="Install Rustup and Rust compiler/toolchain" [starship]="Install Starship shell prompt" + [uv]="Fast Python package installer and resolver" [yay]="Install Yay AUR helper" [yazi]="Install Yazi terminal file manager and dependencies" [zoxide]="Install Zoxide directory jumper" @@ -21,9 +22,10 @@ declare -A INSTALLER_DISPLAYS=( [pnpm]="Pnpm" [rust]="Rust" [starship]="Starship" + [uv]="uv" [yay]="Yay" [yazi]="Yazi" [zoxide]="Zoxide" ) -INSTALLER_KEYS=(agy bat node nvim pnpm rust starship yay yazi zoxide) +INSTALLER_KEYS=(agy bat node nvim pnpm rust starship uv yay yazi zoxide) diff --git a/readme.md b/readme.md index 7942f7e..3893955 100644 --- a/readme.md +++ b/readme.md @@ -19,6 +19,7 @@ Here is a comparison of the size and complexity of using Bootstrap (`to b`) vers | **PNPM (`pnpm`)** | 245 lines | 213 lines (Official get.pnpm.io script) | | **Rust (`rust`)** | 155 lines | 921 lines (Official sh.rustup.rs script) | | **Starship (`starship`)** | 132 lines | 554 lines (Official starship.rs script) | +| **uv (`uv`)** | 139 lines | 2184 lines (Official uv install script) | | **Yay (`yay`)** | 96 lines | N/A (Official manual build process) | | **Yazi (`yazi`)** | 163 lines | N/A (Standard package install) | | **Zoxide (`zoxide`)** | 90 lines | 466 lines (Official zoxide install script) | @@ -33,12 +34,10 @@ To bootstrap a new machine and set up the `b` command tool, run the following: curl -fsSL https://adityagupta.dev/b | bash ``` -Once bootstrapped, you can run any installer script using the `b` command followed by its shortcut name. You can also chain multiple installations by separating their names with a comma: +Once bootstrapped, you list all commands available - ```bash -b nvim -b yazi -b nvim,yazi +b all ``` ### Inspecting and Editing Installers (`b ware`) @@ -56,6 +55,8 @@ To bypass the editor and install the tool directly using the `ware` command, app ```bash b ware nvim -y +# or directly: +b nvim ``` To list all available installer tools and their descriptions, run the `ware` (or `bware`) command without any arguments: @@ -64,6 +65,8 @@ To list all available installer tools and their descriptions, run the `ware` (or b ware ``` +### Editing Configurations (`b con`) + You can also edit configurations located in your `~/.config/` directory by running: ```bash @@ -71,7 +74,9 @@ b con nvim b con i3 ``` -It automatically fuzzy-finds the folder in case there is no exact match. +It automatically fuzzy-finds the folder in case there is no exact match. Also, in case there is only a singular config file in that folder, then it will directly open that file. + +### Updating To check for updates and update the tool manually: @@ -115,6 +120,7 @@ The scripts are intentionally straightforward Bash scripts that can be inspected Potential additions include: +* RSA based authentication * Development environment bootstrap * Workstation setup * Server provisioning @@ -142,6 +148,10 @@ curl -fsSL https://git.adityagupta.dev/sortedcord/bootstrap/raw/branch/master/li and review the contents before piping it into a shell. +## Should I Use It? + +Hell no, go make your own. + ## License MIT