

















@@ -557,6 +557,173 @@ describe("install-cli.sh", () => {
557557}
558558});
559559560+it("replaces cached generic Node runtimes below the runtime floor", () => {
561+const tmp = mkdtempSync(join(tmpdir(), "openclaw-install-cli-generic-stale-node-"));
562+const prefix = join(tmp, "prefix");
563+const nodePrefixBin = join(prefix, "tools", "node-v22.22.0", "bin");
564+const staleNode = join(nodePrefixBin, "node");
565+const staleNpm = join(nodePrefixBin, "npm");
566+const newNode = join(tmp, "new-node");
567+const newNpm = join(tmp, "new-npm");
568+569+mkdirSync(nodePrefixBin, { recursive: true });
570+writeFileSync(
571+staleNode,
572+[
573+"#!/bin/bash",
574+'if [[ "${1:-}" == "-v" ]]; then',
575+" printf 'v22.18.0\\n'",
576+" exit 0",
577+"fi",
578+'if [[ "${1:-}" == "-e" ]]; then',
579+" exit 0",
580+"fi",
581+"exit 0",
582+"",
583+].join("\n"),
584+);
585+writeFileSync(staleNpm, ["#!/bin/bash", "exit 0", ""].join("\n"));
586+writeFileSync(
587+newNode,
588+[
589+"#!/bin/bash",
590+'if [[ "${1:-}" == "-v" ]]; then',
591+" printf 'v22.22.0\\n'",
592+" exit 0",
593+"fi",
594+'if [[ "${1:-}" == "-e" ]]; then',
595+" exit 0",
596+"fi",
597+"exit 0",
598+"",
599+].join("\n"),
600+);
601+writeFileSync(newNpm, ["#!/bin/bash", "exit 0", ""].join("\n"));
602+chmodSync(staleNode, 0o755);
603+chmodSync(staleNpm, 0o755);
604+chmodSync(newNode, 0o755);
605+chmodSync(newNpm, 0o755);
606+607+try {
608+const result = runInstallCliShell(
609+[
610+"set -euo pipefail",
611+`cd ${JSON.stringify(process.cwd())}`,
612+`source ${JSON.stringify(SCRIPT_PATH)}`,
613+"os_detect() { printf 'linux\\n'; }",
614+"arch_detect() { printf 'x64\\n'; }",
615+"is_musl_linux() { return 1; }",
616+"detect_downloader() { :; }",
617+"require_bin() { :; }",
618+"download_file() {",
619+' case "$1" in',
620+" */SHASUMS256.txt) printf 'fixture-sha node-v22.22.0-linux-x64.tar.gz\\n' > \"$2\" ;;",
621+" *) printf 'node tarball fixture\\n' > \"$2\" ;;",
622+" esac",
623+"}",
624+"sha256_file() { printf 'fixture-sha\\n'; }",
625+"tar() {",
626+" local dest=''",
627+" while [[ $# -gt 0 ]]; do",
628+' if [[ "$1" == \'-C\' ]]; then dest="$2"; shift 2; else shift; fi',
629+" done",
630+' mkdir -p "$dest/bin"',
631+' cp "$NEW_NODE" "$dest/bin/node"',
632+' cp "$NEW_NPM" "$dest/bin/npm"',
633+"}",
634+`PREFIX=${JSON.stringify(prefix)}`,
635+"NODE_VERSION=22.22.0",
636+"NODE_VERSION_REQUESTED=1",
637+"install_node",
638+].join("\n"),
639+{
640+NEW_NODE: newNode,
641+NEW_NPM: newNpm,
642+},
643+);
644+645+expect(result.status).toBe(0);
646+expect(result.stdout).toContain("Installing Node 22.22.0 (user-space)");
647+expect(result.stdout).not.toContain('"status":"skip"');
648+expect(readFileSync(staleNode, "utf8")).toContain("v22.22.0");
649+} finally {
650+rmSync(tmp, { force: true, recursive: true });
651+}
652+});
653+654+it("rejects downloaded generic Node runtimes below the runtime floor", () => {
655+const tmp = mkdtempSync(join(tmpdir(), "openclaw-install-cli-generic-old-node-"));
656+const prefix = join(tmp, "prefix");
657+const newNode = join(tmp, "new-node");
658+const newNpm = join(tmp, "new-npm");
659+660+writeFileSync(
661+newNode,
662+[
663+"#!/bin/bash",
664+'if [[ "${1:-}" == "-v" ]]; then',
665+" printf 'v22.18.0\\n'",
666+" exit 0",
667+"fi",
668+'if [[ "${1:-}" == "-e" ]]; then',
669+" exit 0",
670+"fi",
671+"exit 0",
672+"",
673+].join("\n"),
674+);
675+writeFileSync(newNpm, ["#!/bin/bash", "exit 0", ""].join("\n"));
676+chmodSync(newNode, 0o755);
677+chmodSync(newNpm, 0o755);
678+679+try {
680+const result = runInstallCliShell(
681+[
682+"set -euo pipefail",
683+`cd ${JSON.stringify(process.cwd())}`,
684+`source ${JSON.stringify(SCRIPT_PATH)}`,
685+"os_detect() { printf 'linux\\n'; }",
686+"arch_detect() { printf 'x64\\n'; }",
687+"is_musl_linux() { return 1; }",
688+"detect_downloader() { :; }",
689+"require_bin() { :; }",
690+"download_file() {",
691+' case "$1" in',
692+" */SHASUMS256.txt) printf 'fixture-sha node-v22.18.0-linux-x64.tar.gz\\n' > \"$2\" ;;",
693+" *) printf 'node tarball fixture\\n' > \"$2\" ;;",
694+" esac",
695+"}",
696+"sha256_file() { printf 'fixture-sha\\n'; }",
697+"tar() {",
698+" local dest=''",
699+" while [[ $# -gt 0 ]]; do",
700+' if [[ "$1" == \'-C\' ]]; then dest="$2"; shift 2; else shift; fi',
701+" done",
702+' mkdir -p "$dest/bin"',
703+' cp "$NEW_NODE" "$dest/bin/node"',
704+' cp "$NEW_NPM" "$dest/bin/npm"',
705+"}",
706+`PREFIX=${JSON.stringify(prefix)}`,
707+"NODE_VERSION=22.18.0",
708+"NODE_VERSION_REQUESTED=1",
709+"install_node",
710+].join("\n"),
711+{
712+NEW_NODE: newNode,
713+NEW_NPM: newNpm,
714+},
715+);
716+717+expect(result.status).toBe(1);
718+expect(result.stdout).toContain(
719+"Installed Node 22.18.0 must provide Node >= 22.19.0 with node:sqlite",
720+);
721+expect(result.stdout).toContain("found v22.18.0");
722+} finally {
723+rmSync(tmp, { force: true, recursive: true });
724+}
725+});
726+560727it("clears npm freshness filters for package installs", () => {
561728expect(script).toContain('freshness_flag="--min-release-age=0"');
562729expect(script).toContain('npm_config_has_raw_key "$(npm_bin)" "min-release-age"');
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。