summaryrefslogtreecommitdiff
path: root/build.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-10 17:32:43 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commit685b8c8e74c9edbdf701594f50ff1b70ac288ec9 (patch)
treef303bd5e1f422030c2c645ea2d6c3a393990fb5e /build.zig
parentddc2eefb1e7cdd402593efb1297c25fc7ae4b110 (diff)
downloadpardes-685b8c8e74c9edbdf701594f50ff1b70ac288ec9.tar.gz
pardes-685b8c8e74c9edbdf701594f50ff1b70ac288ec9.zip
web snapshots: add switch for saving/loading exports, update web version, web snapshot tooling
Diffstat (limited to 'build.zig')
-rw-r--r--build.zig65
1 files changed, 60 insertions, 5 deletions
diff --git a/build.zig b/build.zig
index a387db9e..58179faf 100644
--- a/build.zig
+++ b/build.zig
@@ -1,7 +1,7 @@
const std = @import("std");
pub const Platform = enum { tty, gui, web };
-pub const TreeSitterGrammars = enum { disabled, minimal, full };
+pub const TreeSitterGrammars = enum { disabled, zig, minimal, full };
const GhosttyArtifact = enum { ghostty, lib };
pub fn build(b: *std.Build) void {
@@ -24,13 +24,62 @@ pub fn build(b: *std.Build) void {
const is_emscripten = target.result.os.tag == .emscripten;
// wasm: size is the budget
const optimize = if (is_emscripten) .ReleaseSmall else requested_optimize;
- const default_grammars: TreeSitterGrammars = if (is_emscripten) .minimal else .full;
- const tree_sitter_grammars = b.option(TreeSitterGrammars, "tree-sitter", "tree-sitter grammar set: disabled, minimal, full") orelse default_grammars;
+ const default_grammars: TreeSitterGrammars = if (is_emscripten) .zig else .full;
+ const tree_sitter_grammars = b.option(TreeSitterGrammars, "tree-sitter", "tree-sitter grammar set: disabled, zig, minimal (c/c++/zig), full") orelse default_grammars;
const tracy = b.option([]const u8, "tracy", "enable Tracy profiling; supply the path to a Tracy source checkout");
// the browser shell: zig object + emcc link + html, installed to zig-out/web
const web_step = b.step("web", "build the browser shell into zig-out/web (-Dplatform=web -Dtarget=wasm32-emscripten -Ddump=<dump.zon>)");
+ // Web LOOK has a tiny read-only source filesystem. Generate one Zig module
+ // on the host from every tracked .zig path + its current working-tree
+ // contents. The generator prefers Git as the tracked-file filter and has a
+ // conservative filesystem fallback for source archives without `.git`.
+ const source_gen = b.addExecutable(.{
+ .name = "pardes-embed-zig-sources",
+ .root_module = b.createModule(.{
+ .target = b.graph.host,
+ .optimize = .ReleaseSafe,
+ .root_source_file = b.path("tools/embed_zig_sources.zig"),
+ }),
+ });
+ const run_source_gen = b.addRunArtifact(source_gen);
+ run_source_gen.addDirectoryArg(b.path("."));
+ const embedded_sources = run_source_gen.addOutputFileArg("embedded_sources.zig");
+ // The tracked set can change without any already-known input changing, so
+ // discovery intentionally runs whenever a consumer builds it.
+ run_source_gen.has_side_effects = true;
+ const inspect_sources = b.addInstallFileWithDir(embedded_sources, .{ .custom = "web" }, "embedded_sources.zig");
+ b.step("embed-web-sources", "generate zig-out/web/embedded_sources.zig from tracked .zig files").dependOn(&inspect_sources.step);
+
+ // Browser regression suite: make an isolated web build from the real TTY
+ // dump captured after running `git ls-files '*.zig'`, with the Zig-only
+ // tree-sitter tier. The dependency-free CDP harness then drives
+ // its .snap script through real Chromium touch events. This recursive build
+ // selects `web`, not `web-snap`, so it bottoms out after one level.
+ const build_web_snap = b.addSystemCommand(&.{
+ b.graph.zig_exe,
+ "build",
+ "web",
+ "-Dplatform=web",
+ "-Dtarget=wasm32-emscripten",
+ "-Dtree-sitter=zig",
+ "-Ddump=test/web-snapshots/source-list.dump.zon",
+ "-p",
+ "zig-out/web-snap-test",
+ });
+ build_web_snap.setCwd(b.path("."));
+ const run_web_snap = b.addSystemCommand(&.{
+ "node",
+ "test/web_snapshot.mjs",
+ "zig-out/web-snap-test/web",
+ "test/web-snapshots/source-list.snap",
+ });
+ run_web_snap.setCwd(b.path("."));
+ run_web_snap.step.dependOn(&build_web_snap.step);
+ if (b.args) |args| run_web_snap.addArgs(args);
+ b.step("web-snap", "run browser touch/LOOK snapshots (-- --update regenerates goldens)").dependOn(&run_web_snap.step);
+
const emscripten_sysroot = if (is_emscripten) detectEmscriptenSysroot(b) else null;
if (platform == .web and !is_emscripten) return failBuild(b, web_step, "-Dplatform=web requires -Dtarget=wasm32-emscripten");
if (platform != .web and is_emscripten) return failBuild(b, web_step, "-Dtarget=wasm32-emscripten requires -Dplatform=web");
@@ -88,7 +137,8 @@ pub fn build(b: *std.Build) void {
const opts = b.addOptions();
opts.addOption(Platform, "platform", platform);
opts.addOption(bool, "syntax_highlighting", tree_sitter_grammars != .disabled);
- opts.addOption(bool, "syntax_minimal_grammars", tree_sitter_grammars != .disabled);
+ opts.addOption(bool, "syntax_zig_grammar", tree_sitter_grammars != .disabled);
+ opts.addOption(bool, "syntax_minimal_grammars", tree_sitter_grammars == .minimal or tree_sitter_grammars == .full);
opts.addOption(bool, "syntax_full_grammars", tree_sitter_grammars == .full);
opts.addOption(bool, "enable_tracy", tracy != null);
root_mod.addOptions("pardes_config", opts);
@@ -176,7 +226,10 @@ pub fn build(b: *std.Build) void {
};
const ts_queries = b.addOptions();
inline for (grammars) |g| {
- if (tree_sitter_grammars == .full or g.minimal) {
+ if (tree_sitter_grammars == .full or
+ (tree_sitter_grammars == .minimal and g.minimal) or
+ (tree_sitter_grammars == .zig and std.mem.eql(u8, g.name, "zig")))
+ {
const dep = b.dependency(g.dep, .{});
const query_path = dep.path(g.query);
const query = std.Io.Dir.cwd().readFileAlloc(io, query_path.getPath(b), b.allocator, .limited(0x100000)) catch @panic("read " ++ g.name ++ " highlights");
@@ -329,6 +382,7 @@ pub fn build(b: *std.Build) void {
root_mod.addAnonymousImport("embedded.dump.zon", .{
.root_source_file = if (std.fs.path.isAbsolute(dp)) .{ .cwd_relative = dp } else b.path(dp),
});
+ root_mod.addAnonymousImport("embedded_sources", .{ .root_source_file = embedded_sources });
} else {
root_mod.addAnonymousImport("ui.vert.spv", .{
.root_source_file = compileGlsl(b, "shaders/ui.vert.glsl", "vertex", "ui.vert.spv"),
@@ -376,6 +430,7 @@ pub fn build(b: *std.Build) void {
"-sMIN_WEBGL_VERSION=2",
"-sMAX_WEBGL_VERSION=2",
"-sINCOMING_MODULE_JS_API=canvas",
+ "-sEXPORTED_FUNCTIONS=['_main','_pardes_web_test_cols','_pardes_web_test_rows','_pardes_web_test_cursor_x','_pardes_web_test_cursor_y','_pardes_web_test_cell','_pardes_web_test_cell_fg','_pardes_web_test_cell_bg','_pardes_web_test_cell_attrs','_pardes_web_test_cell_x','_pardes_web_test_cell_y']",
"-o",
});
const js = emcc.addOutputFileArg("pardes.js");