diff --git a/.dagger/modules/e2e/main.dang b/.dagger/modules/e2e/main.dang index 1b95544..3182b64 100644 --- a/.dagger/modules/e2e/main.dang +++ b/.dagger/modules/e2e/main.dang @@ -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 } diff --git a/dagger-module.toml b/dagger-module.toml index 3d53cf8..2bf7646 100644 --- a/dagger-module.toml +++ b/dagger-module.toml @@ -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" diff --git a/dagger.json b/dagger.json index e38c38e..95b85ed 100644 --- a/dagger.json +++ b/dagger.json @@ -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" - } - ] + } } diff --git a/dagger.lock b/dagger.lock index f8cfb64..617173c 100644 --- a/dagger.lock +++ b/dagger.lock @@ -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"] \ No newline at end of file diff --git a/main.dang b/main.dang index eed9566..0874d79 100644 --- a/main.dang +++ b/main.dang @@ -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 } """ @@ -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, @@ -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 diff --git a/main.dang.tmpl b/main.dang.tmpl index 52aea22..d457be9 100644 --- a/main.dang.tmpl +++ b/main.dang.tmpl @@ -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 } """ @@ -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, @@ -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 diff --git a/mod.dang b/mod.dang index f6a2922..67e2246 100644 --- a/mod.dang +++ b/mod.dang @@ -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 @@ -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 } } diff --git a/prebuilt/m2/io/dagger/dagger-codegen-maven-plugin/0.21.4/dagger-codegen-maven-plugin-0.21.4.jar b/prebuilt/m2/io/dagger/dagger-codegen-maven-plugin/0.21.4/dagger-codegen-maven-plugin-0.21.4.jar index e4c09a0..8ba5f73 100644 Binary files a/prebuilt/m2/io/dagger/dagger-codegen-maven-plugin/0.21.4/dagger-codegen-maven-plugin-0.21.4.jar and b/prebuilt/m2/io/dagger/dagger-codegen-maven-plugin/0.21.4/dagger-codegen-maven-plugin-0.21.4.jar differ diff --git a/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/Helpers.java b/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/Helpers.java index 91bd827..ea3d7d7 100644 --- a/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/Helpers.java +++ b/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/Helpers.java @@ -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("*/", "*/"); } } diff --git a/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/InterfaceVisitor.java b/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/InterfaceVisitor.java index db1ef07..48827b7 100644 --- a/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/InterfaceVisitor.java +++ b/sdk/dagger-codegen-maven-plugin/src/main/java/io/dagger/codegen/introspection/InterfaceVisitor.java @@ -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 =