Skip to content

feat/module gen dang - #26

Draft
TomChv wants to merge 2 commits into
feat/module-config-writersfrom
feat/module-gen-dang
Draft

feat/module gen dang#26
TomChv wants to merge 2 commits into
feat/module-config-writersfrom
feat/module-gen-dang

Conversation

@TomChv

@TomChv TomChv commented Aug 11, 2026

Copy link
Copy Markdown
Member

Stack created with GitHub Stacks CLIGive Feedback 💬

TomChv added 2 commits August 11, 2026 15:08
Generating a fixture both ways and diffing turned up three places where our
generator — ported with the client codegen, from an older upstream commit than
the engine we pin — produces different output from the engine's:

- Enum members were named with strcase.ToCamel, which mangles consecutive
  capitals: EStarGZ became EstarGz where the engine emits EStarGz. Module code
  written against the engine's bindings would not compile against ours.
  Upstream had already fixed this by routing formatEnum through the same
  PascalCase rule as the rest of the generator; the corrected helper was
  sitting unused in our copy.
- `arguments` was missing from the JS keyword list, so a field of that name
  came out unescaped instead of as `arguments_`.
- The entrypoint emitted no source maps. The scan reports a location for every
  declaration and our typedef structs dropped all but the object's on the
  floor; the renderer had no sourceMapExpr at all. Taken from the beta.9 tag
  along with the register template that calls it — our copies had no local
  changes to preserve, unlike the binding templates, which carry the client
  work developed here.

Regenerating the library bindings and rebuilding the bundle propagates the enum
fix into core.d.ts, which had inherited the old casing.

With this, every generated file matches the engine's byte-for-byte for the
same fixture, except core.js — ours is built from the vendored lockfile and is
1.1MB smaller than the engine's, which builds without one.

Signed-off-by: Tom Chauveau <tom@dagger.io>
Assemble a module's generated tree here rather than routing through the
engine's built-in TypeScript runtime: bindings from the module-facing schema,
the sdk/ directory the runtime mounts as @dagger.io/dagger, the dispatch
entrypoint, and the config files.

The schema is ModuleSource.introspectionSchemaJSON — the same builder call the
engine makes before handing the file to Codegen, so this is the same input, not
an approximation.

The scan runs with the compiler installed beside the introspector rather than
in the module tree: a bare import resolves from the importing file's directory,
so the module's own node_modules is not somewhere the scanner would look.

Exposed as generateModuleLocal and left unwired: Mod.generate still delegates
to the engine while the two are compared. Verified for the generate/app fixture
by generating it both ways — every file matches byte-for-byte except core.js
(§ the lockfile difference) — and by generating the generate-deps fixtures and
calling a function on the result, which exercises the whole tree, dependency
bindings included, through the engine runtime.

ModConfig.runtime becomes public: codegen needs to know which config files a
module wants, and the detection already lived there.

Signed-off-by: Tom Chauveau <tom@dagger.io>
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