Skip to content

feat: make module discovery cwd-aware#8

Merged
TomChv merged 1 commit into
mainfrom
feat/make-module-discovery-cwd-aware
Jul 22, 2026
Merged

feat: make module discovery cwd-aware#8
TomChv merged 1 commit into
mainfrom
feat/make-module-discovery-cwd-aware

Conversation

@TomChv

@TomChv TomChv commented Jul 22, 2026

Copy link
Copy Markdown
Member

What

Makes Dang SDK module discovery follow the cwd-aware convention from
dagger/dagger#13688, and teaches lookup + discovery the CLI 1.0
dagger-module.toml config in addition to the legacy dagger.json.

Companion to the same change in the other official SDKs:

Behavior after this change

Discovery is anchored at the client's cwd, not the workspace root. modules()
and generateAll() now return the nearest enclosing module plus every Dang
module at or below the cwd — running from a subdirectory acts on the project
you're in and the projects beneath it, not the whole workspace.

Caller location Modules seen by modules / generateAll
Workspace root Every Dang module at or below the root
A module root That module and Dang descendants
Inside a module The nearest enclosing Dang module plus Dang descendants
A sibling directory Not included

Both dagger-module.toml ([runtime] source = "dang") and legacy dagger.json
(sdk.source = "dang") participate in discovery and in mod(...) find-up. In a
partially migrated tree the nearest config wins.

How discovery differs from go/python/typescript

All of these SDKs, including this one, validate a single mod(...) lookup by
content search — does the found config declare the SDK's runtime. The
difference is only in the bulk modules() discovery path:

  • go/typescript intersect findConfigDirs with currentModule.asSDK.modules;
    python with ws.sdk(...).modules — i.e. the workspace's managed-SDK list.
  • The Dang SDK instead filters findConfigDirs by content search (does the
    config declare the built-in dang runtime). dang is an engine runtime, not
    an installed SDK, so there is no managed-SDK list to intersect against — a
    module is Dang because of what its config says, matching this module's
    existing discovery model.

Internal model

Mod.rootPath is the workspace-root-relative identity used for generation and
configuration. The public Mod.path is now relative to the caller cwd (. for
the module itself, sub/mod beneath, .. for an enclosing one), so listings
read the way a shell user would.

Scope / notes

  • The e2e module is bumped to engineVersion: v1.0.0-0 (required for
    asWorkspace(cwd:) in the discovery tests).
  • The root dang-sdk module stays on v0.20.8: the cwd is resolved through the
    polyfill's findUp(".", ".") helper instead of Workspace.cwd, so no new
    engine floor is required.
  • Pins dagger/polyfill@main (provides findConfigDirs).

Tests

New/updated e2e checks:

  • module-lookup-toml-check — find-up + exact lookup through a dagger-module.toml.
  • module-lookup-non-dang-toml-check — a toml module owned by another runtime is rejected.
  • mixed-config-lookup-check — a nearer dagger-module.toml beats an ancestor dagger.json.
  • modules-check — root discovery lists both config formats, excludes other-runtime modules.
  • modules-cwd-check — re-anchors the workspace via asWorkspace(cwd:) and verifies
    walk-down scoping, find-up (..), and toml-cone discovery. The snapshot is scoped to the
    fixture tree so the repo's own Dang modules (this e2e module, the root module) don't leak
    into find-up under content-search discovery.

Verified with dagger --x-release=v1.0.0-beta.7 -m .dagger/modules/e2e check: 15/15 pass.

Discovery is now anchored at the client's cwd instead of the workspace
root: modules() and generateAll() see the nearest enclosing module plus
every Dang module at or below the cwd, so running from a subdirectory
acts on the project you're in and the projects beneath it — not the whole
workspace.

Lookup and discovery both recognize the CLI 1.0 dagger-module.toml in
addition to the legacy dagger.json; in a partially migrated tree the
nearest config wins. Mod.rootPath is the module's stable
workspace-root-relative identity used for generation and configuration,
while the public Mod.path is now relative to the caller cwd.

The e2e module is bumped to v1.0.0-0 for asWorkspace(cwd:); the root
dang-sdk module stays on v0.20.8 by resolving the cwd through the
polyfill's findUp helper rather than Workspace.cwd.

Part of dagger/dagger#13688

Signed-off-by: Tom Chauveau <tom@dagger.io>
@TomChv
TomChv merged commit 5664ccb into main Jul 22, 2026
2 checks passed
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.

2 participants