Skip to content

refactor: split build_files.zig into focused sub-modules (behavior-preserving) - #549

Merged
apotema merged 1 commit into
mainfrom
refactor/split-build-files
Jul 5, 2026
Merged

refactor: split build_files.zig into focused sub-modules (behavior-preserving)#549
apotema merged 1 commit into
mainfrom
refactor/split-build-files

Conversation

@apotema

@apotema apotema commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What

Pure, behavior-preserving extraction of src/build_files.zig (~1165 lines) into a src/build_files/ sub-package, leaving build_files.zig a thin 35-line barrel. Mirrors the proven #539/#541 pattern.

Sections

Split along the natural, cohesive seam the file already documented with ==== banners: build.zig generation vs build.zig.zon generation. No private helper crosses the boundary (sanitizeExeName is build.zig-only; v2BackendDepName/relativePath/generateZonPathsFallback are zon-only), so there are no circular imports.

  • build_files/build_zig.zig (862 lines) — sanitizeExeName, BuildZigOptions, generateBuildZig, plus the emit* helpers, desktopUsesGenericV2, androidNeedsAppImport, inProjectLibDir.
  • build_files/build_zig_zon.zig (323 lines) — BuildZigZonOptions, generateBuildZigZon, the deps-link/fallback path, the deps_linker re-export, v2BackendDepName, relativePath.
  • build_files.zig (35 lines) — barrel re-exporting the exact public surface.

Unchanged public surface

Every re-exported symbol keeps its original name and identity, so root.zig's build_files.generateBuildZig / BuildZigOptions / generateBuildZigZon / deps_linker call sites are untouched. Sub-files are path-@import'd (embed paths adjusted templates/…../templates/…); no build.zig change.

Before / after

file before after
build_files.zig 1165 35
build_files/build_zig.zig 862
build_files/build_zig_zon.zig 323

Bar

  • zig build — green
  • zig build test — green (exit 0)
  • golden suite — zero diff (the golden-comparison tests run under zig build test; any byte divergence would fail the run)
  • zig fmt --check — clean

https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw

Summary by CodeRabbit

  • Refactor
    • Split build-file generation into smaller, focused pieces while keeping the same public behavior.
    • Improved build output handling for desktop, web, iOS, and Android targets.
    • Added safer executable name handling and better support for generated dependency manifests.
    • Strengthened compatibility checks so unsupported setups fail earlier and more clearly.

…eserving)

Pure extraction, mirrors #539/#541. `build_files.zig` was a single
~1165-line module; it is now a 35-line barrel re-exporting the public
surface from two cohesive sub-modules under `build_files/`:

  - build_files/build_zig.zig     — build.zig generation (sanitizeExeName,
                                     BuildZigOptions, generateBuildZig, emit*
                                     helpers, desktopUsesGenericV2, ...)
  - build_files/build_zig_zon.zig — build.zig.zon generation
                                     (BuildZigZonOptions, generateBuildZigZon,
                                     deps-link/fallback path, deps_linker
                                     re-export, v2BackendDepName, relativePath)

Split along the natural build.zig-vs-build.zig.zon seam; no private helper
crosses the boundary. Public surface (root.zig call sites) unchanged; every
symbol keeps its name and identity. Sub-files are path-@import'd (no
build.zig change). `zig build` + `zig build test` green; golden suite
zero diff; `zig fmt --check` clean.

Claude-Session: https://claude.ai/code/session_017pW3ifKf9wgxNg4viy6okw
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7dab2ece-def5-45ad-bb08-74814cc88414

📥 Commits

Reviewing files that changed from the base of the PR and between cd062ec and 1e71610.

📒 Files selected for processing (3)
  • src/build_files.zig
  • src/build_files/build_zig.zig
  • src/build_files/build_zig_zon.zig

📝 Walkthrough

Walkthrough

The monolithic src/build_files.zig was split into two new sub-modules, src/build_files/build_zig.zig and src/build_files/build_zig_zon.zig, containing the build.zig and build.zig.zon generation logic respectively, with the original file reduced to a thin barrel re-exporting the same public API.

Changes

build.zig / build.zig.zon generator split

Layer / File(s) Summary
Barrel re-export
src/build_files.zig
File reduced to imports of the two sub-modules, re-exports of sanitizeExeName, BuildZigOptions, generateBuildZig, deps_linker, BuildZigZonOptions, generateBuildZigZon, plus a test block forcing compilation of both.
build.zig generator core
src/build_files/build_zig.zig
New module with template embedding, helpers (inProjectLibDir, sanitizeExeName, desktopUsesGenericV2, androidNeedsAppImport), promoted-script/pack module emission, BuildZigOptions, and generateBuildZig handling wasm/ios/android/desktop platform routing with manifest-v2 validation and capability negotiation.
build.zig.zon generator core
src/build_files/build_zig_zon.zig
New module implementing BuildZigZonOptions, v2BackendDepName, generateBuildZigZon (hardlink deps creation with fallback, Zig 0.16 fingerprinting, v2-aware backend dep re-keying and wasm emsdk deps), generateZonPathsFallback, and relativePath helper.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant generateBuildZig
  participant ManifestV2
  participant PackModules
  participant Template

  Caller->>generateBuildZig: generateBuildZig(allocator, cfg, opts)
  generateBuildZig->>ManifestV2: load/validate backend manifest
  ManifestV2-->>generateBuildZig: capabilities or UnsupportedCapability
  generateBuildZig->>PackModules: emitPackModules / emitPromotedScriptModules
  PackModules-->>generateBuildZig: wired modules
  generateBuildZig->>Template: emit platform header/link/footer sections
  Template-->>Caller: rendered build.zig text
Loading
sequenceDiagram
  participant Caller
  participant generateBuildZigZon
  participant deps_linker
  participant ManifestV2
  participant Template

  Caller->>generateBuildZigZon: generateBuildZigZon(allocator, cfg, target_dir, output_dir, project_dir, opts)
  generateBuildZigZon->>deps_linker: createDepsLinks(.labelle/deps)
  deps_linker-->>generateBuildZigZon: linked paths or fallback
  generateBuildZigZon->>ManifestV2: derive root deps / backend dep re-key when v2 enabled
  ManifestV2-->>generateBuildZigZon: dep entries
  generateBuildZigZon->>Template: render header/footer with fingerprint and deps
  Template-->>Caller: rendered build.zig.zon text
Loading

Possibly related PRs

  • labelle-toolkit/labelle-assembler#452: Updates tests/fixtures to supply the sokol backend manifest to generateBuildZig, directly touching the generator's external-backend codegen path this PR restructures.
  • labelle-toolkit/labelle-assembler#464: Adds manifest-v2 desktop codegen wiring (manifest_v2_splice, build hooks) overlapping with the new BuildZigOptions.backend_manifest_name v2 path introduced here.
  • labelle-toolkit/labelle-assembler#473: Updates backend_manifest_name auto-detection wiring in src/root.zig, directly consuming the options struct introduced in this refactor.

Poem

A monolith once stood so tall,
Now split in two, it serves us all —
build_zig hums, build_zig_zon sings,
Barrel file just re-exports things. 🐇
Hop along, generators new,
Manifests v2, packs wired true!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main refactor: splitting build_files.zig into focused sub-modules while preserving behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/split-build-files

Comment @coderabbitai help to get the list of available commands.

@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 refactors src/build_files.zig by splitting the large module into a thin barrel file that re-exports two new sub-modules: src/build_files/build_zig.zig for build.zig generation and src/build_files/build_zig_zon.zig for build.zig.zon generation. The review feedback identifies a potential memory leak in both sub-modules where converting the allocating writer's buffer to an ArrayList could leak memory if a subsequent toOwnedSlice call fails with an out-of-memory error. Adding an errdefer to deinit the ArrayList in both files is recommended to prevent this leak.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +859 to +860

var arr_list = alloc_writer.toArrayList();

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

When moving the allocating writer's buffer to an ArrayList via toArrayList(), the writer is reset to empty. To prevent memory leaks if the subsequent toOwnedSlice fails with OutOfMemory, an errdefer should be added to deinit the ArrayList.

    var arr_list = alloc_writer.toArrayList();
    errdefer arr_list.deinit(allocator);
    return arr_list.toOwnedSlice(allocator);
References
  1. In Zig, when moving an allocating writer's buffer to an ArrayList via toArrayList(), the writer is reset to empty. To prevent memory leaks if a subsequent toOwnedSlice fails with OutOfMemory, add an errdefer to deinit the ArrayList.

Comment on lines +214 to +215
var arr_list = alloc_writer.toArrayList();
return arr_list.toOwnedSlice(allocator);

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

When moving the allocating writer's buffer to an ArrayList via toArrayList(), the writer is reset to empty. To prevent memory leaks if the subsequent toOwnedSlice fails with OutOfMemory, an errdefer should be added to deinit the ArrayList.

    var arr_list = alloc_writer.toArrayList();
    errdefer arr_list.deinit(allocator);
    return arr_list.toOwnedSlice(allocator);
References
  1. In Zig, when moving an allocating writer's buffer to an ArrayList via toArrayList(), the writer is reset to empty. To prevent memory leaks if a subsequent toOwnedSlice fails with OutOfMemory, add an errdefer to deinit the ArrayList.

@apotema
apotema merged commit a162c97 into main Jul 5, 2026
4 checks passed
@apotema
apotema deleted the refactor/split-build-files branch July 5, 2026 15:12
apotema added a commit that referenced this pull request Jul 5, 2026
Rebuilt onto the six parallel split-refactors (#539-#549): identical
semantics, new homes — scanPack verb-copy in root/pack_scan.zig,
surface+depends_on emission in build_files/build_zig.zig, the .all
diagnostic in plugin_manifest/pack.zig. pack_root/pack_validate/
pack_refs/tests/docs carried verbatim (untouched by the splits).

Includes the review fixes from the first head: @"…" escaping on
exposed verb idents both sides, token-sequence .exposes = .all
detection (exposesAllShorthand), docs aligned with header-only +
targeted-diagnostic behavior.

Claude-Session: https://claude.ai/code/session_01P7YLw4hXFCCaY2LAUt4G1j
apotema added a commit that referenced this pull request Jul 5, 2026
…548)

Rebuilt onto the six parallel split-refactors (#539-#549): identical
semantics, new homes — scanPack verb-copy in root/pack_scan.zig,
surface+depends_on emission in build_files/build_zig.zig, the .all
diagnostic in plugin_manifest/pack.zig. pack_root/pack_validate/
pack_refs/tests/docs carried verbatim (untouched by the splits).

Includes the review fixes from the first head: @"…" escaping on
exposed verb idents both sides, token-sequence .exposes = .all
detection (exposesAllShorthand), docs aligned with header-only +
targeted-diagnostic behavior.

Claude-Session: https://claude.ai/code/session_01P7YLw4hXFCCaY2LAUt4G1j
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