diff --git a/docs/user-guide.md b/docs/user-guide.md index 892e3a0..42161eb 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -116,9 +116,13 @@ curl -fsSL https://raw.githubusercontent.com/Cloudstic/cli/main/scripts/install. # Install completion for a specific shell curl -fsSL https://raw.githubusercontent.com/Cloudstic/cli/main/scripts/install.sh | sh -s -- --with-completion --shell zsh + +# Skip checksum verification (not recommended) +curl -fsSL https://raw.githubusercontent.com/Cloudstic/cli/main/scripts/install.sh | sh -s -- --no-verify ``` -The installer verifies release checksums by default. +The installer verifies release checksums by default. `--no-verify` is available +for constrained/debug environments but is not recommended. Completion files are written to user directories (for example `~/.zfunc` for zsh, `~/.config/fish/completions` for fish, and `~/.local/share/bash-completion/completions` for bash). @@ -126,9 +130,16 @@ Completion files are written to user directories (for example `~/.zfunc` for zsh Download the latest release for your platform from the [GitHub Releases](https://github.com/cloudstic/cli/releases) page. Binaries are available for macOS (Intel & Apple Silicon), Linux (amd64 & arm64), and Windows. +> Prefer the curl installer above when possible; it verifies checksums automatically. + ```bash # Example: macOS Apple Silicon -curl -L https://github.com/cloudstic/cli/releases/latest/download/cloudstic_$(curl -s https://api.github.com/repos/cloudstic/cli/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/^v//')_darwin_arm64.tar.gz | tar xz +VERSION=$(curl -fsSL https://api.github.com/repos/cloudstic/cli/releases/latest | awk -F '"' '/tag_name/{gsub(/^v/,"",$4); print $4; exit}') +ASSET="cloudstic_${VERSION}_darwin_arm64.tar.gz" +curl -fsSL "https://github.com/cloudstic/cli/releases/latest/download/${ASSET}" -o "${ASSET}" +curl -fsSL https://github.com/cloudstic/cli/releases/latest/download/checksums.txt -o checksums.txt +grep " ${ASSET}$" checksums.txt | shasum -a 256 -c - +tar -xzf "${ASSET}" mv cloudstic /usr/local/bin/ ``` diff --git a/scripts/install.sh b/scripts/install.sh index 5ac191b..ec7b713 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -124,6 +124,11 @@ parse_args() { done } +print_install_dir_hint() { + echo "Try running with sudo or choose a user-writable directory:" >&2 + echo " sh -s -- --install-dir \"$HOME/.local/bin\"" >&2 +} + detect_default_shell() { if [ -n "${SHELL:-}" ]; then shell_name="$(basename "$SHELL")" @@ -203,7 +208,10 @@ install_binary() { if [ "$VERSION" = "latest" ]; then tag="latest" else - tag="$VERSION" + case "$VERSION" in + v*) tag="$VERSION" ;; + *) tag="v$VERSION" ;; + esac fi if [ "$tag" = "latest" ]; then @@ -253,14 +261,25 @@ install_binary() { exit 1 fi - mkdir -p "$INSTALL_DIR" + if ! mkdir -p "$INSTALL_DIR" 2>/dev/null; then + echo "Error: cannot create install directory: $INSTALL_DIR" >&2 + print_install_dir_hint + exit 1 + fi + target="$INSTALL_DIR/$BIN_NAME" - if cp "$tmpdir/$BIN_NAME" "$target" 2>/dev/null; then - chmod +x "$target" + cp_err_file="$tmpdir/cp.err" + if cp "$tmpdir/$BIN_NAME" "$target" 2>"$cp_err_file"; then + chmod_err_file="$tmpdir/chmod.err" + if ! chmod +x "$target" 2>"$chmod_err_file"; then + echo "Error: failed to set executable bit on $target" >&2 + cat "$chmod_err_file" >&2 + exit 1 + fi else - echo "Permission denied writing to $INSTALL_DIR." >&2 - echo "Try running with sudo or choose a user-writable directory:" >&2 - echo " sh -s -- --install-dir \"$HOME/.local/bin\"" >&2 + echo "Error: failed to install $BIN_NAME to $target" >&2 + cat "$cp_err_file" >&2 + print_install_dir_hint exit 1 fi @@ -275,6 +294,7 @@ install_binary() { main() { need_cmd curl need_cmd tar + need_cmd awk parse_args "$@" os="$(detect_os)" arch="$(detect_arch)"