Something went wrong. Try again.
Command line interface for accessing the Open Web Index shards and slices.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487#!/bin/sh# OWILIX Installer (POSIX sh)# Usage:# curl -fsSL https://opencode.it4i.eu/openwebsearcheu-public/owi-cli/-/raw/main/scripts/install.sh?ref_type=heads | sh## Options (via environment variables):# OWILIX_VERSION - Specific version to install (default: latest)# OWILIX_PATH - Installation directory for uv/pipx (default: ~/.venv/owilix)# OWILIX_NO_PATH - Set to 1 to skip PATH modification# OWILIX_UPGRADE - Set to 1 for upgrade mode# OWILIX_PM - Force package manager: uv, conda, mamba, pipx (skip selection)
set -eu
# ---- Colors (safe-ish for sh) ----RED=$(printf '\033[0;31m')GREEN=$(printf '\033[0;32m')YELLOW=$(printf '\033[1;33m')BLUE=$(printf '\033[0;34m')CYAN=$(printf '\033[0;36m')NC=$(printf '\033[0m')
log() { printf "%s[owilix]%s %s\n" "$BLUE" "$NC" "$1"; }success() { printf "%s[owilix]%s %s\n" "$GREEN" "$NC" "$1"; }warn() { printf "%s[owilix]%s %s\n" "$YELLOW" "$NC" "$1"; }error() { printf "%s[owilix]%s %s\n" "$RED" "$NC" "$1" >&2; }
# ---- Config ----OWILIX_VERSION=${OWILIX_VERSION:-}OWILIX_PATH=${OWILIX_PATH:-"$HOME/.venv/owilix"}OWILIX_NO_PATH=${OWILIX_NO_PATH:-0}OWILIX_UPGRADE=${OWILIX_UPGRADE:-0}OWILIX_PM=${OWILIX_PM:-}
OWILIX_INDEX="https://opencode.it4i.eu/api/v4/projects/92/packages/pypi/simple"PY4LEXIS_INDEX="https://opencode.it4i.eu/api/v4/projects/107/packages/pypi/simple"
# uv requires URL dependencies to be expressed as direct requirements.# Keep this in sync with pyproject.toml to avoid URL conflicts.GIT_DEP="python-http-irods-client @ git+https://opencode.it4i.eu/lexis-platform/data/python-http-irods-client.git@1.1.4"# Keep py4lexis deterministic for installer resolution, since newer py4lexis# releases may change URL-pinned transitive dependencies.PY4LEXIS_DEP="py4lexis==5.4.0"
# Fix for OSTYPE not set in some environments (causes issues with set -u)OSTYPE=${OSTYPE:-unknown}export OSTYPE
# ---- Helpers ----have() { command -v "$1" >/dev/null 2>&1; }
detect_os() { case "$(uname -s 2>/dev/null || echo unknown)" in Linux*) OS="linux" ;; Darwin*) OS="macos" ;; MINGW*|CYGWIN*|MSYS*) OS="windows" ;; *) OS="unknown" ;; esac log "Detected OS: $OS"}
detect_package_managers() { AVAILABLE_PMS="" have uv && AVAILABLE_PMS="$AVAILABLE_PMS uv" have conda && AVAILABLE_PMS="$AVAILABLE_PMS conda" have mamba && AVAILABLE_PMS="$AVAILABLE_PMS mamba" have pipx && AVAILABLE_PMS="$AVAILABLE_PMS pipx"
if [ -n "$AVAILABLE_PMS" ]; then log "Available package managers:${AVAILABLE_PMS}" else log "Available package managers: none" fi}
count_words() { # prints number of words in $1 # shellcheck disable=SC2086 set -- $1 echo $#}
nth_word() { # nth_word "a b c" 2 -> b list=$1 n=$2 i=1 for w in $list; do if [ "$i" -eq "$n" ]; then echo "$w" return 0 fi i=$((i + 1)) done return 1}
install_uv() { if have uv; then log "uv is already installed: $(uv --version 2>/dev/null || echo unknown)" return 0 fi
log "Installing uv..." if have curl; then curl -fsSL https://astral.sh/uv/install.sh | sh elif have wget; then wget -qO- https://astral.sh/uv/install.sh | sh else error "Neither curl nor wget found. Please install one first." exit 1 fi
# Common install location for uv PATH="$HOME/.local/bin:$PATH" export PATH
if have uv; then success "uv installed: $(uv --version 2>/dev/null || echo unknown)" AVAILABLE_PMS="$AVAILABLE_PMS uv" else error "Failed to install uv" exit 1 fi}
choose_package_manager() { if [ -n "$OWILIX_PM" ]; then PM=$OWILIX_PM log "Using package manager (from OWILIX_PM): $PM" return 0 fi
n=$(count_words "$AVAILABLE_PMS")
if [ "$n" -eq 1 ]; then PM=$(nth_word "$AVAILABLE_PMS" 1) log "Using package manager: $PM" return 0 fi
if [ "$n" -eq 0 ]; then log "No package managers found. Installing uv..." install_uv PM="uv" return 0 fi
echo "" printf "%sMultiple package managers detected. Please choose:%s\n\n" "$CYAN" "$NC"
i=1 for pm in $AVAILABLE_PMS; do case "$pm" in uv) printf " %s) uv - Fast, recommended (creates venv at %s)\n" "$i" "$OWILIX_PATH" ;; conda) printf " %s) conda - Creates 'owilix' conda environment\n" "$i" ;; mamba) printf " %s) mamba - Fast conda alternative (creates 'owilix' env)\n" "$i" ;; pipx) printf " %s) pipx - Isolated install (creates venv at %s)\n" "$i" "$OWILIX_PATH" ;; esac i=$((i + 1)) done echo ""
# Read from tty so curl|sh still prompts printf "Enter choice [1-%s] (default: 1): " "$n" > /dev/tty read -r choice < /dev/tty || true [ -z "${choice:-}" ] && choice=1
case "$choice" in *[!0-9]*|'') choice=1 ;; esac if [ "$choice" -lt 1 ] || [ "$choice" -gt "$n" ]; then choice=1 fi
PM=$(nth_word "$AVAILABLE_PMS" "$choice" || true) [ -z "${PM:-}" ] && PM=$(nth_word "$AVAILABLE_PMS" 1)
log "Selected package manager: $PM"}
handle_existing_path() { if [ -d "$OWILIX_PATH" ]; then warn "Installation directory exists: $OWILIX_PATH" printf "Remove and reinstall? [y/N] " > /dev/tty read -r reply < /dev/tty || true case "$reply" in y|Y) rm -rf "$OWILIX_PATH" ;; *) error "Installation aborted"; exit 1 ;; esac fi}
# ---- Installers ----install_with_uv() { version_arg="" [ -n "$OWILIX_VERSION" ] && version_arg="==$OWILIX_VERSION"
if [ "$OWILIX_UPGRADE" = "1" ] && [ -d "$OWILIX_PATH" ]; then log "Upgrading with uv..." # shellcheck disable=SC1090 [ -f "$OWILIX_PATH/bin/activate" ] && . "$OWILIX_PATH/bin/activate" || true uv pip install --upgrade "$GIT_DEP" "$PY4LEXIS_DEP" "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --extra-index-url "$PY4LEXIS_INDEX" return 0 fi
handle_existing_path
log "Creating virtual environment at $OWILIX_PATH..." uv venv --python 3.11 "$OWILIX_PATH"
log "Installing owilix with uv..." # shellcheck disable=SC1090 . "$OWILIX_PATH/bin/activate" uv pip install "$GIT_DEP" "$PY4LEXIS_DEP" "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --extra-index-url "$PY4LEXIS_INDEX"}
conda_hook() { # Make conda activate work in non-interactive sh if have conda; then # Prefer posix hook, fall back to sh hook eval "$(conda shell.posix hook 2>/dev/null || conda shell.sh hook 2>/dev/null)" || true fi}
install_with_conda() { version_arg="" [ -n "$OWILIX_VERSION" ] && version_arg="==$OWILIX_VERSION" env_name="owilix"
conda_hook
if [ "$OWILIX_UPGRADE" = "1" ]; then log "Upgrading with conda..." conda activate "$env_name" >/dev/null 2>&1 || true pip install --upgrade "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --extra-index-url "$PY4LEXIS_INDEX" else if conda env list 2>/dev/null | grep -q "^$env_name[[:space:]]"; then warn "Conda environment '$env_name' exists" printf "Remove and recreate? [y/N] " > /dev/tty read -r reply < /dev/tty || true case "$reply" in y|Y) conda env remove -n "$env_name" -y ;; *) error "Installation aborted"; exit 1 ;; esac fi
log "Creating conda environment '$env_name'..." conda create -n "$env_name" python=3.11 -y
log "Installing owilix with conda/pip..." conda activate "$env_name" pip install "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --extra-index-url "$PY4LEXIS_INDEX" fi
success "owilix installed in conda env '$env_name'" warn "To use: conda activate $env_name"}
install_with_mamba() { version_arg="" [ -n "$OWILIX_VERSION" ] && version_arg="==$OWILIX_VERSION" env_name="owilix"
conda_hook
if [ "$OWILIX_UPGRADE" = "1" ]; then log "Upgrading with mamba..." # activation varies; try conda hook/activate conda activate "$env_name" >/dev/null 2>&1 || true pip install --upgrade "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --extra-index-url "$PY4LEXIS_INDEX" else if (have mamba && mamba env list 2>/dev/null | grep -q "^$env_name[[:space:]]") \ || (have conda && conda env list 2>/dev/null | grep -q "^$env_name[[:space:]]"); then warn "Mamba/conda environment '$env_name' exists" printf "Remove and recreate? [y/N] " > /dev/tty read -r reply < /dev/tty || true case "$reply" in y|Y) (have mamba && mamba env remove -n "$env_name" -y >/dev/null 2>&1) || true (have conda && conda env remove -n "$env_name" -y >/dev/null 2>&1) || true ;; *) error "Installation aborted"; exit 1 ;; esac fi
log "Creating mamba environment '$env_name'..." mamba create -n "$env_name" python=3.11 -y
log "Installing owilix with mamba/pip..." conda activate "$env_name" pip install "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --extra-index-url "$PY4LEXIS_INDEX" fi
success "owilix installed in mamba env '$env_name'" warn "To use: mamba activate $env_name (or conda activate $env_name)"}
install_with_pipx() { version_arg="" [ -n "$OWILIX_VERSION" ] && version_arg="==$OWILIX_VERSION"
if [ "$OWILIX_UPGRADE" = "1" ]; then log "Upgrading with pipx..." pipx upgrade owilix >/dev/null 2>&1 || true else log "Installing owilix with pipx..." # pipx doesn't handle git deps well, try pipx and fall back to uv if pipx install "owilix${version_arg}" \ --index-url "$OWILIX_INDEX" \ --pip-args="--extra-index-url=$PY4LEXIS_INDEX" >/dev/null 2>&1 then : else warn "pipx install failed (dependency resolution issue)" log "Falling back to uv installation..." install_uv PM="uv" install_with_uv return 0 fi fi
success "owilix installed with pipx"}
# ---- PATH setup ----setup_path() { # Skip for conda/mamba (they use activation) if [ "$PM" = "conda" ] || [ "$PM" = "mamba" ]; then return 0 fi
if [ "$OWILIX_NO_PATH" = "1" ]; then log "Skipping PATH modification (OWILIX_NO_PATH=1)" return 0 fi
path_line="export PATH=\"$OWILIX_PATH/bin:\$PATH\"" shell_rc=""
# In sh we can't reliably know the user's interactive shell; best effort: case "${SHELL:-}" in *zsh*) shell_rc="$HOME/.zshrc" ;; *bash*) if [ "$OS" = "macos" ]; then shell_rc="$HOME/.bash_profile" else shell_rc="$HOME/.bashrc" fi ;; *) # POSIX default shell_rc="$HOME/.profile" ;; esac
if [ -n "$shell_rc" ]; then if [ -f "$shell_rc" ] && grep -qi "owilix" "$shell_rc" 2>/dev/null; then log "PATH already configured in $shell_rc" else { echo "" echo "# OWILIX CLI" echo "$path_line" } >> "$shell_rc" success "Added owilix to PATH in $shell_rc" fi fi}
# ---- Config migration ----check_migration() { owilix_bin="" case "$PM" in uv|pipx) owilix_bin="$OWILIX_PATH/bin/owilix" ;; conda|mamba) owilix_bin="owilix" ;; *) owilix_bin="owilix" ;; esac
log "Checking configuration status..."
if ! "$owilix_bin" config version >/dev/null 2>&1; then log "No existing configuration found" return 0 fi
version_output=$("$owilix_bin" config version 2>&1 || true) echo "$version_output"
echo "$version_output" | grep -qi "migration available\|upgrade\|outdated" || return 0
echo "" printf "Config migration available. Run migration now? [Y/n] " > /dev/tty read -r reply < /dev/tty || true case "$reply" in n|N) return 0 ;; esac
log "Running migration (dry-run first)..." "$owilix_bin" config migrate --dry-run >/dev/null 2>&1 || true echo "" printf "Apply migration? [y/N] " > /dev/tty read -r reply2 < /dev/tty || true case "$reply2" in y|Y) "$owilix_bin" config migrate success "Migration completed" ;; esac}
print_usage() { echo "" success "╔════════════════════════════════════════════════════════════════╗" success "║ OWILIX installed successfully! ║" success "╚════════════════════════════════════════════════════════════════╝" echo ""
case "$PM" in uv|pipx) echo " To use (after restarting terminal):" echo " owilix --help" ;; conda) echo " To use:" echo " conda activate owilix" echo " owilix --help" ;; mamba) echo " To use:" echo " mamba activate owilix # or: conda activate owilix" echo " owilix --help" ;; esac
echo "" echo " Quick start:" echo " owilix remote doctor # Check connection" echo " owilix remote ls all # List datasets" echo "" echo " Documentation:" echo " https://openwebsearcheu-public.pages.it4i.eu/owi-cli/" echo ""}
main() { echo "" log "╔════════════════════════════════════════════════════════════════╗" log "║ OWILIX Installer (sh) ║" log "╚════════════════════════════════════════════════════════════════╝" echo ""
detect_os detect_package_managers choose_package_manager
case "$PM" in uv) install_with_uv ;; conda) install_with_conda ;; mamba) install_with_mamba ;; pipx) install_with_pipx ;; *) error "Unknown package manager: $PM" exit 1 ;; esac
setup_path check_migration print_usage}
main "$@"