Skip to content

refactor(codegen): extract blocks/scene_manifests.zig from main_zig.zig (part of #183) - #198

Merged
apotema merged 1 commit into
feat/183-split-main-zigfrom
refactor/183-extract-scene-manifests
May 25, 2026
Merged

apotema merged 1 commit into
feat/183-split-main-zigfrom
refactor/183-extract-scene-manifests

Conversation

@apotema

@apotema apotema commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Per the cut plan in #193 (step 5: blocks/scene_manifests.zig, low risk):

  • Moved writeSceneAssetManifests and writeSceneInitialStateManifests
    out of src/main_zig.zig into src/codegen/blocks/scene_manifests.zig
    (137-line module, well under the 200-line target).
  • Re-exported through main_zig.zig as pub const scene_manifests_block
    plus private function aliases so existing call sites inside the
    orchestrator stay unchanged (the pub const couldn't reuse the bare
    name scene_manifests because that's an existing function-parameter
    name elsewhere in the file — Zig forbids the shadow).
  • Depends on idents.zig from 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.zig and
blocks/asset_wiring.zig from the same base; the re-export header of
main_zig.zig will need a mechanical merge at merge time (each PR adds
one pub const line).

Test plan

  • zig build — clean
  • zig build test — exit 0, same test count
  • scripts/gen_all_examples.sh — 8/8 working examples generate (sokol_imgui soft-fails as expected without labelle-imgui sibling)
  • Bit-identical generated output:
    • 9/9 main.zig files byte-identical against refactor/183-extract-next
    • 65/65 .zig files byte-identical
    • 110/110 generated non-deps files byte-identical
    • Only flow_catalog.json differs (timestamp only, as documented in the cut plan)

Refs: #183
Builds on: #195

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/codegen/idents.zig
Comment on lines +77 to +93
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];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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
  1. 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.

Comment thread src/codegen/scan.zig
Comment on lines +756 to +759
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");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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
  1. 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).

@apotema
apotema changed the base branch from main to feat/183-split-main-zig May 25, 2026 18:55
@apotema
apotema marked this pull request as ready for review May 25, 2026 20:25
@cursor

cursor Bot commented May 25, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Mechanical move of pure writer functions with re-exports and aliases; PR claims bit-identical generated main.zig output.

Overview
Moves scene-manifest codegen out of main_zig.zig into a new leaf module codegen/blocks/scene_manifests.zig, continuing the #183 split of main_zig.zig.

writeSceneAssetManifests and writeSceneInitialStateManifests (comptime SceneAssetManifests / SceneInitialStateManifests emission for generated main.zig) are relocated unchanged. main_zig.zig imports the block as scene_manifests_block (avoids shadowing an existing scene_manifests parameter name) and keeps private aliases so template generation still calls the same unqualified names. Logic still depends on idents / scan helpers from #195.

No intended change to generated output; orchestrator call sites in generateMainZigFromTemplate stay the same.

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>
@apotema
apotema force-pushed the refactor/183-extract-scene-manifests branch from 5efa863 to aac4f23 Compare May 25, 2026 20:28
@apotema
apotema merged commit 555f911 into feat/183-split-main-zig May 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant