Files
openclaw/test/scripts/install-npm-fixtures.ts
Peter Steinberger 7bc994aee8 fix(install): avoid success after incomplete lifecycle changes (#125992)
* fix(install): make lifecycle mutations transactional

Standalone installers now apply npm-version-aware lifecycle approval. Updates verify and repair the installation before reporting success and preserve the prior install owner during method switches. Uninstall now exits nonzero when requested cleanup is only partially completed. Plugin update behavior is unchanged.

Closes #125925

* test(uninstall): assert aggregated live-owner failure

* fix(install): satisfy standalone shell checks

* fix(update): scan PATH for prior Git wrapper

* test(hooks): await Gmail watcher descendant exit

* fix(install): verify Windows npm candidate

* fix(ci): normalize package acceptance version

* fix(update): preserve staged local package links

* test(update): fold staged symlink coverage

* fix(update): retire every legacy Git wrapper

* test(docs): align consolidated ownership checks
2026-08-18 20:50:15 -07:00

130 lines
4.7 KiB
TypeScript

// NPM CLI fixture writers used by installer shell-script tests.
import { chmodSync, writeFileSync } from "node:fs";
export function writeNpmInstallRetryFixture(path: string) {
writeFileSync(
path,
[
"#!/usr/bin/env bash",
"set -euo pipefail",
'if [[ "${1:-}" == "--version" ]]; then printf "11.15.0\\n"; exit 0; fi',
'if [[ "${1:-}" == "config" ]]; then printf "null\\n"; exit 0; fi',
'if [[ "${1:-}" == "view" ]]; then printf "2026.8.1\\n"; exit 0; fi',
'if [[ "${1:-}" == "root" ]]; then printf "%s\\n" "${NPM_FAKE_ROOT:-}"; exit 0; fi',
"is_install=0",
'for arg in "$@"; do [[ "$arg" == "install" ]] && is_install=1; done',
'if [[ "$is_install" -eq 0 ]]; then exit 0; fi',
'spec="${!#}"',
'printf "%s\\n" "$spec" >> "$NPM_FAKE_CALLS"',
'attempt="$(awk \'END { print NR }\' "$NPM_FAKE_CALLS")"',
'if [[ "$NPM_FAKE_OUTCOME" == "success" || "$NPM_FAKE_OUTCOME" == "transient" && "$attempt" -eq 2 ]]; then',
' if [[ -n "${NPM_FAKE_PACKAGE_DIR:-}" ]]; then',
' mkdir -p "$NPM_FAKE_PACKAGE_DIR/dist"',
' printf "#!/bin/sh\\nprintf \'2026.8.1\\\\n\'\\n" > "$NPM_FAKE_PACKAGE_DIR/openclaw.mjs"',
' printf "#!/usr/bin/env node\\n" > "$NPM_FAKE_PACKAGE_DIR/dist/entry.js"',
' chmod +x "$NPM_FAKE_PACKAGE_DIR/openclaw.mjs" "$NPM_FAKE_PACKAGE_DIR/dist/entry.js"',
" fi",
" exit 0",
"fi",
'printf "%s (attempt %s)\\n" "$NPM_FAKE_ERROR" "$attempt" >&2',
"exit 1",
"",
].join("\n"),
);
chmodSync(path, 0o755);
}
export function writeNpmFreshnessConflictFixture(path: string, argsLog: string) {
writeFileSync(
path,
[
"#!/usr/bin/env bash",
"set -euo pipefail",
'if [[ "${1:-}" == "--version" ]]; then printf "11.15.0\\n"; exit 0; fi',
`printf '%s\\n' "$*" >> ${JSON.stringify(argsLog)}`,
'if [[ "$1" == "config" && "$2" == "get" && "$3" == "min-release-age" ]]; then',
" printf 'null\\n'",
" exit 0",
"fi",
'if [[ "$1" == "config" && "$2" == "get" && "$3" == "before" ]]; then',
" printf 'Wed May 13 2026 21:25:20 GMT-0300 (Brasilia Standard Time)\\n'",
" exit 0",
"fi",
'for arg in "$@"; do',
' if [[ "$arg" == --before=* ]]; then',
" printf '%s\\n' 'Exit prior to config file resolving' >&2",
" printf '%s\\n' 'cause' >&2",
" printf '%s\\n' '--min-release-age cannot be provided when using --before' >&2",
" exit 64",
" fi",
"done",
'for arg in "$@"; do',
' if [[ "$arg" == "--min-release-age=0" ]]; then',
" exit 0",
" fi",
"done",
"exit 65",
"",
].join("\n"),
);
chmodSync(path, 0o755);
}
export function writeNpmBeforePolicyFixture(path: string, argsLog: string) {
writeFileSync(
path,
[
"#!/usr/bin/env bash",
"set -euo pipefail",
'if [[ "${1:-}" == "--version" ]]; then printf "11.15.0\\n"; exit 0; fi',
`printf '%s\\n' "$*" >> ${JSON.stringify(argsLog)}`,
'if [[ "$1" == "config" && "$2" == "get" && "$3" == "min-release-age" ]]; then',
" printf 'null\\n'",
" exit 0",
"fi",
'if [[ "$1" == "config" && "$2" == "get" && "$3" == "before" ]]; then',
" printf 'Wed May 13 2026 21:25:20 GMT-0300 (Brasilia Standard Time)\\n'",
" exit 0",
"fi",
'for arg in "$@"; do',
' if [[ "$arg" == "--min-release-age=0" ]]; then',
" printf '%s\\n' 'min-release-age should not be selected for project-only npmrc' >&2",
" exit 64",
" fi",
"done",
'for arg in "$@"; do',
' if [[ "$arg" == --before=* ]]; then',
" exit 0",
" fi",
"done",
"exit 65",
"",
].join("\n"),
);
chmodSync(path, 0o755);
}
export function writeNpmLifecycleFixture(path: string) {
writeFileSync(
path,
[
"#!/usr/bin/env bash",
"set -euo pipefail",
'if [[ "${1:-}" == "--version" ]]; then',
' [[ "${NPM_FAKE_VERSION_STATUS:-0}" == "0" ]] || exit "$NPM_FAKE_VERSION_STATUS"',
' printf "%s\\n" "$NPM_FAKE_VERSION"',
" exit 0",
"fi",
'if [[ "${1:-}" == "root" ]]; then printf "%s\\n" "$NPM_FAKE_ROOT"; exit 0; fi',
'if [[ "${1:-}" == "config" ]]; then printf "null\\n"; exit 0; fi',
'printf "%s\\n" "$*" >> "$NPM_FAKE_ARGS"',
'mkdir -p "$NPM_FAKE_PACKAGE_DIR/dist"',
'printf "#!/usr/bin/env node\\n" > "$NPM_FAKE_PACKAGE_DIR/dist/entry.js"',
'if [[ "${NPM_FAKE_KEEP_GUARD:-0}" == "1" ]]; then : > "$NPM_FAKE_PACKAGE_DIR/dist/openclaw-install-guard"; else rm -f "$NPM_FAKE_PACKAGE_DIR/dist/openclaw-install-guard"; fi',
"exit 0",
"",
].join("\n"),
);
chmodSync(path, 0o755);
}