| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…nmarshalJSON) Generated code currently relies on package-level globals (marshalCtx, dag) for (un)marshaling Dagger objects, set once per dispatch via SetMarshalContext. This couples core types to module-specific global state and is one of the blockers for sharing core types via dagger.io/dagger instead of regenerating them under internal/dagger per module. Introduce an explicit seam, in all codegen modes: - IDClient: minimal client surface (QueryBuilder, GraphQLClient) needed to reconstruct objects from IDs; *Client already implements it in library, module, and standalone-client modes. - MarshalJSON(ctx, v): marshals v, scoping the ID-resolution context to this call (mutex-guarded swap of marshalCtx). - UnmarshalJSON(c, data, v) (module mode): unmarshals data, reconstructing objects through the given client (mutex-guarded swap of dag). Rewire the generated module dispatch to use them: parent state and input args now unmarshal via dagger.UnmarshalJSON(dag, ...), and the function result marshals via dagger.MarshalJSON(ctx, ...). SetMarshalContext remains (deprecated) so user code that json.Marshal's Dagger objects directly keeps working; it can be dropped once per-type UnmarshalJSON methods go away. Behavior is unchanged: the helpers swap the same globals the per-type methods read today. The point is that generated code now expresses its ctx/client dependencies explicitly, so the globals can later be removed (e.g. via json/v2 marshalers) without touching call sites again. Signed-off-by: Sandu Turcan <idlsoft@gmail.com>
Build on the IDClient seam by generating json/v2 marshaler/unmarshaler sets that carry their ctx/client in closures instead of package-level globals: data, err := json.Marshal(v, json.WithMarshalers(dagger.Marshalers(ctx))) err = json.Unmarshal(data, &v, json.WithUnmarshalers(dagger.Unmarshalers(dag))) Unlike the v1 MarshalJSON/UnmarshalJSON methods, these need no methods on the types at all, no globals, and are safe for multiple clients in one process. They also bring ID-based unmarshaling to the library and standalone-client modes for the first time (previously module-only). Two implementations, selected by the goexperiment.jsonv2 build tag: - jsonv2.gen.go (//go:build goexperiment.jsonv2): stdlib encoding/json/v2. Selected by default on Go 1.27+, opt-in on 1.25/1.26. - jsonv2_compat.gen.go (//go:build !goexperiment.jsonv2): github.com/go-json-experiment/json, which tracks the stdlib API. Both render from the same template body, so they only differ in the import. Once the SDK's minimum Go version reaches 1.27 the compat file and the go-json-experiment dependency can be deleted with no API change. Nothing generated calls these yet; migrating the module dispatch onto them (and then dropping the per-type UnmarshalJSON methods and the marshalCtx/dag globals) is a follow-up. Signed-off-by: Sandu Turcan <idlsoft@gmail.com>
Every generated object and interface client type gains
func (r *T) GraphQLQuery() *querybuilder.Selection
pairing with the existing WithGraphQLQuery setter. This is the read half of
the public query seam: dependency bindings generated outside the core
package (portable API mode) need to build selections on top of an object's
current query, which today is only possible by reading the unexported query
field from within the same package.
Purely additive; no behavior change.
Signed-off-by: Sandu Turcan <idlsoft@gmail.com>
Document why the json/v2 marshaler support is generated in two build-tag-selected variants, and the mechanical steps to collapse it onto stdlib encoding/json/v2 (and drop the go-json-experiment dependency) once the repository's minimum Go version reaches 1.27. The compat templates carry TODO(go1.27) pointers to the doc. Signed-off-by: Sandu Turcan <idlsoft@gmail.com>
| Back | FazBrowse Home | New Git URL |
What
Three commits that make the core types library-friendly: after this PR, anything with an engine connection can marshal, unmarshal, and build on Dagger objects through the published dagger.io/dagger API alone — no generated package-local state required. This is the foundation for the Go codegen v2 proposal (related: #11417, #11547): sharing core types via dagger.io/dagger instead of regenerating them under internal/dagger in every module. Behavior of existing modules is unchanged.
Commit 1 — explicit marshal/unmarshal seam
Generated code currently resolves objects to IDs (and back) through package-level globals — marshalCtx and dag — set once per dispatch via SetMarshalContext. This commit makes the dependencies explicit, in all codegen modes (library, module, standalone client):
The generated module dispatch now calls these with its ctx/dag explicitly: parent state and input args go through dagger.UnmarshalJSON(dag, ...), function results through dagger.MarshalJSON(ctx, ...). SetMarshalContext remains (deprecated) so user code that calls json.Marshal directly on Dagger objects keeps resolving IDs with the dispatch context.
Commit 2 — json/v2 Marshalers/Unmarshalers
Builds on IDClient to generate json/v2 marshaler/unmarshaler sets that carry their context/client in closures:
Unlike the v1 per-type methods, these need no methods on the types and no globals, are safe with multiple clients in one process, and bring ID-based unmarshaling to the library and standalone-client modes for the first time (previously module-only).
Two implementations rendered from one template body, selected by the goexperiment.jsonv2 build tag:
Once the SDK's minimum Go version reaches 1.27, the compat file and the go-json-experiment dependency can be deleted with no API change.
Nothing generated calls these yet; migrating dispatch onto them — and then deleting the per-type UnmarshalJSON methods and the marshalCtx/dag globals, which is what makes internal/dagger's core types byte-identical to the published SDK — is the follow-up PR.
Commit 3 — GraphQLQuery selection getter
Every generated object/interface type gains GraphQLQuery() *querybuilder.Selection, pairing with the existing WithGraphQLQuery setter. Together they form the public query seam: code outside the generated package (dependency bindings in portable mode, third-party integrations) can read an object's selection and build on it without network ID round-trips or access to the unexported query field. Purely additive.
Notes for reviewers
Test plan