diff --git a/.dagger/modules/e2e/discovery.dang b/.dagger/modules/e2e/discovery.dang index c1aa098..9bed36e 100644 --- a/.dagger/modules/e2e/discovery.dang +++ b/.dagger/modules/e2e/discovery.dang @@ -37,11 +37,12 @@ type DiscoveryChecks { nothing that isn't managed by this SDK (e.g. a sibling module using another SDK). - Runs against the real workspace, so it also catches a dagger.toml - [[...as-sdk.modules]] entry that no longer matches the fixture tree. + Runs against the whole fixture workspace rather than a discovery snapshot, so + it also catches a fixtures dagger.toml [[...as-sdk.modules]] entry that no + longer matches the fixture tree. """ modulesCheck(ws: Workspace!): Void @check { - let roots = typescriptSdk.modules(ws).{{rootPath}}.map { mod => mod.rootPath } + let roots = typescriptSdk.modules(fixtures.workspace(ws)).{{rootPath}}.map { mod => mod.rootPath } fixtures.managedModules.each { want => Asserts.assert(Asserts.contains(roots, want), "managed module should be listed: " + want) @@ -84,9 +85,11 @@ type DiscoveryChecks { "cwd=lookup/app/nested (cwd-relative)", ) - # Root cwd: the whole workspace is in scope, so exactly the managed modules - # are discovered, whether marked by dagger.json or dagger-module.toml. - Asserts.paths(discovered(ws, "/"), fixtures.managedModules, "cwd=/") + # Fixture root: every fixture is in scope, so exactly the managed modules are + # discovered, whether marked by dagger.json or dagger-module.toml. This is + # the widest cwd they can be seen from — the dagger.toml declaring them lives + # here. + Asserts.paths(discovered(ws, fixtures.root), fixtures.managedModules, "cwd=fixtures") null } diff --git a/.dagger/modules/e2e/fixtures/dagger.toml b/.dagger/modules/e2e/fixtures/dagger.toml new file mode 100644 index 0000000..ee2fe2e --- /dev/null +++ b/.dagger/modules/e2e/fixtures/dagger.toml @@ -0,0 +1,43 @@ +# Test-only workspace: registers this SDK against the e2e fixtures, so the +# repository's own workspace never advertises test fixtures as managed modules. +# +# The workspace root is the git root and dagger.toml is only the nearest config +# found walking up from the cwd, so a config nested here selects configuration +# without moving the root: `source` resolves against this file, while as-sdk +# paths stay relative to the repository root. Checks reach it through +# `Fixtures.workspace`, which anchors a workspace cwd at this directory. + +[modules.typescript-sdk] +source = "../../../.." +check.skip = ["*"] + +[modules.typescript-sdk.as-sdk] +name = "typescript" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/generate/app" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/lookup/app" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/deps/app" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/skip/app" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/managed-toml/app" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/generate-deps/app" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/generate-deps/dep" + +[[modules.typescript-sdk.as-sdk.modules]] +path = ".dagger/modules/e2e/fixtures/parent-source/.dagger/modules/app" + +[[modules.typescript-sdk.as-sdk.clients]] +path = ".dagger/modules/e2e/fixtures/client/out" +module = ".dagger/modules/e2e/fixtures/client/app" diff --git a/.dagger/modules/e2e/generate.dang b/.dagger/modules/e2e/generate.dang index ea71c02..789219c 100644 --- a/.dagger/modules/e2e/generate.dang +++ b/.dagger/modules/e2e/generate.dang @@ -13,9 +13,10 @@ type GenerateChecks { module without touching unrelated paths. """ generateCheck(ws: Workspace!): Void @check { - let changes = typescriptSdk.mod(ws, path: fixtures.generateModule).generate(ws) + let tws = fixtures.workspace(ws) + let changes = typescriptSdk.mod(tws, path: "/" + fixtures.generateModule).generate(tws) - Asserts.generated(changes, fixtures.generateModule + "/sdk/index.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.generateModule) + "/sdk/index.ts") null } @@ -30,16 +31,17 @@ type GenerateChecks { failed with "dir module source does not contain a dagger config file". """ generateDependencyCheck(ws: Workspace!): Void @check { - let changes = typescriptSdk.mod(ws, path: fixtures.depAppModule).generate(ws) + let tws = fixtures.workspace(ws) + let changes = typescriptSdk.mod(tws, path: "/" + fixtures.depAppModule).generate(tws) - Asserts.generated(changes, fixtures.depAppModule + "/sdk/index.ts") - Asserts.generated(changes, fixtures.depAppModule + "/sdk/gendep.gen.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.depAppModule) + "/sdk/index.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.depAppModule) + "/sdk/gendep.gen.ts") # Generating the dependent stages its dependency's codegen only to feed its # own; that staging is ephemeral and must not leak into the changeset. Asserts.notAdded( changes, - fixtures.depLibModule + "/sdk/index.ts", + fixtures.changesetPath(fixtures.depLibModule) + "/sdk/index.ts", "generating a dependent should not also stage its dependency's own files", ) @@ -56,45 +58,45 @@ type GenerateChecks { than conflict over the files the closure staging touched. """ generateAllCheck(ws: Workspace!): Void @check { - let changes = typescriptSdk.generateAllModule(ws) + let changes = typescriptSdk.generateAllModule(fixtures.workspace(ws)) - Asserts.generated(changes, fixtures.generateModule + "/sdk/index.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.generateModule) + "/sdk/index.ts") # Both ends of the dependency edge, plus the dependency's bindings inside # the dependent. - Asserts.generated(changes, fixtures.depAppModule + "/sdk/index.ts") - Asserts.generated(changes, fixtures.depAppModule + "/sdk/gendep.gen.ts") - Asserts.generated(changes, fixtures.depLibModule + "/sdk/index.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.depAppModule) + "/sdk/index.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.depAppModule) + "/sdk/gendep.gen.ts") + Asserts.generated(changes, fixtures.changesetPath(fixtures.depLibModule) + "/sdk/index.ts") # Skip-marked and unmanaged modules stay untouched. Asserts.notAdded( changes, - fixtures.lookupModule + "/sdk/index.ts", + fixtures.changesetPath(fixtures.lookupModule) + "/sdk/index.ts", "generate-all generated a lookup fixture that should be skipped", ) Asserts.notAdded( changes, - fixtures.depsModule + "/sdk/index.ts", + fixtures.changesetPath(fixtures.depsModule) + "/sdk/index.ts", "generate-all generated dependency fixtures that should be skipped", ) Asserts.notAdded( changes, - fixtures.skipModule + "/sdk/index.ts", + fixtures.changesetPath(fixtures.skipModule) + "/sdk/index.ts", "generate-all generated a skipped module", ) Asserts.notAdded( changes, - fixtures.managedTomlModule + "/sdk/index.ts", + fixtures.changesetPath(fixtures.managedTomlModule) + "/sdk/index.ts", "generate-all generated a skipped dagger-module.toml module", ) Asserts.notAdded( changes, - fixtures.parentSourceCode + "/sdk/index.ts", + fixtures.changesetPath(fixtures.parentSourceCode) + "/sdk/index.ts", "generate-all generated a skipped relocated-source module", ) Asserts.notAdded( changes, - fixtures.nonTsModule + "/sdk/index.ts", + fixtures.changesetPath(fixtures.nonTsModule) + "/sdk/index.ts", "generate-all generated a non-TypeScript SDK module", ) @@ -133,10 +135,11 @@ type GenerateChecks { A skip marker above a module should make generate return an empty changeset. """ skipGenerateCheck(ws: Workspace!): Void @check { - let mod = typescriptSdk.mod(ws, path: fixtures.skipModule) - let changes = mod.generate(ws) + let tws = fixtures.workspace(ws) + let mod = typescriptSdk.mod(tws, path: "/" + fixtures.skipModule) + let changes = mod.generate(tws) - Asserts.assert(mod.skipGenerate(ws), "skip marker was not detected") + Asserts.assert(mod.skipGenerate(tws), "skip marker was not detected") Asserts.assert(changes.isEmpty, "generate returned changes for a skipped module") null diff --git a/.dagger/modules/e2e/util.dang b/.dagger/modules/e2e/util.dang index 523fbbe..71b574c 100644 --- a/.dagger/modules/e2e/util.dang +++ b/.dagger/modules/e2e/util.dang @@ -158,17 +158,40 @@ type Fixtures { let clientExisting: String! = root + "/client/existing" """ - A snapshot of `ws` holding just the files module discovery reads, re-anchored - at `cwd` so a check can stand anywhere in the tree. + `ws` re-anchored at the fixture root, where the test-only dagger.toml registers + the fixture modules and client as SDK-managed. - Keeps the workspace config (dagger.toml, whose [modules..as-sdk] list is - what discovery resolves the re-anchored workspace against) and every module - config, in both filenames. `extra` adds paths a check needs to exist for the - cwd itself to be a directory. + Everything the SDK resolves from workspace config — the managed module list, + the registered clients, the "typescript" SDK itself — has to be read from here + rather than from the repository's own dagger.toml, which deliberately knows + nothing about the fixtures. Dropping that config from the snapshot keeps it out + of reach, so a check cannot silently fall back to the real workspace. + """ + let workspace(ws: Workspace!): Workspace! { + ws.directory("/").withoutFile("dagger.toml").asWorkspace(cwd: root) + } + + """ + A path as it appears in a changeset produced in the fixture workspace. A + returned changeset is applied relative to the caller's cwd, which `workspace` + anchors at the fixture root, so generated paths drop that prefix. + """ + let changesetPath(path: String!): String! { + path.trimPrefix(root + "/") + } + + """ + A snapshot of the fixture workspace holding just the files module discovery + reads, re-anchored at `cwd` so a check can stand anywhere in the tree. + + Keeps the workspace config (the fixtures dagger.toml, whose + [modules..as-sdk] list is what discovery resolves the re-anchored + workspace against) and every module config, in both filenames. `extra` adds + paths a check needs to exist for the cwd itself to be a directory. """ let discoverySnapshot(ws: Workspace!, cwd: String!, extra: [String!]! = []): Workspace! { - ws - .directory("/", include: ["dagger.toml", "**/dagger.json", "**/dagger-module.toml"] + extra) + workspace(ws) + .directory("/", include: ["**/dagger.toml", "**/dagger.json", "**/dagger-module.toml"] + extra) .asWorkspace(cwd: cwd) } diff --git a/dagger.toml b/dagger.toml index 09cbb79..db8d7e7 100644 --- a/dagger.toml +++ b/dagger.toml @@ -6,43 +6,12 @@ # Marker filename that skips generate when found at or above a TypeScript SDK module root. # settings.skipGenerateFilename = "" +# This SDK is registered against the e2e fixture modules in +# .dagger/modules/e2e/fixtures/dagger.toml, not here, so this workspace stays +# free of test fixtures. + [modules.e2e] source = ".dagger/modules/e2e" -[modules.typescript-sdk] -source = "." -check.skip = ["*"] - [modules.sdk-sdk] source = "github.com/dagger/sdk-sdk" - -[modules.typescript-sdk.as-sdk] -name = "typescript" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/generate/app" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/lookup/app" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/deps/app" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/skip/app" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/managed-toml/app" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/generate-deps/app" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/generate-deps/dep" - -[[modules.typescript-sdk.as-sdk.modules]] -path = ".dagger/modules/e2e/fixtures/parent-source/.dagger/modules/app" - -[[modules.typescript-sdk.as-sdk.clients]] -path = ".dagger/modules/e2e/fixtures/client/out" -module = ".dagger/modules/e2e/fixtures/client/app"