nushell-plugins/install.sh

476 lines
12 KiB
Bash
Raw Normal View History

#!/bin/bash
# Universal Installer for Nushell Plugins
# Downloads and installs the latest release of nushell plugins for your platform
set -e
# Configuration
REPO_OWNER="YOUR_ORG" # Replace with actual GitHub org/user
REPO_NAME="nushell-plugins"
GITHUB_REPO="${REPO_OWNER}/${REPO_NAME}"
BASE_URL="https://github.com/${GITHUB_REPO}"
API_URL="https://api.github.com/repos/${GITHUB_REPO}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default values
INSTALL_DIR="/usr/local/bin"
VERSION=""
PLATFORM=""
FORCE=false
DRY_RUN=false
QUIET=false
TEMP_DIR=""
# Functions
log() {
if [ "$QUIET" != "true" ]; then
echo -e "${BLUE}[INFO]${NC} $1"
fi
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1" >&2
}
error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
usage() {
cat << EOF
Universal Installer for Nushell Plugins
USAGE:
$0 [OPTIONS]
OPTIONS:
-d, --install-dir DIR Installation directory (default: /usr/local/bin)
-v, --version VERSION Specific version to install (default: latest)
-p, --platform PLATFORM Force specific platform (auto-detected by default)
-f, --force Force installation even if already installed
--dry-run Show what would be done without doing it
--quiet Suppress non-essential output
-h, --help Show this help message
EXAMPLES:
# Install latest version to default location
$0
# Install to custom directory
$0 --install-dir ~/.local/bin
# Install specific version
$0 --version v1.2.3
# Force specific platform
$0 --platform linux-amd64
PLATFORMS:
linux-amd64 Linux x86_64
linux-arm64 Linux ARM64
darwin-amd64 macOS Intel
darwin-arm64 macOS Apple Silicon
windows-amd64 Windows x86_64
REQUIREMENTS:
- curl or wget
- tar (for Unix-like systems)
- nushell (nu command should be available)
- Write permissions to installation directory
MORE INFO:
Repository: ${BASE_URL}
Releases: ${BASE_URL}/releases
EOF
}
# Platform detection
detect_platform() {
local os=""
local arch=""
# Detect OS
case "$(uname -s)" in
Linux*) os="linux" ;;
Darwin*) os="darwin" ;;
CYGWIN*|MINGW*|MSYS*) os="windows" ;;
*)
error "Unsupported operating system: $(uname -s)"
exit 1
;;
esac
# Detect architecture
case "$(uname -m)" in
x86_64|amd64) arch="amd64" ;;
aarch64|arm64) arch="arm64" ;;
armv7l) arch="arm32" ;;
*)
error "Unsupported architecture: $(uname -m)"
exit 1
;;
esac
echo "${os}-${arch}"
}
# Check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check prerequisites
check_prerequisites() {
log "Checking prerequisites..."
# Check for download tools
if ! command_exists curl && ! command_exists wget; then
error "Neither curl nor wget found. Please install one of them."
exit 1
fi
# Check for tar (Unix-like systems)
if [ "$PLATFORM" != "windows-amd64" ] && ! command_exists tar; then
error "tar command not found. Please install tar."
exit 1
fi
# Check for nushell
if ! command_exists nu; then
warn "nushell (nu) not found in PATH. You'll need to install nushell to use these plugins."
warn "Visit: https://www.nushell.sh/book/installation.html"
fi
# Check write permissions
if [ ! -w "$(dirname "$INSTALL_DIR")" ]; then
error "No write permission to $(dirname "$INSTALL_DIR")"
error "Try running with sudo or choose a different directory with --install-dir"
exit 1
fi
}
# Download file
download_file() {
local url="$1"
local output="$2"
log "Downloading: $url"
if command_exists curl; then
curl -L --fail --progress-bar "$url" -o "$output"
elif command_exists wget; then
wget --progress=bar:force:noscroll "$url" -O "$output"
else
error "No download tool available"
exit 1
fi
}
# Get latest release info
get_latest_release() {
local api_url="${API_URL}/releases/latest"
log "Fetching latest release information..."
if command_exists curl; then
curl -s "$api_url"
elif command_exists wget; then
wget -qO- "$api_url"
else
error "No download tool available"
exit 1
fi
}
# Get specific release info
get_release_info() {
local version="$1"
local api_url="${API_URL}/releases/tags/${version}"
log "Fetching release information for ${version}..."
if command_exists curl; then
curl -s "$api_url"
elif command_exists wget; then
wget -qO- "$api_url"
else
error "No download tool available"
exit 1
fi
}
# Parse JSON (simple parsing for our needs)
parse_json_value() {
local json="$1"
local key="$2"
echo "$json" | sed -n "s/.*\"$key\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -1
}
# Find download URL for platform
find_download_url() {
local release_json="$1"
local platform="$2"
# Look for asset with platform name
echo "$release_json" | grep -o '"browser_download_url":"[^"]*"' | \
grep "$platform" | \
head -1 | \
sed 's/"browser_download_url":"\([^"]*\)"/\1/'
}
# Extract archive
extract_archive() {
local archive="$1"
local dest_dir="$2"
log "Extracting archive to $dest_dir..."
case "$archive" in
*.tar.gz)
tar -xzf "$archive" -C "$dest_dir"
;;
*.zip)
if command_exists unzip; then
unzip -q "$archive" -d "$dest_dir"
else
error "unzip command not found. Please install unzip to extract .zip files."
exit 1
fi
;;
*)
error "Unsupported archive format: $archive"
exit 1
;;
esac
}
# Install plugins
install_plugins() {
local extract_dir="$1"
log "Installing plugins to $INSTALL_DIR..."
# Find the extracted directory (might be nested)
local plugin_dir=""
if [ -d "$extract_dir" ]; then
# Look for nu_plugin_* files directly or in subdirectories
plugin_dir=$(find "$extract_dir" -name "nu_plugin_*" -type f -executable | head -1 | xargs dirname)
if [ -z "$plugin_dir" ]; then
# Try to find a directory with plugins
plugin_dir=$(find "$extract_dir" -type d -name "*nushell-plugins*" | head -1)
if [ -z "$plugin_dir" ]; then
plugin_dir="$extract_dir"
fi
fi
fi
if [ ! -d "$plugin_dir" ]; then
error "Could not find plugin directory in extracted archive"
exit 1
fi
log "Found plugins in: $plugin_dir"
# Create install directory if it doesn't exist
mkdir -p "$INSTALL_DIR"
# Copy plugin binaries
local installed_count=0
for plugin in "$plugin_dir"/nu_plugin_*; do
if [ -f "$plugin" ] && [ -x "$plugin" ]; then
local plugin_name=$(basename "$plugin")
local dest_path="$INSTALL_DIR/$plugin_name"
if [ "$DRY_RUN" = "true" ]; then
log "Would install: $plugin_name -> $dest_path"
else
log "Installing: $plugin_name"
cp "$plugin" "$dest_path"
chmod +x "$dest_path"
fi
installed_count=$((installed_count + 1))
fi
done
if [ $installed_count -eq 0 ]; then
error "No plugin binaries found to install"
exit 1
fi
success "Installed $installed_count plugins"
# Copy installation script if available
if [ -f "$plugin_dir/install_nu_plugins.nu" ] && [ "$DRY_RUN" != "true" ]; then
log "Running nushell installation script..."
if command_exists nu; then
cd "$plugin_dir"
nu install_nu_plugins.nu --bin-path "$INSTALL_DIR" || {
warn "Installation script failed, but binaries were copied"
}
else
warn "Nushell not available, skipping automatic plugin registration"
fi
fi
}
# Cleanup temporary files
cleanup() {
if [ -n "$TEMP_DIR" ] && [ -d "$TEMP_DIR" ]; then
log "Cleaning up temporary files..."
rm -rf "$TEMP_DIR"
fi
}
# Main installation function
main() {
# Set up cleanup trap
trap cleanup EXIT
log "Nushell Plugins Universal Installer"
log "Repository: $GITHUB_REPO"
# Auto-detect platform if not specified
if [ -z "$PLATFORM" ]; then
PLATFORM=$(detect_platform)
log "Detected platform: $PLATFORM"
else
log "Using specified platform: $PLATFORM"
fi
# Check prerequisites
check_prerequisites
# Get release information
local release_json=""
if [ -z "$VERSION" ]; then
log "Getting latest release..."
release_json=$(get_latest_release)
VERSION=$(parse_json_value "$release_json" "tag_name")
else
log "Getting release $VERSION..."
release_json=$(get_release_info "$VERSION")
fi
if [ -z "$release_json" ] || [ "$release_json" = "null" ]; then
error "Failed to get release information"
exit 1
fi
log "Version: $VERSION"
# Find download URL
local download_url=$(find_download_url "$release_json" "$PLATFORM")
if [ -z "$download_url" ]; then
error "No download found for platform: $PLATFORM"
error "Available platforms can be found at: ${BASE_URL}/releases/tag/${VERSION}"
exit 1
fi
log "Download URL: $download_url"
if [ "$DRY_RUN" = "true" ]; then
log "DRY RUN: Would download and install from $download_url"
log "DRY RUN: Would install to $INSTALL_DIR"
return 0
fi
# Create temporary directory
TEMP_DIR=$(mktemp -d)
local archive_name=$(basename "$download_url")
local archive_path="$TEMP_DIR/$archive_name"
# Download archive
download_file "$download_url" "$archive_path"
# Verify download
if [ ! -f "$archive_path" ]; then
error "Download failed: $archive_path not found"
exit 1
fi
# Extract archive
extract_archive "$archive_path" "$TEMP_DIR"
# Install plugins
install_plugins "$TEMP_DIR"
success "Installation completed successfully!"
# Show next steps
echo ""
echo "🎉 Nushell plugins have been installed to: $INSTALL_DIR"
echo ""
echo "📝 Next steps:"
echo " 1. Make sure $INSTALL_DIR is in your PATH"
echo " 2. In nushell, register plugins with:"
# List installed plugins
for plugin in "$INSTALL_DIR"/nu_plugin_*; do
if [ -f "$plugin" ] && [ -x "$plugin" ]; then
echo " plugin add $plugin"
fi
done
echo ""
echo "💡 Or run this one-liner in nushell:"
echo " ls $INSTALL_DIR/nu_plugin_* | each { |plugin| plugin add \$plugin.name }"
echo ""
echo "🔗 More info: ${BASE_URL}"
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-d|--install-dir)
INSTALL_DIR="$2"
shift 2
;;
-v|--version)
VERSION="$2"
shift 2
;;
-p|--platform)
PLATFORM="$2"
shift 2
;;
-f|--force)
FORCE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
--quiet)
QUIET=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
error "Unknown option: $1"
usage
exit 1
;;
esac
done
# Run main function
main