Skip to content

Add multi-file code generation support (--multiple-files) - #73

Merged
christianhelle merged 15 commits into
mainfrom
multiple-files
Jul 29, 2026
Merged

Add multi-file code generation support (--multiple-files)#73
christianhelle merged 15 commits into
mainfrom
multiple-files

Conversation

@christianhelle

@christianhelle christianhelle commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Adds the --multiple-files CLI flag to generate separate files for models (models.zig), runtime helpers ( untime.zig), and the API client (client.zig) into a specified output directory.

Key changes:

  • --multiple-files CLI flag in cli.zig
  • New RuntimeGenerator extracting runtime types (Owned, RawResponse, ApiResult, CancellationToken, SSE parsing) into a separate file
  • Refactored UnifiedApiGenerator with model_prefix and generateHeaderMulti for multi-file output
  • generateCodeMultiple in library API returning GeneratedFiles struct
  • generated/main.zig updated to import and verify multi-file client
  • New build step un-generate-v3-multi

Usage:

openapi2zig generate -i spec.json -o output_dir --multiple-files

This creates output_dir/models.zig, output_dir/runtime.zig, and output_dir/client.zig.

Summary by CodeRabbit

Summary

  • New Features
    • Added multi-file API code generation that outputs separate models, runtime (optional), and client files.
    • Introduced --multiple-files to generate results into an output directory layout.
    • Added library support for multi-part code generation via a new multi-file API.
  • Documentation
    • Updated command-line help/usage to describe --multiple-files and its effect on --output.
  • Tests
    • Extended build/test coverage to compile and run a generated multi-file fixture using the OpenAPI Petstore spec.

@christianhelle christianhelle added the enhancement New feature or request label Jul 29, 2026
@christianhelle christianhelle self-assigned this Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 48bb766a-dfa5-4140-9448-57b5a98fdb3d

📥 Commits

Reviewing files that changed from the base of the PR and between 61da0b7 and d5615ec.

⛔ Files ignored due to path filters (14)
  • generated/anthropic.zig is excluded by !**/generated/**
  • generated/compile_multi_generated.zig is excluded by !**/generated/**
  • generated/generated_v2.zig is excluded by !**/generated/**
  • generated/generated_v2_yaml.zig is excluded by !**/generated/**
  • generated/generated_v3.zig is excluded by !**/generated/**
  • generated/generated_v31.zig is excluded by !**/generated/**
  • generated/generated_v31_yaml.zig is excluded by !**/generated/**
  • generated/generated_v32.zig is excluded by !**/generated/**
  • generated/generated_v3_yaml.zig is excluded by !**/generated/**
  • generated/lmstudio.zig is excluded by !**/generated/**
  • generated/multi/client.zig is excluded by !**/generated/**
  • generated/multi/models.zig is excluded by !**/generated/**
  • generated/multi/runtime.zig is excluded by !**/generated/**
  • generated/openai.zig is excluded by !**/generated/**
📒 Files selected for processing (5)
  • build.zig
  • src/cli.zig
  • src/generators/unified/api_generator.zig
  • src/generators/unified/runtime_generator.zig
  • src/lib.zig
🚧 Files skipped from review as they are similar to previous changes (4)
  • build.zig
  • src/lib.zig
  • src/generators/unified/runtime_generator.zig
  • src/generators/unified/api_generator.zig

📝 Walkthrough

Walkthrough

The CLI adds --multiple-files. Generation now produces separate models.zig, runtime.zig, and client.zig files, with dedicated runtime and client generation support. The build adds v3 petstore generation and compilation coverage.

Changes

Multi-file generation

Layer / File(s) Summary
Multi-file CLI contract
src/cli.zig
Parses, documents, and tests the --multiple-files option.
Generated runtime and client support
src/generators/unified/runtime_generator.zig, src/generators/unified/api_generator.zig
Adds generated runtime JSON/SSE utilities, client-only output, runtime reexports, model prefixes, and split header handling.
Split generation API
src/lib.zig
Exports RuntimeGenerator, adds GeneratedFiles, and provides generateCodeMultiple for models, runtime, and client outputs.
File output and build integration
src/generator.zig, build.zig
Writes separate generated files and adds v3 petstore generation and compilation steps.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Generator
  participant RuntimeGenerator
  participant UnifiedApiGenerator
  participant OutputDirectory
  CLI->>Generator: select --multiple-files
  Generator->>RuntimeGenerator: generate runtime source
  Generator->>UnifiedApiGenerator: generate client-only source
  Generator->>OutputDirectory: write models.zig, runtime.zig, client.zig
Loading

Possibly related PRs

🚥 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 matches the main change: adding multi-file code generation via the --multiple-files flag.
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 multiple-files

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
src/cli.zig (1)

193-206: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a parser test for --multiple-files.

Existing tests cover --models-only/defaults/upgrade but not the new flag.

test "parse generate supports multiple-files flag" {
    const argv = [_][:0]const u8{
        "openapi2zig", "generate", "-i", "openapi.json", "--multiple-files",
    };
    const parsed = try parse(&argv);
    try std.testing.expect(parsed.args.multiple_files);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli.zig` around lines 193 - 206, Add a parser test alongside the existing
generate argument tests that invokes parse with the --multiple-files flag and
asserts parsed.args.multiple_files is true, using the same input-path setup and
test style as the models-only case.
build.zig (1)

241-249: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No compile verification for multi-file generated output.

generated_tests only compiles generated/compile_generated.zig (single-file mode). Consider adding a similar test target that imports generated/multi/models.zig, runtime.zig, and client.zig so cross-file breakage (like the pub visibility issue flagged in runtime_generator.zig) is caught in CI.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@build.zig` around lines 241 - 249, Add a second generated-output test target
alongside generated_tests in the build configuration, using a root module that
imports generated/multi/models.zig, runtime.zig, and client.zig so multi-file
generated code is compiled and cross-file visibility errors are caught. Register
its run artifact with test_step, while preserving the existing single-file
generated_tests coverage.
src/generators/unified/runtime_generator.zig (1)

33-97: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Runtime template strings duplicated with api_generator.zig.

generateRuntimeTypes, generateHttpObserverType, generateSseFunctions, and generateSseBufferConstants here are near-verbatim copies of generateRuntimePreamble/generateHttpObserverType/generateSsePreamble/generateSseBufferConstants in api_generator.zig (used for single-file mode). Any future fix/change to the runtime code (e.g. the SSE parser) must be applied in both places, and they've already drifted slightly (e.g. leading blank-line differences). Consider extracting the shared template text into a common helper both generators call.

Also applies to: 99-109, 111-230

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/generators/unified/runtime_generator.zig` around lines 33 - 97, Remove
the duplicated runtime template emission from generateRuntimeTypes,
generateHttpObserverType, generateSseFunctions, and generateSseBufferConstants,
and extract the shared template text into a common helper reusable by both
RuntimeGenerator and api_generator’s corresponding generation methods. Preserve
the generated runtime contents and eliminate formatting drift between
single-file and runtime generation paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/generators/unified/runtime_generator.zig`:
- Around line 129-215: Make checkCancellation and TypedSseCallback public in
runtime_generator.zig by changing both declarations to pub fn, allowing
generated consumers to access them across file boundaries. In api_generator.zig
lines 253-269, make no direct changes; its existing reexports should resolve
once the runtime symbols are public.
- Around line 129-133: In the generated runtime declarations, change both
checkCancellation and TypedSseCallback from non-public functions to pub
functions so client.zig can reexport and use them in --multiple-files mode;
leave their signatures and behavior unchanged.

In `@src/lib.zig`:
- Around line 251-288: Replace the success-inactive errdefer cleanup for the
intermediate buffers in generateCodeMultiple—models_code, header, runtime_code,
and api_code—with defer cleanup. Keep the concatenated result buffers owned by
the returned GeneratedFiles value, while ensuring each source buffer is freed
after successful generation and on errors.
- Around line 241-246: Update the GeneratedFiles struct to add a
deinit(allocator) method that frees each owned buffer: models, runtime when
present, and client when present. Use the provided allocator and preserve the
optional fields’ null-safe cleanup behavior.

---

Nitpick comments:
In `@build.zig`:
- Around line 241-249: Add a second generated-output test target alongside
generated_tests in the build configuration, using a root module that imports
generated/multi/models.zig, runtime.zig, and client.zig so multi-file generated
code is compiled and cross-file visibility errors are caught. Register its run
artifact with test_step, while preserving the existing single-file
generated_tests coverage.

In `@src/cli.zig`:
- Around line 193-206: Add a parser test alongside the existing generate
argument tests that invokes parse with the --multiple-files flag and asserts
parsed.args.multiple_files is true, using the same input-path setup and test
style as the models-only case.

In `@src/generators/unified/runtime_generator.zig`:
- Around line 33-97: Remove the duplicated runtime template emission from
generateRuntimeTypes, generateHttpObserverType, generateSseFunctions, and
generateSseBufferConstants, and extract the shared template text into a common
helper reusable by both RuntimeGenerator and api_generator’s corresponding
generation methods. Preserve the generated runtime contents and eliminate
formatting drift between single-file and runtime generation paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0834187f-0ace-4570-8eb9-91620ff648e4

📥 Commits

Reviewing files that changed from the base of the PR and between 3c1abf8 and 61da0b7.

⛔ Files ignored due to path filters (14)
  • generated/anthropic.zig is excluded by !**/generated/**
  • generated/generated_v2.zig is excluded by !**/generated/**
  • generated/generated_v2_yaml.zig is excluded by !**/generated/**
  • generated/generated_v3.zig is excluded by !**/generated/**
  • generated/generated_v31.zig is excluded by !**/generated/**
  • generated/generated_v31_yaml.zig is excluded by !**/generated/**
  • generated/generated_v32.zig is excluded by !**/generated/**
  • generated/generated_v3_yaml.zig is excluded by !**/generated/**
  • generated/lmstudio.zig is excluded by !**/generated/**
  • generated/main.zig is excluded by !**/generated/**
  • generated/multi/client.zig is excluded by !**/generated/**
  • generated/multi/models.zig is excluded by !**/generated/**
  • generated/multi/runtime.zig is excluded by !**/generated/**
  • generated/openai.zig is excluded by !**/generated/**
📒 Files selected for processing (6)
  • build.zig
  • src/cli.zig
  • src/generator.zig
  • src/generators/unified/api_generator.zig
  • src/generators/unified/runtime_generator.zig
  • src/lib.zig

Comment thread src/generators/unified/runtime_generator.zig Outdated
Comment thread src/generators/unified/runtime_generator.zig Outdated
Comment thread src/lib.zig
Comment thread src/lib.zig
@christianhelle christianhelle changed the title feat: add multi-file code generation support (--multiple-files) Add multi-file code generation support (--multiple-files) Jul 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a --multiple-files generation mode to the Zig OpenAPI client generator, splitting output into models.zig, runtime.zig, and client.zig, and wiring that through both the CLI and library API.

Changes:

  • Added --multiple-files CLI flag and multi-file writing flow in the generator.
  • Introduced RuntimeGenerator and refactored UnifiedApiGenerator to support multi-file clients via model_prefix and generateClientOnly().
  • Updated build/test artifacts to generate and compile-check the multi-file v3 output.

Reviewed changes

Copilot reviewed 6 out of 21 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/lib.zig Exposes RuntimeGenerator and adds generateCodeMultiple() returning a GeneratedFiles struct.
src/generators/unified/runtime_generator.zig New generator that emits shared runtime helpers (Owned/ApiResult/etc) and SSE parsing helpers.
src/generators/unified/api_generator.zig Adds multi-file header mode, model prefixing, and generateClientOnly() for client-only output.
src/generator.zig Implements CLI multi-file generation path and writes models.zig, runtime.zig, client.zig to an output directory.
src/cli.zig Adds --multiple-files parsing, usage text, and a parse test.
build.zig Adds run-generate-v3-multi step and a compile-only test for multi-file generated output.
generated/main.zig Imports and exercises the multi-file client in the generated sample harness.
generated/compile_multi_generated.zig New test ensuring multi-file generated client compiles via refAllDecls.
generated/multi/models.zig Checked-in example multi-file models output for v3 petstore.
generated/multi/runtime.zig Checked-in example multi-file runtime output.
generated/multi/client.zig Checked-in example multi-file client output.
generated/openai.zig Regenerated output reflecting updated generator structure/header formatting.
generated/lmstudio.zig Regenerated output reflecting updated generator structure/header formatting.
generated/anthropic.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v32.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v31.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v31_yaml.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v3.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v3_yaml.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v2.zig Regenerated output reflecting updated generator structure/header formatting.
generated/generated_v2_yaml.zig Regenerated output reflecting updated generator structure/header formatting.

Comment thread src/generators/unified/api_generator.zig
Comment thread src/cli.zig Outdated
Comment thread src/generators/unified/api_generator.zig Outdated
@christianhelle
christianhelle merged commit 5aa1150 into main Jul 29, 2026
17 checks passed
@christianhelle
christianhelle deleted the multiple-files branch July 29, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants