From a3dde62e4babe226fc4ab5ba6131ca4cb679307e Mon Sep 17 00:00:00 2001 From: rUv Date: Thu, 27 Nov 2025 05:10:57 +0000 Subject: [PATCH] fix: Rewrite install.sh with proper error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes all critical issues from review: 🔴 Critical fixes: - Remove fake library crate installation (cargo install doesn't work) - Fix CLI "not available" error - now installs ruvector-cli@0.1.2 - Show all output instead of silent error suppression - Pin versions: ruvector-cli@0.1.2, ruvector@0.1.23 🟡 Moderate fixes: - Check if ~/.cargo/env exists before sourcing - Add Windows detection with helpful warnings - Add dependency check for curl and C compiler - Show platform-specific install instructions 🟢 Additional improvements: - Add --uninstall option with instructions - Add --cli-only option - Show installation summary at end - Clarify library crates need 'cargo add' not 'cargo install' - Better error messages with actionable fixes - Disable colors when not in terminal 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- install.sh | 338 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 250 insertions(+), 88 deletions(-) diff --git a/install.sh b/install.sh index 8b414453..21dce628 100755 --- a/install.sh +++ b/install.sh @@ -3,15 +3,25 @@ # Usage: curl -fsSL https://raw.githubusercontent.com/ruvnet/ruvector/main/install.sh | bash # Or: wget -qO- https://raw.githubusercontent.com/ruvnet/ruvector/main/install.sh | bash -set -e +# Don't exit on error - we handle errors manually +set +e -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color +# Colors (disable if not a terminal) +if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + YELLOW='\033[1;33m' + BLUE='\033[0;34m' + CYAN='\033[0;36m' + NC='\033[0m' +else + RED='' + GREEN='' + YELLOW='' + BLUE='' + CYAN='' + NC='' +fi print_banner() { echo -e "${CYAN}" @@ -43,13 +53,17 @@ print_warning() { # Detect OS and architecture detect_platform() { - OS="$(uname -s)" - ARCH="$(uname -m)" + OS="$(uname -s 2>/dev/null || echo "Unknown")" + ARCH="$(uname -m 2>/dev/null || echo "Unknown")" case "$OS" in Linux*) PLATFORM="linux" ;; Darwin*) PLATFORM="darwin" ;; - MINGW*|MSYS*|CYGWIN*) PLATFORM="windows" ;; + MINGW*|MSYS*|CYGWIN*) + PLATFORM="windows" + print_warning "Windows detected. For best results, use WSL2 or run in Git Bash." + print_warning "Native Windows: use 'cargo install' manually after installing Rust." + ;; *) PLATFORM="unknown" ;; esac @@ -67,6 +81,38 @@ command_exists() { command -v "$1" >/dev/null 2>&1 } +# Check for required build dependencies +check_dependencies() { + print_step "Checking dependencies..." + + local missing=() + + # curl or wget required + if ! command_exists curl && ! command_exists wget; then + missing+=("curl or wget") + fi + + # Check for C compiler (needed for Rust builds) + if ! command_exists cc && ! command_exists gcc && ! command_exists clang; then + missing+=("C compiler (gcc/clang)") + fi + + if [ ${#missing[@]} -gt 0 ]; then + print_warning "Missing optional dependencies: ${missing[*]}" + echo " Some crates may fail to compile without a C compiler." + + if [ "$PLATFORM" = "linux" ]; then + echo " Install with: sudo apt-get install build-essential (Debian/Ubuntu)" + echo " or: sudo yum groupinstall 'Development Tools' (RHEL/CentOS)" + elif [ "$PLATFORM" = "darwin" ]; then + echo " Install with: xcode-select --install" + fi + echo "" + else + print_success "All dependencies found" + fi +} + # Install Rust if not present install_rust() { if command_exists rustc; then @@ -75,86 +121,121 @@ install_rust() { return 0 fi - print_step "Installing Rust..." - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - source "$HOME/.cargo/env" - print_success "Rust installed" -} + print_step "Installing Rust via rustup..." -# Install from crates.io -install_crates() { - print_step "Installing RuVector crates from crates.io..." - - local CRATES=( - "ruvector-core" - "ruvector-graph" - "ruvector-gnn" - "ruvector-collections" - "ruvector-filter" - "ruvector-metrics" - "ruvector-snapshot" - ) - - for crate in "${CRATES[@]}"; do - echo -n " Installing ${crate}... " - if cargo install "$crate" --quiet 2>/dev/null; then - echo -e "${GREEN}done${NC}" - else - echo -e "${YELLOW}skipped (library crate)${NC}" - fi - done - - print_success "Core crates installed" -} - -# Install CLI tools -install_cli() { - print_step "Installing RuVector CLI tools..." - - if cargo install ruvector-cli --quiet 2>/dev/null; then - print_success "ruvector-cli installed" - else - print_warning "ruvector-cli not available on crates.io yet" + if ! command_exists curl; then + print_error "curl is required to install Rust" + echo " Install curl first, then re-run this script" + return 1 fi + + if curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; then + # Source cargo env if it exists + if [ -f "$HOME/.cargo/env" ]; then + . "$HOME/.cargo/env" + elif [ -f "$HOME/.cargo/bin/cargo" ]; then + export PATH="$HOME/.cargo/bin:$PATH" + fi + + if command_exists rustc; then + print_success "Rust installed successfully" + return 0 + else + print_error "Rust installation completed but rustc not found in PATH" + echo " Try running: source \$HOME/.cargo/env" + return 1 + fi + else + print_error "Failed to install Rust" + return 1 + fi +} + +# Install CLI binary from crates.io +install_cli() { + print_step "Installing ruvector-cli from crates.io..." + + if ! command_exists cargo; then + print_error "cargo not found. Install Rust first." + return 1 + fi + + # Install with visible output so users can see progress/errors + echo " Running: cargo install ruvector-cli@0.1.2" + if cargo install ruvector-cli@0.1.2 2>&1 | while read -r line; do echo " $line"; done; then + if command_exists ruvector-cli; then + print_success "ruvector-cli installed" + return 0 + fi + fi + + # Check if it was already installed + if command_exists ruvector-cli; then + print_success "ruvector-cli already installed" + return 0 + fi + + print_warning "ruvector-cli installation had issues" + echo " This may be due to missing build dependencies." + echo " Try manually: cargo install ruvector-cli" + return 1 } # Install Node.js packages install_npm() { if ! command_exists node; then - print_warning "Node.js not found, skipping npm packages" + print_warning "Node.js not found - skipping npm packages" + echo " Install Node.js from https://nodejs.org to use npm packages" return 0 fi print_step "Installing npm packages..." - if command_exists npm; then - npm install -g ruvector 2>/dev/null || true - print_success "npm packages installed" + if ! command_exists npm; then + print_warning "npm not found" + return 1 + fi + + NODE_VERSION=$(node --version) + print_success "Node.js ${NODE_VERSION} detected" + + # Install with visible output + echo " Running: npm install -g ruvector@0.1.23" + if npm install -g ruvector@0.1.23 2>&1 | while read -r line; do echo " $line"; done; then + print_success "ruvector npm package installed" + else + print_warning "npm install had issues (may need sudo on some systems)" + echo " Try: sudo npm install -g ruvector" + echo " Or use npx: npx ruvector" fi } -# Show available crates +# Show available crates (informational - these are LIBRARY crates) show_crates() { echo "" - echo -e "${CYAN}Available RuVector Crates:${NC}" + echo -e "${CYAN}Available RuVector Rust Crates:${NC}" echo "" - echo -e "${GREEN}Core:${NC}" - echo " cargo add ruvector-core # Vector database engine" - echo " cargo add ruvector-graph # Hypergraph with Cypher" - echo " cargo add ruvector-gnn # Graph Neural Networks" + echo -e "${GREEN}Add to your Cargo.toml with 'cargo add':${NC}" echo "" - echo -e "${GREEN}Distributed:${NC}" - echo " cargo add ruvector-cluster # Cluster management" - echo " cargo add ruvector-raft # Raft consensus" - echo " cargo add ruvector-replication # Data replication" + echo " # Core (vector database)" + echo " cargo add ruvector-core@0.1.2" echo "" - echo -e "${GREEN}AI Routing:${NC}" - echo " cargo add ruvector-tiny-dancer-core # FastGRNN inference" - echo " cargo add ruvector-router-core # Semantic routing" + echo " # Graph database with Cypher" + echo " cargo add ruvector-graph@0.1.2" echo "" - echo -e "${GREEN}Bindings:${NC}" - echo " cargo add ruvector-node # Node.js (napi-rs)" - echo " cargo add ruvector-wasm # WebAssembly" + echo " # Graph Neural Networks" + echo " cargo add ruvector-gnn@0.1.2" + echo "" + echo " # Distributed systems" + echo " cargo add ruvector-cluster@0.1.2" + echo " cargo add ruvector-raft@0.1.2" + echo " cargo add ruvector-replication@0.1.2" + echo "" + echo " # AI routing" + echo " cargo add ruvector-tiny-dancer-core@0.1.2" + echo " cargo add ruvector-router-core@0.1.2" + echo "" + echo -e "${YELLOW}Note: These are library crates. Use 'cargo add' in your project.${NC}" echo "" } @@ -162,13 +243,32 @@ show_crates() { show_npm() { echo -e "${CYAN}Available npm Packages:${NC}" echo "" - echo " npm install ruvector # All-in-one CLI" - echo " npm install @ruvector/core # Vector database" - echo " npm install @ruvector/gnn # Graph Neural Networks" - echo " npm install @ruvector/graph-node # Hypergraph database" + echo " # All-in-one CLI (recommended)" + echo " npm install ruvector" + echo " npx ruvector" echo "" - echo " npx ruvector install # List all packages" - echo " npx ruvector install --all # Install everything" + echo " # Individual packages" + echo " npm install @ruvector/core # Vector database" + echo " npm install @ruvector/gnn # Graph Neural Networks" + echo " npm install @ruvector/graph-node # Hypergraph database" + echo "" + echo " # List all available packages" + echo " npx ruvector install" + echo "" +} + +# Show uninstall instructions +show_uninstall() { + echo -e "${CYAN}Uninstall Instructions:${NC}" + echo "" + echo " # Remove CLI binary" + echo " cargo uninstall ruvector-cli" + echo "" + echo " # Remove npm packages" + echo " npm uninstall -g ruvector" + echo "" + echo " # Remove Rust entirely (optional)" + echo " rustup self uninstall" echo "" } @@ -182,9 +282,10 @@ main() { # Parse arguments INSTALL_RUST=true - INSTALL_CRATES=true + INSTALL_CLI=true INSTALL_NPM=true SHOW_ONLY=false + SHOW_UNINSTALL=false while [[ $# -gt 0 ]]; do case $1 in @@ -194,78 +295,139 @@ main() { ;; --npm-only) INSTALL_RUST=false - INSTALL_CRATES=false + INSTALL_CLI=false + shift + ;; + --cli-only) + INSTALL_NPM=false shift ;; --list|--show) SHOW_ONLY=true shift ;; + --uninstall) + SHOW_UNINSTALL=true + shift + ;; --help|-h) echo "Usage: install.sh [OPTIONS]" echo "" echo "Options:" - echo " --rust-only Only install Rust crates" - echo " --npm-only Only install npm packages" + echo " --rust-only Install Rust and CLI only (no npm)" + echo " --npm-only Install npm packages only (no Rust)" + echo " --cli-only Install ruvector-cli binary only" echo " --list Show available packages without installing" + echo " --uninstall Show uninstall instructions" echo " --help Show this help" echo "" echo "Examples:" echo " curl -fsSL https://raw.githubusercontent.com/ruvnet/ruvector/main/install.sh | bash" echo " curl -fsSL ... | bash -s -- --rust-only" echo " curl -fsSL ... | bash -s -- --npm-only" + echo " curl -fsSL ... | bash -s -- --list" exit 0 ;; *) print_error "Unknown option: $1" + echo "Use --help for usage information" exit 1 ;; esac done + if [ "$SHOW_UNINSTALL" = true ]; then + show_uninstall + exit 0 + fi + if [ "$SHOW_ONLY" = true ]; then show_crates show_npm exit 0 fi + # Check dependencies + check_dependencies + + # Track what was installed + INSTALLED_RUST=false + INSTALLED_CLI=false + INSTALLED_NPM=false + # Install Rust if [ "$INSTALL_RUST" = true ]; then - install_rust + if install_rust; then + INSTALLED_RUST=true + fi echo "" fi - # Install crates - if [ "$INSTALL_CRATES" = true ]; then - install_crates + # Install CLI + if [ "$INSTALL_CLI" = true ] && [ "$INSTALLED_RUST" = true ] || command_exists cargo; then + if install_cli; then + INSTALLED_CLI=true + fi echo "" fi # Install npm if [ "$INSTALL_NPM" = true ]; then - install_npm + if install_npm; then + INSTALLED_NPM=true + fi echo "" fi # Show summary echo "" echo -e "${GREEN}════════════════════════════════════════════════════════════${NC}" - echo -e "${GREEN} RuVector installed successfully!${NC}" + echo -e "${GREEN} Installation Summary${NC}" echo -e "${GREEN}════════════════════════════════════════════════════════════${NC}" echo "" + if [ "$INSTALLED_RUST" = true ] || command_exists rustc; then + RUST_V=$(rustc --version 2>/dev/null | cut -d' ' -f2 || echo "installed") + echo -e " Rust: ${GREEN}✓${NC} ${RUST_V}" + else + echo -e " Rust: ${YELLOW}○${NC} not installed" + fi + + if [ "$INSTALLED_CLI" = true ] || command_exists ruvector-cli; then + echo -e " ruvector-cli: ${GREEN}✓${NC} installed" + else + echo -e " ruvector-cli: ${YELLOW}○${NC} not installed" + fi + + if command_exists node; then + NODE_V=$(node --version) + echo -e " Node.js: ${GREEN}✓${NC} ${NODE_V}" + if npm list -g ruvector >/dev/null 2>&1; then + echo -e " ruvector npm: ${GREEN}✓${NC} installed" + else + echo -e " ruvector npm: ${YELLOW}○${NC} use 'npx ruvector'" + fi + else + echo -e " Node.js: ${YELLOW}○${NC} not installed" + fi + + echo "" + show_crates show_npm echo -e "${CYAN}Quick Start:${NC}" echo "" - echo " # Rust" + echo " # Rust project" + echo " cargo new my-vector-app && cd my-vector-app" echo " cargo add ruvector-core ruvector-gnn" echo "" echo " # Node.js" - echo " npx ruvector" + echo " npx ruvector info" + echo " npx ruvector benchmark" echo "" echo -e "${CYAN}Documentation:${NC} https://github.com/ruvnet/ruvector" + echo -e "${CYAN}Issues:${NC} https://github.com/ruvnet/ruvector/issues" echo "" }