mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-14 11:56:06 +00:00
fix(cli): preserve literal --update subcommand args (#106144)
Co-authored-by: xydt-juyaohui <xydt-juyaohui@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "@openclaw/normalization-core/string-coerce";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { consumeRootOptionToken, FLAG_TERMINATOR } from "../infra/cli-root-options.js";
|
||||
import {
|
||||
resolveManifestCommandAliasOwnerInRegistry,
|
||||
resolveManifestToolOwnerInRegistry,
|
||||
@@ -37,14 +38,33 @@ function isBareParentDefaultHelpArgv(argv: string[]): boolean {
|
||||
|
||||
export function rewriteUpdateFlagArgv(argv: string[]): string[] {
|
||||
// Preserve the old root --update spelling by rewriting before Commander registration.
|
||||
const index = argv.indexOf("--update");
|
||||
if (index === -1) {
|
||||
// Only rewrite --update while scanning the root-option prefix; once a command
|
||||
// or `--` appears, later --update tokens belong to that command's arguments.
|
||||
const updateIndex = argv.indexOf("--update");
|
||||
if (updateIndex === -1) {
|
||||
return argv;
|
||||
}
|
||||
|
||||
const next = [...argv];
|
||||
next.splice(index, 1, "update");
|
||||
return next;
|
||||
for (let i = 2; i < argv.length; i++) {
|
||||
const arg = argv[i];
|
||||
if (!arg || arg === FLAG_TERMINATOR) {
|
||||
return argv;
|
||||
}
|
||||
if (i === updateIndex) {
|
||||
const next = [...argv];
|
||||
next.splice(updateIndex, 1, "update");
|
||||
return next;
|
||||
}
|
||||
const consumed = consumeRootOptionToken(argv, i);
|
||||
if (consumed > 0) {
|
||||
i += consumed - 1;
|
||||
continue;
|
||||
}
|
||||
if (!arg.startsWith("-")) {
|
||||
return argv;
|
||||
}
|
||||
}
|
||||
return argv;
|
||||
}
|
||||
|
||||
export function shouldEnsureCliPath(argv: string[]): boolean {
|
||||
|
||||
@@ -130,6 +130,45 @@ describe("rewriteUpdateFlagArgv", () => {
|
||||
"--json",
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not rewrite --update after -- positional terminator", () => {
|
||||
expect(
|
||||
rewriteUpdateFlagArgv(["node", "entry.js", "config", "set", "foo", "--", "--update"]),
|
||||
).toEqual(["node", "entry.js", "config", "set", "foo", "--", "--update"]);
|
||||
});
|
||||
|
||||
it("does not rewrite --update when a subcommand appears before it", () => {
|
||||
expect(
|
||||
rewriteUpdateFlagArgv(["node", "entry.js", "config", "set", "update.channel", "--update"]),
|
||||
).toEqual(["node", "entry.js", "config", "set", "update.channel", "--update"]);
|
||||
});
|
||||
|
||||
it("does not rewrite --update that appears as a value after a subcommand", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "config", "set", "foo", "--update"])).toEqual(
|
||||
["node", "entry.js", "config", "set", "foo", "--update"],
|
||||
);
|
||||
});
|
||||
|
||||
it("rewrites --update when it appears before any subcommand", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "--update", "config", "set", "foo"])).toEqual(
|
||||
["node", "entry.js", "update", "config", "set", "foo"],
|
||||
);
|
||||
});
|
||||
|
||||
it("rewrites --update after root boolean flags", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "--no-color", "--update"])).toEqual([
|
||||
"node",
|
||||
"entry.js",
|
||||
"--no-color",
|
||||
"update",
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not skip root boolean flag followers as option values", () => {
|
||||
expect(rewriteUpdateFlagArgv(["node", "entry.js", "--no-color", "status", "--update"])).toEqual(
|
||||
["node", "entry.js", "--no-color", "status", "--update"],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("shouldEnsureCliPath", () => {
|
||||
|
||||
Reference in New Issue
Block a user