Skip to content
Draft
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
11 changes: 2 additions & 9 deletions dagger.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
{
"name": "go-sdk",
"engineVersion": "v1.0.0-0",
"engineVersion": "v1.0.0-beta.10",
"sdk": {
"source": "dang"
},
"dependencies": [
{
"name": "polyfill",
"source": "github.com/dagger/polyfill@main",
"pin": "ec3ea84a2351b4beb06ecece951f2e5ef66509ff"
}
]
}
}
1 change: 0 additions & 1 deletion dagger.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[["version","1"]]
["","git.head",["https://github.com/dagger/dang-sdk"],"207f22ca58a4167ea1d44ea929728d20aa3cc81b","float"]
["","git.head",["https://github.com/dagger/sdk-sdk"],"e1747f4b6221fa24da080701e027243e0cc5fa33","float"]
["","git.ref",["https://github.com/dagger/polyfill","main"],"ec3ea84a2351b4beb06ecece951f2e5ef66509ff","float"]
89 changes: 24 additions & 65 deletions go-sdk.dang
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,16 @@ type GoSdk {
let defaultTemplate: String! = "default"

"""
Return every Go SDK module this workspace manages that is visible from the
client's current location.

Discovery is anchored at the client's cwd, not the workspace root: the
nearest enclosing module plus every managed 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.
Return every managed Go SDK module in the client's cwd scope: every module at
or below the cwd, plus the nearest enclosing module when the cwd itself is not
a managed module. The engine selects this directly from the workspace's
registered SDK modules; no filesystem discovery is required.
"""
modules(ws: Workspace!): [Mod!]! {
let managed = currentModule.asSDK(workspace: ws).modules.{{path}}
let cwd = ws.cwd.trimPrefix("/").trimSuffix("/")
polyfill
.workspace(ws)
.findConfigDirs(moduleConfigFilenames, exclude: ["**/vendor/**"])
.map { dir => moduleRelPath(cwd, dir) }
.uniq
.filter { path => managed.filter { m => m.path == path }.length > 0 }
.map { path => Mod(rootPath: path, ws: ws, skipGenerateFilename: skipGenerateFilename) }
}

"""
Resolve a cwd-relative path — at or below the cwd ("." , "sub/dir") or a
strict ancestor (".." , "../..") — against the cwd into a
workspace-root-relative path.
"""
let moduleRelPath(cwd: String!, dir: String!): String! {
let base = if (cwd == "" or cwd == ".") { [] } else { cwd.split("/") }
let segs = dir.split("/").reduce(base) { acc, seg =>
if (seg == "..") {
acc.dropLast(1)
} else if (seg == "." or seg == "") {
acc
} else {
acc + [seg]
}
}
if (segs.length == 0) { "." } else { segs.join("/") }
currentModule
.asSDK(workspace: ws)
.modules.{{path}}
.map { module => Mod(rootPath: module.path, ws: ws, skipGenerateFilename: skipGenerateFilename) }
}

"""
Expand Down Expand Up @@ -116,12 +89,11 @@ type GoSdk {
let managedBase(ws: Workspace!, path: String!): String {
# asSDK raises when this module is not installed as an SDK in the active
# workspace, which is the normal case for a legacy dagger.json-only repo.
# The `.{{path}}` selection is what executes the query, so it must sit
# inside the guard.
# Selecting `path` executes the query, so it must sit inside the guard.
let managed = currentModule.asSDK(workspace: ws).modules.{{path}} rescue []

managed
.map { m => normalizePath(m.path) }
.map { module => normalizePath(module.path) }
.filter { base => pathContains(base, path) }
.reduce(null) { best, base =>
if (best == null) {
Expand Down Expand Up @@ -290,8 +262,6 @@ type GoSdk {
rawPath.trimSuffix("/")
}

let fork = polyfill.workspace(ws).fork

# An empty name means "the default", not the templates/ directory itself —
# which exists, so it would pass the check below and render every starter as
# a subdirectory of the new module.
Expand All @@ -300,7 +270,7 @@ type GoSdk {
if (currentModule.source.exists("templates/" + starter) == false) {
raise "unknown init template: " + starter
} else {
fork.withDirectory(modPath, renderedTemplate(name, starter)).changes
ws.withNewDirectory("/" + modPath, renderedTemplate(name, starter)).changes(ws)
}
}

Expand All @@ -316,7 +286,7 @@ type GoSdk {
module: String!,
dev: Boolean! = false,
): Changeset! {
polyfill.workspace(ws).fork.changes
ws.changes(ws)
}

"""
Expand Down Expand Up @@ -390,8 +360,7 @@ type GoSdk {
Generate a typed Go client for the module at `module`, written to `path`.
"""
pub generateClient(ws: Workspace!, module: String!, path: String!): Changeset! {
let pws = polyfill.workspace(ws)
let modSrc = pws.moduleSource("/" + module).core
let modSrc = ws.moduleSource("/" + module)
let generated = clientDirectory(
modSrc.clientSchemaIntrospectionJSON.contents,
modSrc.moduleOriginalName,
Expand All @@ -402,7 +371,7 @@ type GoSdk {
modSrc.pin,
existingClientDir(ws, path),
)
pws.fork.withDirectory(path, generated).changes
ws.withNewDirectory("/" + path, generated).changes(ws)
}

"""
Expand All @@ -415,15 +384,14 @@ type GoSdk {
skips clients that live elsewhere in the workspace.
"""
pub generateAllClient(ws: Workspace!): Changeset! @generate {
let pws = polyfill.workspace(ws)
let cwd = normalizePath(ws.cwd)
ws.sdk(name: currentModule.name).clients.{{name, source}}
.filter { client => pathContains(cwd, normalizePath(client.name)) }
.reduce(pws.fork) { fork, client =>
.reduce(ws) { stagedWs, client =>
let generated = if (isLocalModuleRef(client.source)) {
# A local module's cached source can miss live edits, so re-resolve
# it fresh from the workspace; git modules are pinned/immutable.
let src = pws.moduleSource("/" + client.source).core
let src = ws.moduleSource("/" + client.source)
clientDirectory(
src.clientSchemaIntrospectionJSON.contents,
src.moduleOriginalName,
Expand All @@ -448,9 +416,9 @@ type GoSdk {
existingClientDir(ws, client.name),
)
}
fork.withDirectory(client.name, generated)
stagedWs.withNewDirectory("/" + client.name, generated)
}
.changes
.changes(ws)
}

"""
Expand Down Expand Up @@ -478,20 +446,11 @@ type GoSdk {
Modules with the generate skip marker are skipped.
"""
generate(ws: Workspace!): Changeset! @generate {
let pws = polyfill.workspace(ws)
changeset.withChangesets(
modules(ws)
.filter { !_.skipGenerate(ws) }
.map { mod =>
# Stage this module's local dependency closure first (leaf-first, possibly
# across SDKs) so its codegen sees up-to-date dependency bindings. The dep
# codegen is ephemeral: taking the changeset against the staged workspace
# cancels it out, leaving only each module's own changes.
let stagedWs = ws.withChanges(
pws.moduleSource("/" + mod.rootPath).core.generateLocalDependencies(ws),
)
polyfill.workspace(stagedWs).moduleSource("/" + mod.rootPath).generate
},
)
modules(ws)
.filter { !_.skipGenerate(ws) }
.reduce(ws) { stagedWs, mod =>
stagedWs.moduleSource("/" + mod.rootPath).generate(stagedWs)
}
.changes(ws)
}
}
9 changes: 2 additions & 7 deletions mod.dang
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,9 @@ type Mod {
"""
generate(ws: Workspace!): Changeset! {
if (skipGenerate(ws)) {
polyfill.workspace(ws).fork.changes
ws.changes(ws)
} else {
# Stage the local dependency closure so this module's codegen sees
# up-to-date dependency bindings before generating it.
let stagedWs = ws.withChanges(
polyfill.workspace(ws).moduleSource("/" + rootPath).core.generateLocalDependencies(ws),
)
polyfill.workspace(stagedWs).moduleSource("/" + rootPath).generate
ws.moduleSource("/" + rootPath).generate(ws).changes(ws)
}
}
}