mirror of
https://github.com/morluto/rea.git
synced 2026-11-07 07:16:13 +00:00
fix(cli): require absolute ADB device paths for file pull and push (#9048)
pull-adb-file and push-adb-file declared device-path as any non-empty string. The CLI schema advertised a relative path as valid, and the service then refused it under the MCP field name. Reuse the shared device_path fields, and keep the regex constraint in CLI field errors as list-adb-directory does.
This commit is contained in:
3 files changed
+46
-8
No files matched your search
@@ -145,7 +145,7 @@ export const registerAdbCommands = (
|
||||
description: "Pull one device file to a local copy with a SHA-256 digest",
|
||||
args: z.object({
|
||||
serial,
|
||||
"device-path": z.string().min(1).describe("Absolute device path to pull"),
|
||||
"device-path": adbInputSchemas.pull_adb_file.shape.device_path,
|
||||
}),
|
||||
options: z.object({
|
||||
"output-directory": z
|
||||
@@ -166,7 +166,7 @@ export const registerAdbCommands = (
|
||||
args: z.object({
|
||||
serial,
|
||||
"local-path": z.string().min(1).describe("Existing local file"),
|
||||
"device-path": z.string().min(1).describe("Absolute device destination"),
|
||||
"device-path": adbInputSchemas.push_adb_file.shape.device_path,
|
||||
}),
|
||||
options: z.object({
|
||||
overwrite: z
|
||||
|
||||
@@ -22,6 +22,8 @@ const isAdbSelector = (command: string, field: string): boolean =>
|
||||
(adbPackageCommands.has(command) && field === "package") ||
|
||||
(command === "list-adb-directory" && field === "device-path") ||
|
||||
(command === "resolve-adb-packages" && field === "query") ||
|
||||
(["pull-adb-file", "push-adb-file"].includes(command) &&
|
||||
field === "device-path") ||
|
||||
(command === "start-adb-activity" &&
|
||||
["action", "component", "data-uri"].includes(field));
|
||||
|
||||
|
||||
@@ -12,7 +12,18 @@ import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
|
||||
|
||||
const PACKAGE_LINE = "package:/data/app/example/base.apk=com.example.app";
|
||||
|
||||
cliTest.for([
|
||||
interface AdbSelectorCase {
|
||||
readonly command: string;
|
||||
readonly field: string;
|
||||
readonly valid: string;
|
||||
readonly invalid: string;
|
||||
readonly constraint: Readonly<Record<string, unknown>>;
|
||||
/** Positional arguments between the serial and the checked field. */
|
||||
readonly between?: Readonly<Record<string, string>>;
|
||||
readonly options?: readonly string[];
|
||||
}
|
||||
|
||||
cliTest.for<AdbSelectorCase>([
|
||||
{
|
||||
command: "list-adb-directory",
|
||||
field: "device-path",
|
||||
@@ -20,6 +31,22 @@ cliTest.for([
|
||||
invalid: "sdcard",
|
||||
constraint: { expected: "regex" },
|
||||
},
|
||||
{
|
||||
command: "pull-adb-file",
|
||||
field: "device-path",
|
||||
valid: "/sdcard/notes.txt",
|
||||
invalid: "sdcard/notes.txt",
|
||||
constraint: { expected: "regex" },
|
||||
options: ["--output-directory", "pulled"],
|
||||
},
|
||||
{
|
||||
command: "push-adb-file",
|
||||
field: "device-path",
|
||||
valid: "/data/local/tmp/payload.bin",
|
||||
invalid: "data/local/tmp/payload.bin",
|
||||
constraint: { expected: "regex" },
|
||||
between: { "local-path": "payload.bin" },
|
||||
},
|
||||
{
|
||||
command: "resolve-adb-packages",
|
||||
field: "query",
|
||||
@@ -29,18 +56,27 @@ cliTest.for([
|
||||
},
|
||||
])(
|
||||
"publishes the enforced ADB selector constraint for $command",
|
||||
async ({ command, field, valid, invalid, constraint }, { cli }) => {
|
||||
async (
|
||||
{ command, field, valid, invalid, constraint, between = {}, options = [] },
|
||||
{ cli },
|
||||
) => {
|
||||
const schema = await cli.run({
|
||||
arguments: [command, "--schema", "--json"],
|
||||
});
|
||||
expect(schema.exitCode, schema.stderr).toBe(0);
|
||||
const output = schema.json as { args: Parameters<Ajv2020["compile"]>[0] };
|
||||
const validate = new Ajv2020({ strict: false }).compile(output.args);
|
||||
const serial = "emulator-5554";
|
||||
expect(validate({ serial, [field]: valid })).toBe(true);
|
||||
expect(validate({ serial, [field]: invalid })).toBe(false);
|
||||
const leading = { serial: "emulator-5554", ...between };
|
||||
expect(validate({ ...leading, [field]: valid })).toBe(true);
|
||||
expect(validate({ ...leading, [field]: invalid })).toBe(false);
|
||||
const result = await cli.run({
|
||||
arguments: [command, serial, invalid, "--json"],
|
||||
arguments: [
|
||||
command,
|
||||
...Object.values(leading),
|
||||
invalid,
|
||||
...options,
|
||||
"--json",
|
||||
],
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.json).toMatchObject({
|
||||
|
||||
Reference in new issue
Block a user