╭ changed ╮ │build.zig│ ╰─────────╯ ╭────────────────────────────────────────────────╮ │2 │ │3 pub fn build(b: *std.Build) void { │ │4 const xit_dep = b.dependency("xit", .{});│ │5 + const ansi_art = ansiArtModule(b); │ │6 │ │7 // wasm │ │8 const wasm_exe = blk: { │ ╰────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────╮ │58 .use_llvm = true, │ │59 }); │ │60 exe.root_module.addImport("xit", xit_dep.module("xit"));│ │61 + exe.root_module.addImport("ansi_art", ansi_art); │ │62 exe.root_module.addAnonymousImport("haxy.wasm", .{ │ │63 .root_source_file = wasm_exe.getEmittedBin(), │ │64 }); │ ╰────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────╮ │77 }), │ │78 }); │ │79 unit_tests.root_module.addImport("xit", xit_dep.module("xit"));│ │80 + unit_tests.root_module.addImport("ansi_art", ansi_art); │ │81 │ │82 const run_unit_tests = b.addRunArtifact(unit_tests); │ │83 run_unit_tests.has_side_effects = true; │ ╰───────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────╮ │91 .root_source_file = b.path("src/lib.zig"), │ │92 }); │ │93 haxy.addImport("xit", xit_dep.module("xit")); │ │94 + haxy.addImport("ansi_art", ansi_art); │ │95 haxy.addAnonymousImport("haxy.wasm", .{ │ │96 .root_source_file = wasm_exe.getEmittedBin(),│ │97 }); │ ╰─────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │131 .use_llvm = true, │ │132 }); │ │133 server_exe.root_module.addImport("xit", xit_dep.module("xit"));│ │134 + server_exe.root_module.addImport("ansi_art", ansi_art); │ │135 server_exe.root_module.addAnonymousImport("haxy.wasm", .{ │ │136 .root_source_file = wasm_exe.getEmittedBin(), │ │137 }); │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │153 test_step.dependOn(&run_unit_tests.step); │ │154 } │ │155 } │ │156 + │ │157 +// reads every ANSI-art text file while configuring the build. sorting keeps │ │158 +// the generated module stable when directory iteration order changes. │ │159 +fn ansiArtModule(b: *std.Build) *std.Build.Module { │ │160 + const io = b.graph.io; │ │161 + var dir = b.build_root.handle.openDir(io, "src/embed/ansi", .{ .iterate = true }) catch |err| { │ │162 + std.debug.panic("unable to open src/embed/ansi: {t}", .{err}); │ │163 + }; │ │164 + defer dir.close(io); │ │165 │ │166 + var names: std.ArrayList([]const u8) = .empty; │ │167 + var iter = dir.iterate(); │ │168 + while (iter.next(io) catch |err| std.debug.panic("unable to read src/embed/ansi: {t}", .{err})) |entry| {│ │169 + if (entry.kind != .file or !std.mem.endsWith(u8, entry.name, ".txt")) continue; │ │170 + names.append(b.allocator, b.dupe(entry.name)) catch @panic("OOM"); │ │171 + } │ │172 + std.mem.sort([]const u8, names.items, {}, struct { │ │173 + fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool { │ │174 + return std.mem.order(u8, lhs, rhs) == .lt; │ │175 + } │ │176 + }.lessThan); │ │177 + if (names.items.len == 0) @panic("src/embed/ansi must contain at least one .txt file"); │ │178 + │ │179 + const contents = b.allocator.alloc([]const u8, names.items.len) catch @panic("OOM"); │ │180 + for (names.items, contents) |name, *content| { │ │181 + content.* = dir.readFileAlloc(io, name, b.allocator, .limited(16 * 1024 * 1024)) catch |err| { │ │182 + std.debug.panic("unable to read src/embed/ansi/{s}: {t}", .{ name, err }); │ │183 + }; │ │184 + } │ │185 + │ │186 + const options = b.addOptions(); │ │187 + options.addOption([]const []const u8, "art", contents); │ │188 + return options.createModule(); │ │189 +} │ │190 + │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ removed ──────────╮ │src/embed/demon.ans│ ╰───────────────────╯ ╭ added ──────────────────────╮ │src/embed/ansi/demon-lord.txt│ ╰─────────────────────────────╯ ╭ added ──────────────────╮ │src/embed/ansi/dragon.txt│ ╰─────────────────────────╯ ╭ added ────────────────────╮ │src/embed/ansi/gargoyle.txt│ ╰───────────────────────────╯ ╭──────╮ │next →│ ╰──────╯