mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 03:02:56 +00:00
refactor: consolidate shared analysis boundaries (#10293)
This commit is contained in:
1 parent
6878a84796
commit
c836f57b7d
70 files changed
+1240
-1131
No files matched your search
@@ -18,6 +18,7 @@ import type { AnalysisError } from "../domain/analysisErrorBase.js";
|
||||
import { redactExplicitFailure } from "../domain/explicitSensitiveFailure.js";
|
||||
import { err, ok, type Result } from "../domain/result.js";
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { parseCliJsonOption } from "./cliJsonOption.js";
|
||||
import {
|
||||
createEvidenceBundle,
|
||||
createImmutableEvidenceBundle,
|
||||
@@ -102,20 +103,14 @@ export const parseCliAnalysisEvidenceDelivery = <
|
||||
Delivery & { readonly evidenceOutput: string | undefined },
|
||||
AnalysisError
|
||||
> => {
|
||||
let view: unknown;
|
||||
try {
|
||||
view = options.view === undefined ? undefined : JSON.parse(options.view);
|
||||
} catch (cause) {
|
||||
return err(
|
||||
new AnalysisInputError(operation, { cause }, [
|
||||
{
|
||||
path: ["view"],
|
||||
reason: "invalid_format",
|
||||
message: "view must be valid JSON",
|
||||
},
|
||||
]),
|
||||
);
|
||||
}
|
||||
const decoded = parseCliJsonOption(
|
||||
operation,
|
||||
"view",
|
||||
options.view,
|
||||
"view must be valid JSON",
|
||||
);
|
||||
if (!decoded.ok) return decoded;
|
||||
const view = decoded.value;
|
||||
const raw = {
|
||||
detail: options.detail,
|
||||
...(view === undefined ? {} : { view }),
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "./analysisEvidenceDelivery.js";
|
||||
import { androidPackageDeliverySchema } from "../domain/android/androidPackageQuery.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { parseCliJsonOption } from "./cliJsonOption.js";
|
||||
import { parseAnalysisInput } from "../application/AnalysisInput.js";
|
||||
import { androidJniSelectionSchema } from "../domain/android/androidJniBindings.js";
|
||||
import { androidJniDeliverySchema } from "../domain/android/androidJniQuery.js";
|
||||
@@ -105,21 +105,14 @@ export const registerAndroidCommands = (
|
||||
androidJniDeliverySchema,
|
||||
);
|
||||
if (!delivery.ok) return projectAnalysisError(delivery.error);
|
||||
let query: unknown = {};
|
||||
try {
|
||||
if (options.query !== undefined)
|
||||
query = JSON.parse(options.query);
|
||||
} catch (cause: unknown) {
|
||||
return projectAnalysisError(
|
||||
new AnalysisInputError(operation, { cause }, [
|
||||
{
|
||||
path: ["query"],
|
||||
reason: "invalid_format",
|
||||
message: "query must be a JSON selection object.",
|
||||
},
|
||||
]),
|
||||
);
|
||||
}
|
||||
const decoded = parseCliJsonOption(
|
||||
operation,
|
||||
"query",
|
||||
options.query,
|
||||
"query must be a JSON selection object.",
|
||||
);
|
||||
if (!decoded.ok) return projectAnalysisError(decoded.error);
|
||||
const query = decoded.value === undefined ? {} : decoded.value;
|
||||
const selected = parseAnalysisInput(
|
||||
operation,
|
||||
query,
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { parseCliJsonOption } from "./cliJsonOption.js";
|
||||
import { z } from "incur";
|
||||
import type { Logger } from "pino";
|
||||
import { APK_SIGNATURE_PROVIDER_IDENTITY } from "../apkSignature/ApkSignatureRelease.js";
|
||||
import { apkSignatureModule } from "../composition/apkSignature.js";
|
||||
import { inspectApkSignatureInputSchema } from "../domain/apkSignature/apkSignatureQuery.js";
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { safeParseJson } from "../domain/safeJson.js";
|
||||
import { logCliCommand } from "../cliLogging.js";
|
||||
import { localPathStringSchema } from "../domain/localPath.js";
|
||||
import { absoluteCallerPath } from "../filesystem/callerPath.js";
|
||||
@@ -41,24 +40,13 @@ export const registerApkSignatureCommands = (
|
||||
run: ({ args, options }) =>
|
||||
withCommandCancellation((signal) =>
|
||||
logCliCommand(logger, apkSignatureModule.cliCommand, async () => {
|
||||
const decoded =
|
||||
options.view === undefined
|
||||
? { ok: true as const, value: undefined }
|
||||
: safeParseJson(options.view);
|
||||
if (!decoded.ok)
|
||||
return projectAnalysisError(
|
||||
new AnalysisInputError(
|
||||
"inspect_apk_signature",
|
||||
{ cause: decoded.cause },
|
||||
[
|
||||
{
|
||||
path: ["view"],
|
||||
reason: "invalid_format",
|
||||
message: "view must be a JSON APK signature selection",
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
const decoded = parseCliJsonOption(
|
||||
"inspect_apk_signature",
|
||||
"view",
|
||||
options.view,
|
||||
"view must be a JSON APK signature selection",
|
||||
);
|
||||
if (!decoded.ok) return projectAnalysisError(decoded.error);
|
||||
const input = inspectApkSignatureInputSchema.safeParse({
|
||||
path: absoluteCallerPath(args.path),
|
||||
detail: options.detail,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { err, ok, type Result } from "../domain/result.js";
|
||||
import { safeParseJson } from "../domain/safeJson.js";
|
||||
|
||||
/** Decode one named CLI option before using the selected inputs. */
|
||||
export const parseCliJsonOption = (
|
||||
operation: string,
|
||||
name: string,
|
||||
text: string | undefined,
|
||||
message: string,
|
||||
): Result<unknown, AnalysisInputError> => {
|
||||
if (text === undefined) return ok(undefined);
|
||||
const parsed = safeParseJson(text);
|
||||
return parsed.ok
|
||||
? parsed
|
||||
: err(
|
||||
new AnalysisInputError(operation, { cause: parsed.cause }, [
|
||||
{ path: [name], reason: "invalid_format", message },
|
||||
]),
|
||||
);
|
||||
};
|
||||
+8
-18
@@ -1,8 +1,7 @@
|
||||
import { inspectGpuCodeObjectsInputSchema } from "../domain/gpu/gpuCodeObjects.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
import { safeParseJson } from "../domain/safeJson.js";
|
||||
import { parseCliJsonOption } from "./cliJsonOption.js";
|
||||
import { z } from "incur";
|
||||
import type { Logger } from "pino";
|
||||
import type { CliInstance } from "./types.js";
|
||||
@@ -61,22 +60,13 @@ export const registerGpuCommands = (cli: CliInstance, logger: Logger): void => {
|
||||
for (const name of ["object_ids", "targets", "view"] as const) {
|
||||
const value = options[name];
|
||||
if (value === undefined) continue;
|
||||
const decoded = safeParseJson(value);
|
||||
if (!decoded.ok) {
|
||||
return projectAnalysisError(
|
||||
new AnalysisInputError(
|
||||
"inspect_gpu_code_objects",
|
||||
{ cause: decoded.cause },
|
||||
[
|
||||
{
|
||||
path: [name],
|
||||
reason: "invalid_format",
|
||||
message: `${name} must be valid JSON`,
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
const decoded = parseCliJsonOption(
|
||||
"inspect_gpu_code_objects",
|
||||
name,
|
||||
value,
|
||||
`${name} must be valid JSON`,
|
||||
);
|
||||
if (!decoded.ok) return projectAnalysisError(decoded.error);
|
||||
selectors[name] = decoded.value;
|
||||
}
|
||||
const rawInput = {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { parseCliJsonOption } from "./cliJsonOption.js";
|
||||
import { inspectModelArtifactInputSchema } from "../domain/model/modelArtifactQuery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
import { safeParseJson } from "../domain/safeJson.js";
|
||||
import { z } from "incur";
|
||||
import type { Logger } from "pino";
|
||||
import type { CliInstance } from "./types.js";
|
||||
@@ -48,25 +47,13 @@ export const registerModelCommands = (
|
||||
run: ({ args, options }) =>
|
||||
withCommandCancellation((signal) =>
|
||||
logCliCommand(logger, CLI_COMMANDS.inspectModelArtifact, async () => {
|
||||
const decoded =
|
||||
options.view === undefined
|
||||
? { ok: true as const, value: undefined }
|
||||
: safeParseJson(options.view);
|
||||
if (!decoded.ok) {
|
||||
return projectAnalysisError(
|
||||
new AnalysisInputError(
|
||||
"inspect_model_artifact",
|
||||
{ cause: decoded.cause },
|
||||
[
|
||||
{
|
||||
path: ["view"],
|
||||
reason: "invalid_format",
|
||||
message: "view must be a JSON model page selection",
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
const decoded = parseCliJsonOption(
|
||||
"inspect_model_artifact",
|
||||
"view",
|
||||
options.view,
|
||||
"view must be a JSON model page selection",
|
||||
);
|
||||
if (!decoded.ok) return projectAnalysisError(decoded.error);
|
||||
const view = decoded.value;
|
||||
const selected = inspectModelArtifactInputSchema.safeParse({
|
||||
path: absoluteCallerPath(args.path),
|
||||
|
||||
+8
-21
@@ -1,3 +1,4 @@
|
||||
import { parseCliJsonOption } from "./cliJsonOption.js";
|
||||
import { z } from "incur";
|
||||
import { producerLimitsOption } from "./producerLimitsOption.js";
|
||||
import { rustProducerLimitsSchema } from "../domain/rust/rustResourceLimits.js";
|
||||
@@ -12,9 +13,7 @@ import {
|
||||
} from "./analysisEvidenceDelivery.js";
|
||||
import { inspectRustBinaryRequestSchema } from "../domain/rust/rustBinaryQuery.js";
|
||||
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
|
||||
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
|
||||
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
||||
import { safeParseJson } from "../domain/safeJson.js";
|
||||
import type { Logger } from "pino";
|
||||
import type { CliInstance } from "./types.js";
|
||||
import { withCommandCancellation } from "./commandCancellation.js";
|
||||
@@ -62,25 +61,13 @@ export const registerRustCommands = (
|
||||
run: ({ args, options }) =>
|
||||
withCommandCancellation((signal) =>
|
||||
logCliCommand(logger, CLI_COMMANDS.inspectRustBinary, async () => {
|
||||
const decoded =
|
||||
options.view === undefined
|
||||
? { ok: true as const, value: undefined }
|
||||
: safeParseJson(options.view);
|
||||
if (!decoded.ok) {
|
||||
return projectAnalysisError(
|
||||
new AnalysisInputError(
|
||||
"inspect_rust_binary",
|
||||
{ cause: decoded.cause },
|
||||
[
|
||||
{
|
||||
path: ["view"],
|
||||
reason: "invalid_format",
|
||||
message: "view must be a JSON package or edge selection",
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
const decoded = parseCliJsonOption(
|
||||
"inspect_rust_binary",
|
||||
"view",
|
||||
options.view,
|
||||
"view must be a JSON package or edge selection",
|
||||
);
|
||||
if (!decoded.ok) return projectAnalysisError(decoded.error);
|
||||
const view = decoded.value;
|
||||
const input = inspectRustBinaryRequestSchema.safeParse({
|
||||
path: absoluteCallerPath(args.path),
|
||||
|
||||
Reference in new issue
Block a user