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
8 changes: 4 additions & 4 deletions .dagger/modules/e2e/main.dang
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,14 @@ type E2e {
let fromParent = javaSdk.generateAll(
root.asWorkspace(cwd: fixtureRoot + "/generate"),
)
assertAdded(fromParent, generateModulePath + "/sdk/src/main/java/io/dagger/client/Dagger.java")
assertAdded(fromParent, generateModulePath + "/src/generated/java/io/dagger/gen/entrypoint/Entrypoint.java")
assertAdded(fromParent, "app/sdk/src/main/java/io/dagger/client/Dagger.java")
assertAdded(fromParent, "app/src/generated/java/io/dagger/gen/entrypoint/Entrypoint.java")

let fromModule = javaSdk.generateAll(
root.asWorkspace(cwd: generateModulePath),
)
assertAdded(fromModule, generateModulePath + "/sdk/src/main/java/io/dagger/client/Dagger.java")
assertAdded(fromModule, generateModulePath + "/src/generated/java/io/dagger/gen/entrypoint/Entrypoint.java")
assertAdded(fromModule, "sdk/src/main/java/io/dagger/client/Dagger.java")
assertAdded(fromModule, "src/generated/java/io/dagger/gen/entrypoint/Entrypoint.java")

null
}
Expand Down
7 changes: 1 addition & 6 deletions dagger-module.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
name = "java-sdk"
engineVersion = "v1.0.0-0"
engineVersion = "v1.0.0-beta.10"

[runtime]
source = "dang"

[[dependencies]]
name = "polyfill"
source = "github.com/dagger/polyfill@main"
pin = "e90bbfc4843258a877a3a95b8db1571e7981e65f"
11 changes: 2 additions & 9 deletions dagger.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
{
"name": "java-sdk",
"engineVersion": "latest",
"engineVersion": "v1.0.0-beta.10",
"sdk": {
"source": "dang"
},
"dependencies": [
{
"name": "polyfill",
"source": "github.com/dagger/polyfill@main",
"pin": "e90bbfc4843258a877a3a95b8db1571e7981e65f"
}
]
}
}
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"],"c724eec4270870aae489daa9f3cb8cbacfb44680","float"]
["","git.head",["https://github.com/dagger/sdk-sdk"],"8c164424b7a8a37b33a77367ef7547490d5b87b5","float"]
["","git.ref",["https://github.com/dagger/polyfill","main"],"ec3ea84a2351b4beb06ecece951f2e5ef66509ff","float"]
55 changes: 10 additions & 45 deletions main.dang
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,8 @@ type JavaSdk {
rawPath.trimSuffix("/")
}

let before = if (modPath == ".") {
ws.directory("/", include: ["**"])
} else {
ws.directory("/", include: [modPath + "/**"])
}

let selectedTemplate = if (template == "") { "default" } else { template }
before.withDirectory(modPath, renderedTemplate(name, selectedTemplate)).changes(before)
ws.fork.withNewDirectory("/" + modPath, renderedTemplate(name, selectedTemplate)).changes
}

"""
Expand All @@ -90,27 +84,17 @@ type JavaSdk {
Return every Java SDK module this workspace manages that is visible from the
client's current location.

Discovery is anchored at the client's cwd (never the workspace root): the
nearest enclosing module plus every module at or below the cwd, intersected
with the SDK's engine-owned list of managed modules
(currentModule.asSDK.modules). So running from a subdirectory acts on the
project you're in — and the projects beneath it — not the whole workspace.

Discovery is the polyfill's cwd-aware findConfigDirs (dagger/dagger#13688);
this maps its cwd-relative results to workspace-root-relative paths and keeps
the ones this SDK manages, whether they use dagger-module.toml or dagger.json.
The engine selects the modules directly from the workspace's registered SDK
modules: every module at or below the cwd, plus the nearest enclosing module
when the cwd itself is not managed. No filesystem discovery or intersection
is required.
"""
modules(ws: Workspace!): [Mod!]! {
let managed = ws.sdk(name: currentModule.name).modules.{{source}}
let cwd = normalizePath(ws.cwd)
polyfill
.workspace(ws)
.findConfigDirs(moduleConfigFilenames, exclude: ["**/target/**"])
.map { dir => moduleRelPath(cwd, dir) }
.uniq
.filter { path => managed.filter { m => normalizePath(m.source) == path }.length > 0 }
.map { path => Mod(
rootPath: path,
currentModule
.asSDK(workspace: ws)
.modulesInScope.{{path}}
.map { module => Mod(
rootPath: module.path,
ws: ws,
skipGenerateFilename: skipGenerateFilename,
vendorSdkJar: vendorSdkJar,
Expand All @@ -126,25 +110,6 @@ type JavaSdk {
if (normalized == "") { "." } else { normalized }
}

"""
Resolve a findConfigDirs result — a cwd-relative path, at or below the cwd
("." , "sub/dir") or a strict ancestor (".." , "../..") — against the cwd into a
workspace-root-relative path, the format both managed module sources and
Mod.rootPath use.
"""
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("/") }
}

"""
Generate every managed Java SDK module visible from the client's current
Expand Down
55 changes: 10 additions & 45 deletions main.dang.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,8 @@ type JavaSdk {
rawPath.trimSuffix("/")
}

let before = if (modPath == ".") {
ws.directory("/", include: ["**"])
} else {
ws.directory("/", include: [modPath + "/**"])
}

let selectedTemplate = if (template == "") { "default" } else { template }
before.withDirectory(modPath, renderedTemplate(name, selectedTemplate)).changes(before)
ws.fork.withNewDirectory("/" + modPath, renderedTemplate(name, selectedTemplate)).changes
}

"""
Expand All @@ -90,27 +84,17 @@ type JavaSdk {
Return every Java SDK module this workspace manages that is visible from the
client's current location.

Discovery is anchored at the client's cwd (never the workspace root): the
nearest enclosing module plus every module at or below the cwd, intersected
with the SDK's engine-owned list of managed modules
(currentModule.asSDK.modules). So running from a subdirectory acts on the
project you're in — and the projects beneath it — not the whole workspace.

Discovery is the polyfill's cwd-aware findConfigDirs (dagger/dagger#13688);
this maps its cwd-relative results to workspace-root-relative paths and keeps
the ones this SDK manages, whether they use dagger-module.toml or dagger.json.
The engine selects the modules directly from the workspace's registered SDK
modules: every module at or below the cwd, plus the nearest enclosing module
when the cwd itself is not managed. No filesystem discovery or intersection
is required.
"""
modules(ws: Workspace!): [Mod!]! {
let managed = ws.sdk(name: currentModule.name).modules.{{source}}
let cwd = normalizePath(ws.cwd)
polyfill
.workspace(ws)
.findConfigDirs(moduleConfigFilenames, exclude: ["**/target/**"])
.map { dir => moduleRelPath(cwd, dir) }
.uniq
.filter { path => managed.filter { m => normalizePath(m.source) == path }.length > 0 }
.map { path => Mod(
rootPath: path,
currentModule
.asSDK(workspace: ws)
.modulesInScope.{{path}}
.map { module => Mod(
rootPath: module.path,
ws: ws,
skipGenerateFilename: skipGenerateFilename,
vendorSdkJar: vendorSdkJar,
Expand All @@ -126,25 +110,6 @@ type JavaSdk {
if (normalized == "") { "." } else { normalized }
}

"""
Resolve a findConfigDirs result — a cwd-relative path, at or below the cwd
("." , "sub/dir") or a strict ancestor (".." , "../..") — against the cwd into a
workspace-root-relative path, the format both managed module sources and
Mod.rootPath use.
"""
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("/") }
}

"""
Generate every managed Java SDK module visible from the client's current
Expand Down
31 changes: 11 additions & 20 deletions mod.dang
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,10 @@ type Mod {
Stage the vendored SDK + generated entrypoint for one module.
"""
let generateModule(ws: Workspace!, modPathArg: String!): Changeset! {
# Native module-source resolution (Directory.asModuleSource, Query.moduleSource)
# fails from module code: SDK and user-defaults loading need the requester's host
# session. The polyfill resolves the source from a nested client that has one.
# Anchor rootPath at "/" so a non-root workspace cwd is not prefixed again.
let modSource = polyfill.workspace(ws).moduleSource("/" + modPathArg)
let name = modSource.core.moduleName
let introspectionJSON = modSource.core.introspectionSchemaJSON
let modSource = ws.moduleSource("/" + modPathArg)
let name = modSource.moduleName
let introspectionJSON = modSource.introspectionSchemaJSON
let vendored = vendoredSdk(introspectionJSON, name)

# the module as committed, with the whole committed sdk/ dropped (source and
Expand All @@ -217,24 +214,18 @@ type Mod {
.withoutDirectory("src/generated")
let entrypoint = generatedEntrypoint(baseDir, name)

let before = if (modPathArg == ".") {
ws.directory("/", include: ["**"])
} else {
ws.directory("/", include: [modPathArg + "/**"])
}
let staged = before
.withDirectory(joinPath(modPathArg, "sdk"), vendored)
.withDirectory(joinPath(modPathArg, "src/generated/java"), entrypoint)
# Stage through a workspace fork: the changeset comes back measured from
# the caller's cwd, the way the client applies it.
let staged = ws.fork
.withNewDirectory("/" + joinPath(modPathArg, "sdk"), vendored)
.withNewDirectory("/" + joinPath(modPathArg, "src/generated/java"), entrypoint)

if (vendorSdkJar) {
staged
.withDirectory(joinPath(modPathArg, "sdk/repo"), vendoredSdkJar(
introspectionJSON,
name,
))
.changes(before)
.withNewDirectory("/" + joinPath(modPathArg, "sdk/repo"), vendoredSdkJar(introspectionJSON, name))
.changes
} else {
staged.changes(before)
staged.changes
}
}

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,11 @@ static MethodSpec withSetter(InputObject var, TypeName type, TypeName returnType
return builder.build();
}

/** Fix using '$' char in javadoc */
/** Escape schema descriptions before embedding them in Javadoc. */
static String escapeJavadoc(String str) {
if (str == null) {
return "";
}
return str.replace("$", "$$").replace("&", "&");
return str.replace("$", "$$").replace("&", "&").replace("*/", "*/");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ TypeSpec generateType(Type type) {
.addJavadoc(Helpers.escapeJavadoc(type.getDescription()))
.addModifiers(Modifier.PUBLIC);

// GraphQL's Node interface is accepted as an input by fields such as
// LLM.withTools. Model its ID contract in Java so it can use the same
// argument serialization path as concrete Dagger objects.
if ("Node".equals(type.getName())) {
interfaceBuilder.addSuperinterface(
ParameterizedTypeName.get(ClassName.bestGuess("IDAble"), ClassName.bestGuess("ID")));
}

if (type.getFields() != null) {
for (Field field : type.getFields()) {
MethodSpec.Builder methodBuilder =
Expand Down