authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-20 10:40:55-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-20 10:40:55-07:00
log86db35ca6175c3340a18d151a486b77b82664ba7
tree345746eaabd2e9fa4b617449e775e2493d531a71
parent97e5cd3bf7bbee427a177d5017aa2d250429bbf6
signature Signed by PGP key B5690EEEBB952194

[codex] Structure mobile native static-check failures (#3302)

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 37 insertions(+), 6 deletions(-)

scripts/mobile-native-static-check.test.ts created+18
...@@ -0,0 +1,18 @@
1import { assert, it } from "@effect/vitest";
2
3import { NativeStaticCheckCommandError } from "./mobile-native-static-check.ts";
4
5it("describes failed native static-analysis commands structurally", () => {
6 const error = new NativeStaticCheckCommandError({
7 command: "swiftlint",
8 args: ["lint", "--strict"],
9 cwd: "/repo/apps/mobile",
10 exitCode: 2,
11 });
12
13 assert.equal(error.command, "swiftlint");
14 assert.deepStrictEqual(error.args, ["lint", "--strict"]);
15 assert.equal(error.cwd, "/repo/apps/mobile");
16 assert.equal(error.exitCode, 2);
17 assert.equal(error.message, "Native static check command 'swiftlint' exited with code 2.");
18});
scripts/mobile-native-static-check.ts+19-6
...@@ -4,12 +4,12 @@ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";...@@ -4,12 +4,12 @@ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
4import * as NodeServices from "@effect/platform-node/NodeServices";4import * as NodeServices from "@effect/platform-node/NodeServices";
5import { isCommandAvailable, resolveSpawnCommand } from "@t3tools/shared/shell";5import { isCommandAvailable, resolveSpawnCommand } from "@t3tools/shared/shell";
6import * as Console from "effect/Console";6import * as Console from "effect/Console";
7import * as Data from "effect/Data";
8import * as Effect from "effect/Effect";7import * as Effect from "effect/Effect";
9import * as FileSystem from "effect/FileSystem";8import * as FileSystem from "effect/FileSystem";
10import * as Logger from "effect/Logger";9import * as Logger from "effect/Logger";
11import * as Path from "effect/Path";10import * as Path from "effect/Path";
12import * as PlatformError from "effect/PlatformError";11import * as PlatformError from "effect/PlatformError";
12import * as Schema from "effect/Schema";
13import { Command } from "effect/unstable/cli";13import { Command } from "effect/unstable/cli";
14import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";14import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
1515
...@@ -18,9 +18,19 @@ interface NativeStaticTool {...@@ -18,9 +18,19 @@ interface NativeStaticTool {
18 readonly installHint: string;18 readonly installHint: string;
19}19}
2020
21class NativeStaticCheckError extends Data.TaggedError("NativeStaticCheckError")<{21export class NativeStaticCheckCommandError extends Schema.TaggedErrorClass<NativeStaticCheckCommandError>()(
22 readonly message: string;22 "NativeStaticCheckCommandError",
23}> {}23 {
24 command: Schema.String,
25 args: Schema.Array(Schema.String),
26 cwd: Schema.String,
27 exitCode: Schema.Int,
28 },
29) {
30 override get message(): string {
31 return `Native static check command '${this.command}' exited with code ${this.exitCode}.`;
32 }
33}
2434
25const tools = [35const tools = [
26 {36 {
...@@ -85,8 +95,11 @@ const runCommand = Effect.fn("runCommand")(function* (...@@ -85,8 +95,11 @@ const runCommand = Effect.fn("runCommand")(function* (
85 const exitCode = Number(yield* child.exitCode);95 const exitCode = Number(yield* child.exitCode);
8696
87 if (exitCode !== 0) {97 if (exitCode !== 0) {
88 return yield* new NativeStaticCheckError({98 return yield* new NativeStaticCheckCommandError({
89 message: `Command exited with non-zero exit code (${exitCode})`,99 command,
100 args,
101 cwd,
102 exitCode,
90 });103 });
91 }104 }
92});105});