Repository navigation
refactor(codegen): extract blocks/scene_manifests.zig from main_zig.zig (part of #183) - #198
Conversation
There was a problem hiding this comment.
Code Review
This pull request initiates a refactoring plan to split the large src/main_zig.zig file into smaller, more modular submodules under src/codegen/. Specifically, it extracts discovery and scanning helpers into src/codegen/scan.zig, string and identifier helpers into src/codegen/idents.zig, and scene-manifest block writers into src/codegen/blocks/scene_manifests.zig, while maintaining backward compatibility via re-exports. It also introduces a verification script to ensure bit-identical output generation. The review feedback highlights two key improvements: updating pathToPascal to handle digit-leading paths by prefixing them with an underscore to avoid invalid Zig type names, and replacing std.debug.print with standard logging (std.log.err) for user-facing errors in CLI tools.
| pub fn pathToPascal(name: []const u8, pascal_buf: *[128]u8) []const u8 { | ||
| const end = if (std.mem.endsWith(u8, name, ".zig")) name.len - 4 else name.len; | ||
| var i: usize = 0; | ||
| var capitalize_next = true; | ||
| for (name[0..end]) |c| { | ||
| switch (c) { | ||
| 'A'...'Z', 'a'...'z', '0'...'9' => { | ||
| if (i >= pascal_buf.len) break; | ||
| pascal_buf[i] = if (capitalize_next) std.ascii.toUpper(c) else c; | ||
| i += 1; | ||
| capitalize_next = false; | ||
| }, | ||
| else => capitalize_next = true, | ||
| } | ||
| } | ||
| return pascal_buf[0..i]; | ||
| } |
There was a problem hiding this comment.
The pathToPascal function does not handle cases where the first alphanumeric character of the path is a digit (e.g., 2x2_tile). In Zig, identifiers (including type names) must not start with a digit. To prevent generating invalid Zig code, prefix the generated identifier with an underscore if the first character is a digit, matching the behavior of pathToIdent and sanitizePluginIdent.
pub fn pathToPascal(name: []const u8, pascal_buf: *[128]u8) []const u8 {
const end = if (std.mem.endsWith(u8, name, ".zig")) name.len - 4 else name.len;
var i: usize = 0;
var capitalize_next = true;
var first_char = true;
for (name[0..end]) |c| {
switch (c) {
'A'...'Z', 'a'...'z', '0'...'9' => {
if (i >= pascal_buf.len) break;
if (first_char and c >= '0' and c <= '9') {
pascal_buf[i] = '_';
i += 1;
if (i >= pascal_buf.len) break;
}
first_char = false;
pascal_buf[i] = if (capitalize_next) std.ascii.toUpper(c) else c;
i += 1;
capitalize_next = false;
},
else => capitalize_next = true,
}
}
return pascal_buf[0..i];
}
References
- Zig identifiers must not start with a digit. When converting strings (such as file paths) to Zig identifiers, prefix the result with an underscore if the input starts with a digit to ensure the generated code is valid.
| if (idx.* + bytes.len > b.len) { | ||
| std.debug.print("labelle: path too long for identifier (max {d} chars): too many escaped chars\n", .{b.len}); | ||
| @panic("path exceeds identifier buffer size"); | ||
| } |
There was a problem hiding this comment.
In CLI tools, user-facing warnings and errors should be written to stderr or logged using standard logging facilities (such as std.log.err or std.log.warn) rather than using debug-specific print functions like std.debug.print.
if (idx.* + bytes.len > b.len) {
std.log.err("labelle: path too long for identifier (max {d} chars): too many escaped chars", .{b.len});
@panic("path exceeds identifier buffer size");
}
References
- In CLI tools, use standard logging facilities (e.g. std.log.warn) or write to stderr for user-facing warnings, rather than using debug-specific print functions (e.g. std.debug.print).
PR SummaryLow Risk Overview
No intended change to generated output; orchestrator call sites in Reviewed by Cursor Bugbot for commit aac4f23. Bugbot is set up for automated code reviews on this repo. Configure here. |
…ig (part of #183) Per the plan in #193. Moved writeSceneAssetManifests and writeSceneInitialStateManifests to src/codegen/blocks/scene_manifests.zig (137 lines). Re-exported from main_zig.zig so callers don't change. Depends on idents.zig from #195 (writeZigString, pathToIdent). Bit-identical generated output across all 8 working bundled examples (scripts/gen_all_examples.sh green). Refs: #183 Builds on: #195 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5efa863 to
aac4f23
Compare
Summary
Per the cut plan in #193 (step 5:
blocks/scene_manifests.zig, low risk):writeSceneAssetManifestsandwriteSceneInitialStateManifestsout of
src/main_zig.zigintosrc/codegen/blocks/scene_manifests.zig(137-line module, well under the 200-line target).
main_zig.zigaspub const scene_manifests_blockplus private function aliases so existing call sites inside the
orchestrator stay unchanged (the
pub constcouldn't reuse the barename
scene_manifestsbecause that's an existing function-parametername elsewhere in the file — Zig forbids the shadow).
idents.zigfrom refactor(codegen): extract idents helpers from main_zig.zig (#183, step 2) #195 (writeZigString,pathToIdent).src/main_zig.zig: 3817 → 3714 lines (-103 lines net after re-exports).src/codegen/blocks/scene_manifests.zig: 137 lines (new).Base-branch dependency
Branched from
refactor/183-extract-next(the #195 idents extraction).Two sibling agents are simultaneously extracting
validate.zigandblocks/asset_wiring.zigfrom the same base; the re-export header ofmain_zig.zigwill need a mechanical merge at merge time (each PR addsone
pub constline).Test plan
zig build— cleanzig build test— exit 0, same test countscripts/gen_all_examples.sh— 8/8 working examples generate (sokol_imgui soft-fails as expected withoutlabelle-imguisibling)main.zigfiles byte-identical againstrefactor/183-extract-next.zigfiles byte-identicalflow_catalog.jsondiffers (timestamp only, as documented in the cut plan)Refs: #183
Builds on: #195