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
21 changes: 21 additions & 0 deletions .dagger/modules/e2e/fixtures/dagger.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[modules.java-sdk]
source = "../../../.."
check.skip = ["*"]

[modules.java-sdk.as-sdk]
name = "java"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/generate/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/lookup/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/deps/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/skip/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/managed-toml/app"
119 changes: 89 additions & 30 deletions .dagger/modules/e2e/main.dang
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,31 @@ type E2e {
# A module using a different SDK; this SDK must never manage it.
let nonJavaModulePath: String! = fixtureRoot + "/lookup/not-java"

"""Fail the current check when a condition is false."""
"""
Fail the current check when a condition is false.
"""
let assert(condition: Boolean!, message: String!): Void {
if (condition == false) { raise message }
null
}

"""Return true when a list contains the exact string."""
"""
Return true when a list contains the exact string.
"""
let contains(values: [String!]!, want: String!): Boolean! {
values.filter { value => value == want }.length > 0
}

"""Assert that a changeset added a path."""
"""
Assert that a changeset added a path.
"""
let assertAdded(changes: Changeset!, path: String!): Void {
assert(contains(changes.addedPaths, path), "expected added path: " + path)
}

"""Assert that a string contains a substring."""
"""
Assert that a string contains a substring.
"""
let assertContains(value: String!, want: String!, message: String!): Void {
assert(value.contains(want), message)
}
Expand All @@ -40,16 +48,18 @@ type E2e {
New Java modules should target this repository's build/package-only runtime
rather than a builtin SDK name.
"""
pub targetRuntimeCheck: Void @check {
targetRuntimeCheck: Void @check {
assert(
javaSdk.targetRuntime == "github.com/dagger/java-sdk/runtime",
"targetRuntime should be the in-repo build/package-only runtime",
)
null
}

"""The generate skip marker filename should be stable."""
pub skipGenerateFilenameCheck: Void @check {
"""
The generate skip marker filename should be stable.
"""
skipGenerateFilenameCheck: Void @check {
assert(
javaSdk.skipGenerateFilename == ".dagger-java-sdk-skip-generate",
"skip marker filename changed",
Expand All @@ -64,7 +74,7 @@ type E2e {
the legacy dagger.json) are produced by the engine, not by initModule, and no
existing files are touched.
"""
pub initCheck(ws: Workspace!): Void @check {
initCheck(ws: Workspace!): Void @check {
let p = outputRoot + "/init-default"
let changes = javaSdk.initModule(ws, name: "init-default", path: p)

Expand Down Expand Up @@ -93,21 +103,43 @@ type E2e {
null
}

let testWS(ws: Workspace!): Workspace! {
ws.directory("/").withoutFile("dagger.toml").asWorkspace(cwd: ".dagger/modules/e2e/fixtures")
}

"""
From the workspace root the whole workspace is in scope, so modules() should
return every Java SDK module this workspace manages — whether it is configured
by the legacy dagger.json or the CLI 1.0 dagger-module.toml — and nothing that
isn't managed by this SDK (e.g. a sibling module using another SDK).
"""
pub modulesCheck(ws: Workspace!): Void @check {
let pathRecords = javaSdk.modules(ws).{{rootPath}}
modulesCheck(ws: Workspace!): Void @check {
let pathRecords = javaSdk.modules(testWS(ws)).{{rootPath}}

assert(pathRecords.filter { r => r.rootPath == lookupModulePath }.length > 0, "lookup Java module should be listed")
assert(pathRecords.filter { r => r.rootPath == skipModulePath }.length > 0, "skip-marked Java module should still be listed (skip only affects generate)")
assert(pathRecords.filter { r => r.rootPath == generateModulePath }.length > 0, "generate Java module should be listed")
assert(pathRecords.filter { r => r.rootPath == depsModulePath }.length > 0, "deps Java module should be listed")
assert(pathRecords.filter { r => r.rootPath == managedTomlModulePath }.length > 0, "a dagger-module.toml (CLI 1.0) managed module should be listed")
assert(pathRecords.filter { r => r.rootPath == nonJavaModulePath }.length == 0, "a module not managed by this SDK should be excluded from modules listing")
assert(
pathRecords.filter { r => r.rootPath == lookupModulePath }.length > 0,
"lookup Java module should be listed",
)
assert(
pathRecords.filter { r => r.rootPath == skipModulePath }.length > 0,
"skip-marked Java module should still be listed (skip only affects generate)",
)
assert(
pathRecords.filter { r => r.rootPath == generateModulePath }.length > 0,
"generate Java module should be listed",
)
assert(
pathRecords.filter { r => r.rootPath == depsModulePath }.length > 0,
"deps Java module should be listed",
)
assert(
pathRecords.filter { r => r.rootPath == managedTomlModulePath }.length > 0,
"a dagger-module.toml (CLI 1.0) managed module should be listed",
)
assert(
pathRecords.filter { r => r.rootPath == nonJavaModulePath }.length == 0,
"a module not managed by this SDK should be excluded from modules listing",
)

null
}
Expand All @@ -118,23 +150,37 @@ type E2e {
cone (walk-down) plus the nearest enclosing one (find-up), and excludes managed
modules that live outside it.
"""
pub modulesCwdCheck(ws: Workspace!): Void @check {
modulesCwdCheck(ws: Workspace!): Void @check {
# A stable snapshot of the workspace, re-anchorable at any cwd. Snapshot the
# whole workspace (not just config files) so the re-anchored workspace keeps
# its dagger.toml — modules() reads the managed-module list from it via
# ws.sdk — alongside every module config (dagger.json and dagger-module.toml,
# for discovery) and lookup/app/nested (a config-less subdirectory).
let root = ws.directory("/")
let root = testWS(ws).directory("/")

# Walk-down: from fixtures/generate only generate/app is in the cone; the
# sibling managed modules live outside it and must be excluded. Its
# cwd-relative path is "app" — a directory beneath the cwd.
let fromGenerate = javaSdk.modules(root.asWorkspace(cwd: fixtureRoot + "/generate"))
let fromGenerate = javaSdk.modules(
root.asWorkspace(cwd: fixtureRoot + "/generate"),
)
let fromGenerateRoots = fromGenerate.{{rootPath}}
assert(fromGenerateRoots.filter { r => r.rootPath == generateModulePath }.length > 0, "cwd=generate: the managed module in the cone should be discovered")
assert(fromGenerateRoots.filter { r => r.rootPath == lookupModulePath }.length == 0, "cwd=generate: lookup/app is outside the cone and must be excluded")
assert(fromGenerateRoots.filter { r => r.rootPath == depsModulePath }.length == 0, "cwd=generate: deps/app is outside the cone and must be excluded")
assert(fromGenerateRoots.filter { r => r.rootPath == skipModulePath }.length == 0, "cwd=generate: skip/app is outside the cone and must be excluded")
assert(
fromGenerateRoots.filter { r => r.rootPath == generateModulePath }.length > 0,
"cwd=generate: the managed module in the cone should be discovered",
)
assert(
fromGenerateRoots.filter { r => r.rootPath == lookupModulePath }.length == 0,
"cwd=generate: lookup/app is outside the cone and must be excluded",
)
assert(
fromGenerateRoots.filter { r => r.rootPath == depsModulePath }.length == 0,
"cwd=generate: deps/app is outside the cone and must be excluded",
)
assert(
fromGenerateRoots.filter { r => r.rootPath == skipModulePath }.length == 0,
"cwd=generate: skip/app is outside the cone and must be excluded",
)
assert(fromGenerateRoots.length == 1, "cwd=generate: exactly one managed module is in the cone")
assert(fromGenerate.{{path}}.filter { r => r.path == "app" }.length > 0, "cwd=generate: the discovered module's path should be cwd-relative (app)")

Expand All @@ -143,20 +189,33 @@ type E2e {
# cwd-relative path is ".." — an ancestor of the cwd.
let fromNested = javaSdk.modules(root.asWorkspace(cwd: lookupNestedPath))
let fromNestedRoots = fromNested.{{rootPath}}
assert(fromNestedRoots.filter { r => r.rootPath == lookupModulePath }.length > 0, "cwd=lookup/app/nested: find-up should discover the enclosing lookup/app")
assert(fromNestedRoots.filter { r => r.rootPath == generateModulePath }.length == 0, "cwd=lookup/app/nested: generate/app is outside the cone")
assert(
fromNestedRoots.filter { r => r.rootPath == lookupModulePath }.length > 0,
"cwd=lookup/app/nested: find-up should discover the enclosing lookup/app",
)
assert(
fromNestedRoots.filter { r => r.rootPath == generateModulePath }.length == 0,
"cwd=lookup/app/nested: generate/app is outside the cone",
)
assert(fromNestedRoots.length == 1, "cwd=lookup/app/nested: only the enclosing module should be discovered")
assert(fromNested.{{path}}.filter { r => r.path == ".." }.length > 0, "cwd=lookup/app/nested: the enclosing module's path should be cwd-relative (..)")

# Root cwd: the whole workspace is in scope, so every managed module — and
# only the managed ones — is discovered, whether marked by dagger.json or
# dagger-module.toml.
let fromRoot = javaSdk.modules(root.asWorkspace(cwd: "/")).{{rootPath}}
assert(fromRoot.filter { r => r.rootPath == generateModulePath }.length > 0, "cwd=/: generate/app should be listed")
# Using the fixture root where the test specific workspace is defined
let fromRoot = javaSdk.modules(root.asWorkspace(cwd: fixtureRoot)).{{rootPath}}
assert(
fromRoot.filter { r => r.rootPath == generateModulePath }.length > 0,
"cwd=/: generate/app should be listed",
)
assert(fromRoot.filter { r => r.rootPath == lookupModulePath }.length > 0, "cwd=/: lookup/app should be listed")
assert(fromRoot.filter { r => r.rootPath == depsModulePath }.length > 0, "cwd=/: deps/app should be listed")
assert(fromRoot.filter { r => r.rootPath == skipModulePath }.length > 0, "cwd=/: skip/app should be listed")
assert(fromRoot.filter { r => r.rootPath == managedTomlModulePath }.length > 0, "cwd=/: the dagger-module.toml managed module should be listed")
assert(
fromRoot.filter { r => r.rootPath == managedTomlModulePath }.length > 0,
"cwd=/: the dagger-module.toml managed module should be listed",
)
assert(fromRoot.length == 5, "cwd=/: exactly the five managed modules should be listed")

null
Expand All @@ -166,11 +225,11 @@ type E2e {
Generation from a subdirectory must resolve managed module root paths from
the workspace root, not relative to the caller's cwd.
"""
pub generateCwdCheck(ws: Workspace!): Void @check {
generateCwdCheck(ws: Workspace!): Void @check {
# Prepare a valid module in memory and remove the fixture-wide skip marker
# so this check can exercise generation without changing committed fixtures.
let initialized = javaSdk.initModule(ws, name: "generate-app", path: generateModulePath)
let root = ws
let root = testWS(ws)
.directory("/", exclude: [fixtureRoot + "/.dagger-java-sdk-skip-generate"])
.withDirectory(".", initialized.layer)
let fromParent = javaSdk.generateAll(
Expand Down
22 changes: 0 additions & 22 deletions dagger.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
[modules.e2e]
source = ".dagger/modules/e2e"

[modules.java-sdk]
source = "."
check.skip = ["*"]

[modules.packager]
source = ".dagger/modules/packager"

Expand All @@ -25,21 +21,3 @@ path = "."

[modules.sdk-sdk]
source = "github.com/dagger/sdk-sdk"

[modules.java-sdk.as-sdk]
name = "java"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/generate/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/lookup/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/deps/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/skip/app"

[[modules.java-sdk.as-sdk.modules]]
path = ".dagger/modules/e2e/fixtures/managed-toml/app"
24 changes: 15 additions & 9 deletions main.dang
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ type JavaSdk {
"""
Runtime source written into the dagger-module.toml of new Java modules.
"""
pub targetRuntime: String! { "github.com/dagger/java-sdk/runtime" }
targetRuntime: String! { "github.com/dagger/java-sdk/runtime" }

"""
Marker filename that skips generate when found at or above a Java SDK module root.
"""
pub skipGenerateFilename: String! = ".dagger-java-sdk-skip-generate"
skipGenerateFilename: String! = ".dagger-java-sdk-skip-generate"

"""
Config filenames that mark a Dagger module root: the CLI 1.0
Expand All @@ -33,19 +33,19 @@ type JavaSdk {
Opt-in (set `settings.vendorSdkJar = true` under `[modules.java-sdk]` in the
workspace dagger.toml) because it adds a committed binary artifact.
"""
pub vendorSdkJar: Boolean! = false
vendorSdkJar: Boolean! = false

"""
Initialize Java-owned files for a new Dagger module.
"""
pub initModule(
initModule(
ws: Workspace!,
name: String!,
path: String!,
"""
Template to use to init the module: default*, empty, legacy
"""
template: String! = "default"
template: String! = "default",
): Changeset! {
let rawPath = path.trimPrefix("./").trimPrefix("/")
let modPath = if (rawPath == "" or rawPath == ".") {
Expand Down Expand Up @@ -100,15 +100,21 @@ type JavaSdk {
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.
"""
pub modules(ws: Workspace!): [Mod!]! {
modules(ws: Workspace!): [Mod!]! {
let managed = ws.sdk(name: currentModule.name).modules.{{source}}
let cwd = normalizePath(ws.cwd)
polyfill.workspace(ws)
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, ws: ws, skipGenerateFilename: skipGenerateFilename, vendorSdkJar: vendorSdkJar) }
.map { path => Mod(
rootPath: path,
ws: ws,
skipGenerateFilename: skipGenerateFilename,
vendorSdkJar: vendorSdkJar,
) }
}

"""
Expand Down Expand Up @@ -146,7 +152,7 @@ type JavaSdk {
running from a subdirectory generates only the project you're in and the
projects beneath it.
"""
pub generateAll(ws: Workspace!): Changeset! @generate {
generateAll(ws: Workspace!): Changeset! @generate {
changeset.withChangesets(
modules(ws)
.filter { mod => mod.skipGenerate(ws) == false }
Expand Down
Loading