Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dagger/modules/e2e/fixtures/generate/app/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/sdk/** linguist-generated
32 changes: 32 additions & 0 deletions .dagger/modules/e2e/main.dang
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ type E2e {
assert(contains(changes.addedPaths, path), "expected added path: " + path)
}

"""
Assert that a changeset reported none of `paths` as added.
"""
let assertNoneAdded(changes: Changeset!, paths: [String!]!, what: String!): Void {
let reAdded = paths.filter { path => contains(changes.addedPaths, path) }
assert(
reAdded.length == 0,
what + " re-added files that already exist: " + reAdded.join(", "),
)
}

"""
Assert that a string contains a substring.
"""
Expand Down Expand Up @@ -249,6 +260,27 @@ type E2e {
null
}

"""
Generation should report only what generation produced.

The module's own config is engine-owned, and the fixture commits the
`.gitattributes` that generation emits: both are already on disk, so a
changeset claiming to add either describes the workspace base rather than the
generated context. Every other generated file is genuinely new on this
fixture, which is why only an already-present one can catch that.
"""
pub generateSkipsExistingFilesCheck(ws: Workspace!): Void @check {
let existing = [
generateModulePath + "/dagger.json",
generateModulePath + "/.gitattributes",
]

assertNoneAdded(pythonSdk.mod(ws, path: generateModulePath).generate, existing, "generate")
assertNoneAdded(pythonSdk.generateAll(ws), existing, "generateAll")

null
}

"""
Generating an existing module should produce generated files rooted at that
module without touching unrelated paths.
Expand Down
3 changes: 2 additions & 1 deletion dagger.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[["version","2"]]
["","container.from",["docker.io/library/alpine:3.22","linux/amd64"],"sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce"]
["","container.from",["docker.io/library/golang:1.25-alpine","linux/amd64"],"sha256:1ae0735f00daffa3aaf1363a5184c0d2dc55c78e3db4ec70241cdac97bf84b59"]
["","git.ref",["https://github.com/dagger/sdk-sdk","HEAD"],{"ref":"refs/heads/main","sha":"00bb06748bcf22d724ed467f2298d31f1fb49be0"}]
["","container.from",["docker.io/library/golang:1.26-alpine","linux/amd64"],"sha256:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468"]
["","git.ref",["https://github.com/dagger/sdk-sdk","HEAD"],{"ref":"refs/heads/main","sha":"334448911a8292fba0d677e5f31926c79ad80ad3"}]
21 changes: 20 additions & 1 deletion mod.dang
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,26 @@ type Mod {
if (skipGenerate) {
ws.changes(ws)
} else {
ws.moduleSource("/" + rootPath).generate(ws).changes(ws)
# Stage the local dependency closure so this module's codegen sees
# up-to-date dependency bindings. It is only an input to resolving the
# module source, never the diff baseline, so the dependencies' codegen
# does not ride along.
let stagedWs = ws.withChanges(
ws.moduleSource("/" + rootPath).generateLocalDependencies(ws),
)
let generated = stagedWs
.moduleSource("/" + rootPath)
.generatedContextDirectory
.directory(rootPath)

# The generated context holds only generated files, and withNewDirectory
# replaces rather than layers, so merge it onto the module first.
# Workspace.changes then reports just the difference, rooted at the
# caller's cwd.
ws.withNewDirectory(
"/" + rootPath,
ws.directory("/" + rootPath).withDirectory(".", generated),
).changes(ws)
}
}
}
11 changes: 5 additions & 6 deletions python-sdk.dang
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,10 @@ type PythonSdk {
Modules with the generate skip marker are skipped.
"""
pub generateAll(ws: Workspace!): Changeset! @generate {
modules(ws)
.filter { mod => mod.skipGenerate == false }
.reduce(ws) { stagedWs, mod =>
stagedWs.moduleSource("/" + mod.rootPath).generate(stagedWs)
}
.changes(ws)
changeset.withChangesets(
modules(ws)
.filter { mod => mod.skipGenerate == false }
.map { mod => mod.generate },
)
}
}