#!/bin/sh # Semantr installer. # # curl -LsSf https://semantr.com/install.sh | sh # # Node ships npm, so `npx thing` assumes nothing. Python has no equivalent — which is why # `uvx semantr` fails with "command not found" for anyone who does not already use uv, and # why `pip install` fails on Debian and Ubuntu system Python with externally-managed- # environment. This script is the one instruction that works either way: it uses uv if # present, installs it if not, and falls back to pip only where uv cannot be had. # # POSIX sh, no bashisms — /bin/sh is dash on Debian and Ubuntu. set -eu BOLD=''; DIM=''; RED=''; GREEN=''; RESET='' if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then BOLD=$(printf '\033[1m'); DIM=$(printf '\033[2m'); RED=$(printf '\033[31m') GREEN=$(printf '\033[32m'); RESET=$(printf '\033[0m') fi say() { printf '%s\n' "$*"; } step() { printf '%s==>%s %s\n' "$BOLD" "$RESET" "$*"; } die() { printf '%serror:%s %s\n' "$RED" "$RESET" "$*" >&2; exit 1; } has() { command -v "$1" >/dev/null 2>&1; } say "" say "${BOLD}Semantr${RESET} — find out what your organisation is actually using AI for" say "" # ---------------------------------------------------------------------------- uv if has uv; then step "uv is already installed" else step "Installing uv (the Python tool runner Semantr ships through)" if has curl; then curl -LsSf https://astral.sh/uv/install.sh | sh || die "could not install uv" elif has wget; then wget -qO- https://astral.sh/uv/install.sh | sh || die "could not install uv" else die "need curl or wget to install uv. Install one, or use: pip install semantr" fi # The uv installer puts binaries here but only edits shell profiles, which do not # affect the shell this script is running in. for candidate in "$HOME/.local/bin" "$HOME/.cargo/bin"; do if [ -x "$candidate/uv" ]; then PATH="$candidate:$PATH" export PATH break fi done has uv || die "uv installed but is not on PATH — open a new terminal and re-run this" fi # -------------------------------------------------------------------------- semantr # Overridable so a version can be pinned (SEMANTR_PACKAGE=semantr==1.2.0) and so this # script is testable against a local wheel before a release is published. PACKAGE="${SEMANTR_PACKAGE:-semantr}" step "Installing $PACKAGE" uv tool install --force "$PACKAGE" || die "could not install $PACKAGE" # `uv tool install` places shims in uv's own bin directory, which is on PATH for new # shells but not necessarily this one. TOOL_BIN=$(uv tool dir --bin 2>/dev/null || echo "$HOME/.local/bin") case ":$PATH:" in *":$TOOL_BIN:"*) ;; *) PATH="$TOOL_BIN:$PATH"; export PATH ;; esac has semantr || die "semantr installed to $TOOL_BIN but is not on PATH" say "" say "${GREEN}Installed.${RESET} $(semantr --version)" say "" say "Run it. It finds your Bedrock invocation logs itself — no arguments, no account:" say "" say " ${BOLD}semantr${RESET}" say "" say "${DIM}Reading your logs is free. Naming what it finds costs about a cent, and it asks" say "before spending anything. If it is not on your PATH yet, open a new terminal.${RESET}" say ""