diff --git a/package.json b/package.json index 4947d0c..6518cdf 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "check:format": "biome check .", "format": "biome check --write .", "build:vscode": "bun run --cwd vscode build", - "build:zed": "cargo +1.90 build --manifest-path zed/Cargo.toml --locked --release --target wasm32-wasip2" + "build:zed": "bun scripts/build-zed.ts" }, "devDependencies": { "@biomejs/biome": "2.5.14", diff --git a/scripts/build-zed.test.ts b/scripts/build-zed.test.ts new file mode 100644 index 0000000..79a70d7 --- /dev/null +++ b/scripts/build-zed.test.ts @@ -0,0 +1,30 @@ +import { expect, test } from "bun:test"; +import { join, resolve } from "node:path"; +import { zedBuildEnvironment } from "./build-zed.ts"; + +test("remaps dependency source locations without splitting paths containing spaces", () => { + const cargoHome = resolve("fixture Cargo cache"); + const result = zedBuildEnvironment({ CARGO_HOME: cargoHome }); + expect(result.CARGO_ENCODED_RUSTFLAGS).toBe( + `--remap-path-prefix=${join(cargoHome, "registry", "src")}=/cargo/registry/src`, + ); +}); + +test("preserves existing encoded flags and unrelated build environment", () => { + const result = zedBuildEnvironment({ + CARGO_HOME: resolve("fixture-cargo"), + CARGO_ENCODED_RUSTFLAGS: "-C\x1fopt-level=z", + RUSTFLAGS: "ignored-by-cargo", + CARGO_NET_OFFLINE: "true", + }); + expect(result.CARGO_ENCODED_RUSTFLAGS?.split("\x1f").slice(0, 2)).toEqual(["-C", "opt-level=z"]); + expect(result.CARGO_NET_OFFLINE).toBe("true"); +}); + +test("preserves whitespace-separated RUSTFLAGS when no encoded flags were supplied", () => { + const result = zedBuildEnvironment({ + CARGO_HOME: resolve("fixture-cargo"), + RUSTFLAGS: "-C opt-level=2", + }); + expect(result.CARGO_ENCODED_RUSTFLAGS?.split("\x1f").slice(0, 2)).toEqual(["-C", "opt-level=2"]); +}); diff --git a/scripts/build-zed.ts b/scripts/build-zed.ts new file mode 100644 index 0000000..4a6060d --- /dev/null +++ b/scripts/build-zed.ts @@ -0,0 +1,38 @@ +import { spawnSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { join, resolve } from "node:path"; +import { assertPublicMessage } from "./publication-safety.ts"; + +export function zedBuildEnvironment(environment: NodeJS.ProcessEnv): NodeJS.ProcessEnv { + const cargoHome = resolve(environment.CARGO_HOME || join(homedir(), ".cargo")); + const flags = + environment.CARGO_ENCODED_RUSTFLAGS !== undefined + ? environment.CARGO_ENCODED_RUSTFLAGS.split("\x1f").filter(Boolean) + : (environment.RUSTFLAGS ?? "").split(/\s+/u).filter(Boolean); + flags.push(`--remap-path-prefix=${join(cargoHome, "registry", "src")}=/cargo/registry/src`); + return { ...environment, CARGO_ENCODED_RUSTFLAGS: flags.join("\x1f") }; +} + +if (import.meta.main) { + const result = spawnSync( + "cargo", + [ + "+1.90", + "build", + "--manifest-path", + "zed/Cargo.toml", + "--locked", + "--release", + "--target", + "wasm32-wasip2", + ], + { env: zedBuildEnvironment(process.env), stdio: "inherit", shell: false }, + ); + if (result.error) throw result.error; + if (result.status !== 0) process.exit(result.status ?? 1); + // Panic locations are data strings, so removing debug sections cannot sanitize them. + assertPublicMessage( + readFileSync("zed/target/wasm32-wasip2/release/rootform_zed.wasm").toString("utf8"), + ); +} diff --git a/scripts/verify.ts b/scripts/verify.ts index 049f7a1..9191619 100644 --- a/scripts/verify.ts +++ b/scripts/verify.ts @@ -56,7 +56,7 @@ try { for (const command of [ ["bun", "scripts/check-publication.ts"], - ["bun", "test", "scripts/publication-safety.test.ts"], + ["bun", "test", "scripts/publication-safety.test.ts", "scripts/build-zed.test.ts"], ["gitleaks", "git", "--no-banner", "--redact", "--config", ".gitleaks.toml", "."], ["bun", "run", "check:format"], ["bun", "run", "build:vscode"],