Merge remote-tracking branch 'origin/main' into codex/bug-sweep-20261015-final
This commit is contained in:
commit
930dd5357f
3 files changed
+37
-10
No files matched your search
@@ -7,7 +7,7 @@ import { inspectAppleDispatchMetadata } from "./AppleDispatchMetadata.js";
|
||||
import { observeNativeUi } from "./NativeUiObservation.js";
|
||||
import { LldbCallTracer, type NativeCallTracer } from "./LldbCallTracer.js";
|
||||
import { observeNativeCalls } from "./NativeCallObservation.js";
|
||||
import { dirname, isAbsolute, resolve } from "node:path";
|
||||
import { basename, dirname, isAbsolute, resolve } from "node:path";
|
||||
import { open, realpath, stat } from "node:fs/promises";
|
||||
|
||||
import { z } from "zod";
|
||||
@@ -1094,7 +1094,7 @@ const unreadablePlist = (
|
||||
): AnalysisError => {
|
||||
const sentence = reason.endsWith(".") ? reason : `${reason}.`;
|
||||
// Name the default that is missing and the selection that still works.
|
||||
const missingDefault = `The target has no readable Contents/Info.plist at ${path}: ${sentence} Select another plist in the target with the path input (CLI: --relative-path).`;
|
||||
const missingDefault = `The target has no readable default plist at ${path}: ${sentence} Select another plist in the target with the path input (CLI: --relative-path).`;
|
||||
return requested === undefined
|
||||
? new AnalysisCapabilityUnavailableError(
|
||||
IDENTITY.id,
|
||||
@@ -1150,6 +1150,15 @@ const requireRegularPlist = async (
|
||||
}
|
||||
};
|
||||
|
||||
/** The bundle whose Contents/MacOS directory directly holds `path`. */
|
||||
const macOSBundleRoot = (path: string): string | undefined => {
|
||||
const programs = dirname(path);
|
||||
const contents = dirname(programs);
|
||||
return basename(programs) === "MacOS" && basename(contents) === "Contents"
|
||||
? dirname(contents)
|
||||
: undefined;
|
||||
};
|
||||
|
||||
const resolvePlistPath = async (
|
||||
target: BinaryTarget,
|
||||
requested: string | undefined,
|
||||
@@ -1159,8 +1168,13 @@ const resolvePlistPath = async (
|
||||
if (requested !== undefined && isAbsolute(requested))
|
||||
return ok(resolve(requested));
|
||||
const sourceMetadata = await stat(source);
|
||||
const root = sourceMetadata.isDirectory() ? source : dirname(target.path);
|
||||
const root = sourceMetadata.isDirectory()
|
||||
? source
|
||||
: (macOSBundleRoot(target.path) ?? dirname(target.path));
|
||||
if (requested !== undefined) return ok(resolve(root, requested));
|
||||
// A selected plist file is itself the plist to inspect.
|
||||
if (target.kind === "artifact" && target.format === "plist")
|
||||
return ok(target.path);
|
||||
// A bundle target records the Info.plist its program file was declared
|
||||
// in: Contents/Info.plist, or the root plist of an iOS-style bundle.
|
||||
return ok(target.bundleInfoPlist ?? resolve(root, "Contents/Info.plist"));
|
||||
|
||||
@@ -12,13 +12,22 @@ import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
describe.skipIf(process.platform !== "darwin")(
|
||||
"native plist CLI selection",
|
||||
() => {
|
||||
// Targets are app-relative: the bundle, its program file, or a plist file.
|
||||
cliTest.for([
|
||||
["default", undefined, "default"],
|
||||
["alternate", "Contents/Alternate.plist", "alternate"],
|
||||
["missing", "Contents/Missing.plist", undefined],
|
||||
["default", "", undefined, "default"],
|
||||
["alternate", "", "Contents/Alternate.plist", "alternate"],
|
||||
["missing", "", "Contents/Missing.plist", undefined],
|
||||
["program default", "Contents/MacOS/App", undefined, "default"],
|
||||
[
|
||||
"program alternate",
|
||||
"Contents/MacOS/App",
|
||||
"Contents/Alternate.plist",
|
||||
"alternate",
|
||||
],
|
||||
["plist file", "Contents/Alternate.plist", undefined, "alternate"],
|
||||
] as const)(
|
||||
"honors the $0 plist selection",
|
||||
async ([, selected, identifier], { cli }) => {
|
||||
async ([, target, selected, identifier], { cli }) => {
|
||||
const directory = await createTestTempDirectory("rea-plist-cli-");
|
||||
const app = join(directory, "Example.app");
|
||||
const contents = join(app, "Contents");
|
||||
@@ -39,7 +48,7 @@ describe.skipIf(process.platform !== "darwin")(
|
||||
const result = await cli.run({
|
||||
arguments: [
|
||||
"inspect-plist",
|
||||
app,
|
||||
join(app, target),
|
||||
...(selected === undefined ? [] : ["--relative-path", selected]),
|
||||
"--json",
|
||||
],
|
||||
@@ -55,7 +64,11 @@ describe.skipIf(process.platform !== "darwin")(
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.json).toMatchObject({
|
||||
normalized_result: {
|
||||
source_path: join(app, selected ?? "Contents/Info.plist"),
|
||||
source_path: join(
|
||||
app,
|
||||
selected ??
|
||||
(target.endsWith(".plist") ? target : "Contents/Info.plist"),
|
||||
),
|
||||
value: { CFBundleIdentifier: identifier },
|
||||
},
|
||||
});
|
||||
|
||||
@@ -122,7 +122,7 @@ describe.skipIf(process.platform !== "darwin")(
|
||||
details: {
|
||||
operation: "inspect_plist",
|
||||
reason: expect.stringContaining(
|
||||
`no readable Contents/Info.plist at ${join(directory, "Contents/Info.plist")}: no file exists there.`,
|
||||
`no readable default plist at ${join(directory, "Contents/Info.plist")}: no file exists there.`,
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user