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
31 changes: 30 additions & 1 deletion .dagger/modules/e2e/main.dang
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type E2e {
let configuredDenoModulePath: String! = fixtureRoot + "/config/configured-deno"
let configBareModulePath: String! = fixtureRoot + "/config/bare"

# A client binds to the generate/app module and is generated into its own dir.
let clientOutputPath: String! = fixtureRoot + "/client/out"

"""
Fail the current check when a condition is false.
"""
Expand Down Expand Up @@ -203,7 +206,7 @@ type E2e {
Generating all modules should discover TypeScript SDK modules and ignore skipped ones.
"""
pub generateAllCheck(ws: Workspace!): Void @check {
let changes = typescriptSdk.generateAll(ws)
let changes = typescriptSdk.generateAllModule(ws)

assertAdded(changes, generateModulePath + "/sdk/index.ts")
assert(contains(changes.addedPaths, lookupModulePath + "/src/index.ts") == false, "generateAll generated a lookup fixture that should be skipped")
Expand All @@ -214,6 +217,32 @@ type E2e {
null
}

"""
Generating a client for a module should produce a scoped-package client
(client.gen.ts plus package.json) rooted at the client output path.
"""
pub generateClientCheck(ws: Workspace!): Void @check {
let changes = typescriptSdk.generateClient(ws, module: generateModulePath, path: clientOutputPath)

assertAdded(changes, clientOutputPath + "/client.gen.ts")
assertAdded(changes, clientOutputPath + "/package.json")

null
}

"""
Regenerating all workspace-registered clients should generate each one at its
configured path.
"""
pub generateAllClientCheck(ws: Workspace!): Void @check {
let changes = typescriptSdk.generateAllClient(ws)

assertAdded(changes, clientOutputPath + "/client.gen.ts")
assertAdded(changes, clientOutputPath + "/package.json")

null
}

"""
A skip marker above a module should make generate return an empty changeset.
"""
Expand Down
4 changes: 4 additions & 0 deletions dagger.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ path = ".dagger/modules/e2e/fixtures/deps/app"

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

[[modules.typescript-sdk.as-sdk.clients]]
path = ".dagger/modules/e2e/fixtures/client/out"
module = ".dagger/modules/e2e/fixtures/generate/app"
596 changes: 596 additions & 0 deletions design/client-gen.md

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions helpers/codegen/generator/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package generator

type Config struct {
// Lang is the language to generate the module for.
Lang SDKLang

// OutputDir is the path to put the generated code.
// Usually this is the path to the module source directory.
// This allows generating extra file aside the client bindings
// like go.mod, go.sum etc...
OutputDir string

// IntrospectionJSON is an optional pre-computed introspection json string.
IntrospectionJSON string

// TypeDefsPath is the path of the file to write the typedefs module id.
TypeDefsPath string

// Generate the client in bundle mode.
Bundle bool

// ModuleConfig is the specific config to generate module or typedefs.
ModuleConfig *ModuleGeneratorConfig

// ClientConfig is the specific config to generate standalone client.
ClientConfig *ClientGeneratorConfig

// EntrypointConfig is the specific config to generate the static dispatch
// entrypoint file (currently TypeScript only).
EntrypointConfig *EntrypointGeneratorConfig
}

// Specific configuration for module generation.
type ModuleGeneratorConfig struct {
// Name of the module to generate code for.
ModuleName string

// ModuleSourcePath is the subpath in OutputDir where the module source subpath is located.
ModuleSourcePath string

// ModuleParentPath is the path from the module source subpath to the context directory
ModuleParentPath string

// Whether we are initializing a new module.
// Currently, this is only used in go codegen to enforce backwards-compatible behavior
// where a pre-existing go.mod file is checked during dagger init for whether its module
// name is the expected value.
IsInit bool

// If set, use `@dagger.io/dagger` with the given version and use it in the generated client.
LibVersion string
}

type ModuleSourceDependency struct {
Kind string
Name string `json:"moduleOriginalName"`
Pin string
Source string `json:"asString"`
}

// Specific configuration for entrypoint generation.
type EntrypointGeneratorConfig struct {
// TypedefJSONPath is the path to the JSON-serialized DaggerModule typedef
// produced by the SDK introspector (e.g. ts-introspector with
// EMIT_TYPEDEF_JSON_FILE).
TypedefJSONPath string

// OutputFile is the filename (relative to OutputDir) where the generated
// entrypoint source is written. Defaults to "__dagger.entrypoint.ts" for
// the TypeScript SDK.
OutputFile string

// ModuleRoot is the absolute path of the user's module root, used to
// resolve relative source-import paths for each registered @object class.
ModuleRoot string

// SDKImportPath is the bare specifier the entrypoint uses to import
// runtime helpers (defaults to "@dagger.io/dagger" for TypeScript).
SDKImportPath string

// SourceDir is the user's source directory name relative to ModuleRoot
// (defaults to "src" for TypeScript).
SourceDir string
}

// Specific configuration for client generation.
type ClientGeneratorConfig struct {
// The name of the module to generate for.
ModuleName string

// The list of all dependencies used by the module.
// This is used by the client generator to automatically serves the
// dependencies when connecting to the client.
ModuleDependencies []ModuleSourceDependency

// The directory where the client will be generated.
ClientDir string

// The engine version from dagger.json, used to pin the dagger.io/dagger dependency.
// This is only populated when generating from a module source (not in tests).
EngineVersion string
}
Loading