Repository navigation
Drop the polyfill for native workspace APIs - #11
Merged
Merged
Conversation
eunomie
force-pushed
the
polyfill-removal-refresh
branch
2 times, most recently
from
August 21, 2026 10:36
1e52f4e to
1083681
Compare
eunomie
marked this pull request as ready for review
August 24, 2026 10:12
The Dang SDK used dagger/polyfill for managed module discovery, module generation, and config edits. Those behaviors now live in Workspace and ModuleSource. Read managed modules from currentModule.asSDK(workspace).modules, thread the Workspace through generation, and compare the final workspace with the workspace the SDK received. Remove the polyfill and bump the engine requirement in the same change so existing staged edits are not returned twice. Registering this module as the "dang" SDK is what makes asSDK resolvable, and the entry has to be keyed by the module's own name, so the workspace module renames from dagger-dang-sdk to dang-sdk. engine.requireLatest now writes whatever release the engine resolves "latest" to: the alias is resolved engine-side while the config is written, so it can no longer land in dagger.json verbatim. The check and the README follow. Signed-off-by: Guillaume de Rouville <guillaume@dagger.io> Signed-off-by: Yves Brissaud <yves@dagger.io>
eunomie
force-pushed
the
polyfill-removal-refresh
branch
from
August 24, 2026 13:59
1083681 to
0e95749
Compare
This was referenced Aug 25, 2026
vito
approved these changes
Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Dang SDK no longer needs
dagger/polyfill.Supersedes #10, which cannot be updated in place — its head lives on a fork we
cannot push to. Same change, refreshed against the engine as it stands today
and reviewed; @grouville's commit is preserved as the author.
Requires dagger/dagger#13854 and
dagger/dagger#13855, both merged.
What changed
Managed modules come from
currentModule.asSDK(workspace: ws).modules, usingthe registrations in
dagger.toml. Generation keeps the workspace it receivedand returns only its own work —
Workspace.changes(from:)makes the baselineexplicit, so no workspace fork is needed anywhere.
ModuleSource.generatestages each module's local dependency closure itself, so the SDK no longer does
that by hand.
Config edits go through
ModuleSource.withEngineVersion/withDependenciesand
updatedConfigDirectory, the same pathdagger module engine requiretakes.Two knock-on changes worth calling out:
dagger-dang-sdktodang-sdk.asSDKresolves its entry by the module's own name (
resolveCurrentModuleSDKEntry),so the
dagger.tomlkey has to matchdagger.json's. Check names move withit:
dagger-dang-sdk:generateis nowdang-sdk:generate.engine.require-latestno longer writes the literal stringlatest. Theengine resolves that alias as it writes the config
(
moduleSourceWithEngineVersion), so a concrete release lands instead. Thecheck and the README follow.
Fixed while refreshing
deps update --name <source>silently returned an empty changeset. It matchedonly on module name, while the behaviour it replaced accepted a name, a
source, or a source at a version — and failed when the target was not there.
It now mirrors the engine's own matcher, re-pins to an explicitly requested
version, and distinguishes an unknown target from a local one.
modlookup read the declared runtime by regex-searchingdagger.jsonanddagger-module.toml. It now readsModuleSource.sdk, letting the engine parsewhichever format the module uses.
Mod.pathderived the cwd with the polyfill'sfindUp(".", ".")trick;Workspace.cwdis native now.Workspace.withNewDirectory, which replacesthe directory it writes over — where the polyfill's
fork.withDirectorylayered onto existing content. Three call sites were affected, and two of them
destroyed data:
engine require(andrequire-current/require-latest/deps update) staged the removal of the entire workspace,.gitincluded,because
updatedConfigDirectoryholds only the config file; andinitModuleinto a directory that already held files deleted them. All three now layer
onto what is already there.
isLocalRef,moduleConfigFilenames), a stalegenerate-allin the README, and a README discovery section that still described a
filesystem scan.
generatereports only what it changed — one edit comes back as one path, notas the whole generated context re-reported against an empty baseline
(the failure go-sdk#30 hit). This SDK cannot currently reach that: Dang has no
codegen output, so a module's generated context only ever modifies its own
config and never adds files, and the fault is in the added-path direction.
Verified across every module shape here — root,
dagger.json,dagger-module.toml, and one with local dependencies — including regeneratingafter denormalizing a config and after denormalizing a dependency's config.
A check now pins it, so the day Dang gains generated output this does not become
a silent regression.
New checks cover the
deps updatetargeting, module lookup against adagger.jsonowned by another runtime or declaring no runtime at all, andinitModuleover a non-empty directory.assertOnlyConfigChangednow alsoguards the engine-version edits — it asserted removals only on the dependency
paths before, which is why a whole-workspace deletion passed CI.
Note that
sdk-sdk'scontract:does-not-remove-existing-filesdoes not catchthis class of bug: it only initializes into a fresh path.
depsstill reads and writesdagger.jsondirectly forlist/add/remove.withDependenciesresolves each dependency, which loses the declared form thetests pin (a bare-string entry lists as its source,
addmust not load thetarget to learn its name).
withUpdateDependenciesis also unusable from modulecode: a workspace-derived
ModuleSource's local dependencies arrive asDIR_SOURCEwith an empty ref, so the engine ends up callingmoduleSource(refString: ""). Worth fixing upstream; not a blocker here.Test
Run bare — a filtered glob like
'e-2-e:*'silently skips two-level checknames such as
sdk-sdk:contract:seeds-files.The cross-repo run is against
sdk-sdkmain at3344489, which adds themonorepogroup — a workspace whosedagger.tomlsits in a subdirectory of thegit root, driven from that subdirectory
(dagger#13889). Those six checks
pin exactly the property this PR relies on: module paths cross the engine/SDK
boundary workspace-root-relative, and an SDK that rebases them onto the caller's
cwd splits the new module in two.
initModulehere writes at"/" + modPath,so it passes unchanged.