Files
wehub-resource-sync 70cb81e982
CI / Test (macos-latest, stable) (push) Has been cancelled
CI / Test (ubuntu-latest, stable) (push) Has been cancelled
CI / Test (windows-latest, stable) (push) Has been cancelled
CI / Lint (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:45:24 +08:00

498 lines
15 KiB
Bash
Executable File

#!/bin/bash
# Memvid Installer for macOS and Linux
# v1 - System package managers only, install-if-missing
set -e
# Colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Print success message
print_success() {
echo -e "${GREEN}${NC} $1"
}
# Print error message
print_error() {
echo -e "${RED}${NC} $1"
}
# Print info message
print_info() {
echo -e "${BLUE}${NC} $1"
}
# Print warning message
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
# Detect OS
detect_os() {
if [[ "$OSTYPE" == "darwin"* ]]; then
OS="macos"
PKG_MANAGER="brew"
# Check if Homebrew is installed
if ! command_exists brew; then
print_error "Homebrew is not installed"
print_info "Please install Homebrew first:"
print_info " /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
exit 1
fi
elif [[ -f /etc/os-release ]]; then
. /etc/os-release
DISTRO_NAME="${PRETTY_NAME:-${NAME:-$ID}}"
if [[ "$ID" == "ubuntu" ]] || [[ "$ID" == "debian" ]]; then
OS="linux"
PKG_MANAGER="apt"
DISTRO_FAMILY="debian"
elif [[ "$ID" == "fedora" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "centos" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]]; then
OS="linux"
PKG_MANAGER="dnf"
DISTRO_FAMILY="rhel"
elif [[ "$ID" == "arch" ]] || [[ "$ID" == "manjaro" ]]; then
OS="linux"
PKG_MANAGER="pacman"
DISTRO_FAMILY="arch"
elif [[ "$ID" == "alpine" ]]; then
OS="linux"
PKG_MANAGER="apk"
DISTRO_FAMILY="alpine"
else
print_error "Unsupported Linux distribution: $ID"
print_info "Supported distributions: Ubuntu, Debian, Fedora, RHEL, CentOS, Arch, Alpine"
exit 1
fi
# Check if sudo is available (except for Alpine which might use su)
if ! command_exists sudo && [[ "$DISTRO_FAMILY" != "alpine" ]]; then
print_error "sudo is not available"
print_info "Please install sudo or run as root"
exit 1
fi
else
print_error "Unable to detect operating system"
exit 1
fi
if [[ "$OS" == "linux" ]]; then
print_info "Detected OS: $OS ($DISTRO_NAME)"
else
print_info "Detected OS: $OS"
fi
}
# Check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check for Xcode Command Line Tools on macOS
check_xcode_cli_tools() {
if [[ "$OS" != "macos" ]]; then
return 0
fi
# Check if Xcode CLI Tools are installed
if xcode-select -p &>/dev/null; then
print_success "Xcode Command Line Tools already installed"
return 0
else
print_error "Xcode Command Line Tools not found"
print_warning "Xcode Command Line Tools are required for everything to work properly"
echo ""
# Ask for confirmation
if [[ -t 0 ]] && [[ -t 1 ]]; then
read -p "Install Xcode Command Line Tools now? [Y/n] " -n 1 -r
echo
elif [[ -c /dev/tty ]]; then
read -p "Install Xcode Command Line Tools now? [Y/n] " -n 1 -r < /dev/tty
echo
else
REPLY="Y"
fi
if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ ! $REPLY == "" ]]; then
print_error "Xcode Command Line Tools are required for everything to work properly"
print_info "Please install them manually with: xcode-select --install"
exit 1
fi
print_info "Installing Xcode Command Line Tools..."
xcode-select --install
print_info "Please complete the Xcode Command Line Tools installation in the popup window"
print_info "Then run this installer again"
exit 0
fi
}
# Install system dependencies for Linux
install_system_deps() {
if [[ "$OS" != "linux" ]]; then
return 0
fi
print_info "Checking system dependencies..."
NEEDS_DEPS=false
DEPS_TO_INSTALL=()
# Check and collect missing dependencies
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
if ! dpkg -l | grep -q "^ii.*ca-certificates"; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("ca-certificates")
fi
if ! command_exists curl; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("curl")
fi
if ! dpkg -l | grep -q "^ii.*libssl3"; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("libssl3")
fi
elif [[ "$DISTRO_FAMILY" == "rhel" ]]; then
if ! rpm -q ca-certificates &>/dev/null; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("ca-certificates")
fi
if ! command_exists curl; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("curl")
fi
if ! rpm -q openssl &>/dev/null; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("openssl")
fi
elif [[ "$DISTRO_FAMILY" == "arch" ]]; then
if ! pacman -Q ca-certificates &>/dev/null; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("ca-certificates")
fi
if ! command_exists curl; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("curl")
fi
if ! pacman -Q openssl &>/dev/null; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("openssl")
fi
elif [[ "$DISTRO_FAMILY" == "alpine" ]]; then
if ! apk info -e ca-certificates &>/dev/null; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("ca-certificates")
fi
if ! command_exists curl; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("curl")
fi
if ! apk info -e openssl &>/dev/null; then
NEEDS_DEPS=true
DEPS_TO_INSTALL+=("openssl")
fi
fi
if [[ "$NEEDS_DEPS" == false ]]; then
print_success "All system dependencies are installed"
return 0
fi
print_info "Installing system dependencies: ${DEPS_TO_INSTALL[*]}..."
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
sudo apt-get update
sudo apt-get install -y --no-install-recommends "${DEPS_TO_INSTALL[@]}"
elif [[ "$DISTRO_FAMILY" == "rhel" ]]; then
sudo dnf install -y "${DEPS_TO_INSTALL[@]}"
elif [[ "$DISTRO_FAMILY" == "arch" ]]; then
sudo pacman -S --noconfirm "${DEPS_TO_INSTALL[@]}"
elif [[ "$DISTRO_FAMILY" == "alpine" ]]; then
if command_exists sudo; then
sudo apk add --no-cache "${DEPS_TO_INSTALL[@]}"
else
apk add --no-cache "${DEPS_TO_INSTALL[@]}"
fi
fi
print_success "System dependencies installed successfully"
}
# Check for git
check_git() {
if command_exists git; then
GIT_VERSION=$(git --version | cut -d' ' -f3)
print_success "git already installed (version $GIT_VERSION)"
return 0
else
print_error "git not found"
return 1
fi
}
# Check for node
check_node() {
if command_exists node; then
NODE_VERSION=$(node --version)
print_success "node already installed ($NODE_VERSION)"
# Check if it's LTS (rough check - version should be even major version)
MAJOR_VERSION=$(echo "$NODE_VERSION" | cut -d'v' -f2 | cut -d'.' -f1)
if [ "$((MAJOR_VERSION % 2))" -eq 0 ]; then
print_info "Node version appears to be LTS-compatible"
fi
# Check for npm
if command_exists npm; then
NPM_VERSION=$(npm --version)
print_success "npm already installed (version $NPM_VERSION)"
return 0
else
print_error "npm not found (should come with node)"
return 1
fi
else
print_error "node not found"
return 1
fi
}
# Install git
install_git() {
print_info "Installing git using $PKG_MANAGER..."
if [[ "$OS" == "macos" ]]; then
brew install git
elif [[ "$OS" == "linux" ]]; then
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
sudo apt-get update
sudo apt-get install -y git
elif [[ "$DISTRO_FAMILY" == "rhel" ]]; then
sudo dnf install -y git
elif [[ "$DISTRO_FAMILY" == "arch" ]]; then
sudo pacman -S --noconfirm git
elif [[ "$DISTRO_FAMILY" == "alpine" ]]; then
if command_exists sudo; then
sudo apk add --no-cache git
else
apk add --no-cache git
fi
fi
fi
if command_exists git; then
print_success "git installed successfully"
else
print_error "git installation failed"
exit 1
fi
}
# Install node (LTS)
install_node() {
print_info "Installing node (LTS) using $PKG_MANAGER..."
if [[ "$OS" == "macos" ]]; then
brew install node@lts
# Add to PATH if needed
if ! command_exists node; then
print_info "Adding node to PATH..."
# Detect Homebrew prefix (Apple Silicon vs Intel)
if [[ -d "/opt/homebrew" ]]; then
BREW_PREFIX="/opt/homebrew"
else
BREW_PREFIX="/usr/local"
fi
# Detect shell
if [[ "$SHELL" == *"zsh"* ]]; then
SHELL_RC="$HOME/.zshrc"
else
SHELL_RC="$HOME/.bash_profile"
fi
echo "export PATH=\"$BREW_PREFIX/opt/node@lts/bin:\$PATH\"" >> "$SHELL_RC"
export PATH="$BREW_PREFIX/opt/node@lts/bin:$PATH"
fi
elif [[ "$OS" == "linux" ]]; then
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
# Install Node.js LTS from NodeSource
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y --no-install-recommends nodejs
elif [[ "$DISTRO_FAMILY" == "rhel" ]]; then
# Install Node.js LTS from NodeSource
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo -E bash -
sudo dnf install -y nodejs
elif [[ "$DISTRO_FAMILY" == "arch" ]]; then
sudo pacman -S --noconfirm nodejs npm
elif [[ "$DISTRO_FAMILY" == "alpine" ]]; then
if command_exists sudo; then
sudo apk add --no-cache nodejs npm
else
apk add --no-cache nodejs npm
fi
fi
fi
if command_exists node && command_exists npm; then
NODE_VERSION=$(node --version)
NPM_VERSION=$(npm --version)
print_success "node installed successfully ($NODE_VERSION)"
print_success "npm installed successfully (version $NPM_VERSION)"
else
print_error "node installation failed"
exit 1
fi
}
# Check if memvid is already installed
check_memvid() {
if command_exists memvid; then
# Get version - output format is "memvid 2.0.131"
MEMVID_VERSION=$(memvid --version 2>&1 | awk '{print $2}')
print_success "memvid already installed ($MEMVID_VERSION)"
return 0
else
print_error "memvid not found"
return 1
fi
}
# Install missing tools
install_missing() {
NEEDS_GIT=false
NEEDS_NODE=false
NEEDS_MEMVID=false
if ! check_git; then
NEEDS_GIT=true
fi
if ! check_node; then
NEEDS_NODE=true
fi
if ! check_memvid; then
NEEDS_MEMVID=true
fi
if [[ "$NEEDS_GIT" == false ]] && [[ "$NEEDS_NODE" == false ]] && [[ "$NEEDS_MEMVID" == false ]]; then
print_info "All dependencies are already installed"
return 0
fi
# Show what will be installed
echo ""
print_warning "The following tools will be installed:"
[[ "$NEEDS_GIT" == true ]] && echo " - git"
[[ "$NEEDS_NODE" == true ]] && echo " - node (LTS)"
[[ "$NEEDS_MEMVID" == true ]] && echo " - memvid-cli (latest)"
echo ""
# Ask for confirmation
# Read from /dev/tty to ensure it works when piped via curl | bash
if [[ -t 0 ]] && [[ -t 1 ]]; then
# Interactive terminal - read normally
read -p "Continue? [Y/n] " -n 1 -r
echo
elif [[ -c /dev/tty ]]; then
# Piped input - read from terminal device
read -p "Continue? [Y/n] " -n 1 -r < /dev/tty
echo
else
# No terminal available - proceed automatically (non-interactive mode)
print_info "No terminal detected, proceeding with installation..."
REPLY="Y"
fi
if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ ! $REPLY == "" ]]; then
print_info "Installation cancelled"
exit 0
fi
# Install missing tools
[[ "$NEEDS_GIT" == true ]] && install_git
[[ "$NEEDS_NODE" == true ]] && install_node
[[ "$NEEDS_MEMVID" == true ]] && install_memvid
}
# Install memvid
install_memvid() {
print_info "Installing memvid globally..."
if [[ "$OS" == "linux" ]]; then
# Linux requires sudo for global npm installs
if sudo npm install -g memvid-cli@latest; then
print_success "memvid installed successfully"
else
print_error "memvid installation failed"
exit 1
fi
else
# macOS typically doesn't need sudo if npm was installed via Homebrew
if npm install -g memvid-cli@latest; then
print_success "memvid installed successfully"
else
print_error "memvid installation failed"
exit 1
fi
fi
}
# Verify installation
verify() {
print_info "Verifying installation..."
if command_exists memvid; then
# Get version - output format is "memvid 2.0.131"
MEMVID_VERSION=$(memvid --version 2>&1 | awk '{print $2}')
print_success "memvid is installed and accessible"
print_info "Version: $MEMVID_VERSION"
echo ""
print_success "Installation complete! You can now use 'memvid' command."
else
print_error "memvid verification failed"
print_info "The installation may have completed, but 'memvid' command is not in PATH"
print_info "Please check your npm global bin directory and add it to PATH if needed"
print_info "Or try: npm list -g memvid-cli"
exit 1
fi
}
# Main execution
main() {
echo "Memvid Installer"
echo "Checking system requirements…"
echo ""
detect_os
echo ""
# Check Xcode CLI Tools on macOS
if [[ "$OS" == "macos" ]]; then
check_xcode_cli_tools
echo ""
fi
# Install system dependencies on Linux
if [[ "$OS" == "linux" ]]; then
install_system_deps
echo ""
fi
install_missing
echo ""
verify
}
# Run main function
main