workspace

package
v1.0.0-beta.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ConfigFileName is the workspace config filename.
	ConfigFileName = "dagger.toml"

	// ModuleConfigFileName is the current module config filename.
	ModuleConfigFileName = "dagger-module.toml"

	// LegacyModuleConfigFileName is the legacy module config filename.
	LegacyModuleConfigFileName = "dagger.json"
)
View Source
const (
	LockDirName = ".dagger"

	LockFileName       = "dagger.lock"
	LegacyLockFileName = "lock"
	LegacyLockFilePath = LockDirName + "/" + LegacyLockFileName

	CoreLockNamespace      = ""
	LockOperationOCILatest = "oci-latest"
	LockOperationOCISHA    = "oci-sha"
	LockOperationGitLatest = "git-latest"
	LockOperationGitSHA    = "git-sha"

	LatestReleaseVersion = "v1.0.0-beta.11"
)
View Source
const UndefinedEnvErrorPrefix = "workspace env %q is not defined"

UndefinedEnvErrorPrefix is the format string every "undefined env" error message starts with. Clients that cannot see extensions (version-skewed engines, non-GraphQL boundaries) match on it as a fallback.

View Source
const UndefinedEnvErrorType = "UNDEFINED_ENV_ERROR"

UndefinedEnvErrorType is the _type extension value identifying an UndefinedEnvError in a GraphQL error response.

Variables

This section is empty.

Functions

func AddMigratedModuleSDK

func AddMigratedModuleSDK(wsCfg *Config, sdkSource, modulePath string)

AddMigratedModuleSDK records, in a workspace config, the SDK/runtime a migrated module uses: modulePath is added to the as-sdk managed-module list of the install that exposes sdkSource. An existing as-sdk install for the same runtime source is reused (so several locally-referenced modules sharing a runtime collapse to one [modules.<sdk>] entry); otherwise a new one is created, matching how the root module's SDK is recorded. This keeps every locally-defined module's runtime installed and pinned in the workspace.

func AddMigratedSDKInstall

func AddMigratedSDKInstall(wsCfg *Config, sdkSource string)

AddMigratedSDKInstall records a workspace SDK install for sdkSource without registering a managed module — the "repo is just a dagger module" pin, where the one install is expected to serve every module in the repo. It reuses an existing as-sdk install for the same runtime source, so a later AddMigratedModuleSDK for the same runtime lands on the same entry instead of installing the SDK twice.

func CanonicalLockFilePath

func CanonicalLockFilePath(lockFile string) string

CanonicalLockFilePath maps the legacy .dagger/lock path to its dagger.lock sibling. Other paths are already canonical.

func ConventionalSDKShortName

func ConventionalSDKShortName(sdkRef string) string

ConventionalSDKShortName returns the workspace-side short name to use for an SDK install derived from its canonical source ref. Builtin runtimes ("go", "python", etc.) pass through unchanged; external refs collapse to the last path segment with any @version suffix stripped — matching the convention `dagger install` uses when no --name is supplied.

func DeleteConfigValue

func DeleteConfigValue(existingData []byte, key string) ([]byte, error)

DeleteConfigValue removes the value at the given dotted key from config TOML. It errors when the key is not currently set.

Deletion works on the TOML document rather than the typed config, so any valid config key is removable without per-field handling; only keys whose removal would break the containing entry are refused.

func DeleteUserConfigValue

func DeleteUserConfigValue(existing []byte, workspaceKey, key string) ([]byte, error)

DeleteUserConfigValue removes a config value under [workspaces.<workspaceKey>] in user-level config bytes, pruning any tables the removal leaves empty. It errors when the key is not set for that workspace.

func EnsureEnv

func EnsureEnv(cfg *Config, envName string) bool

EnsureEnv makes sure the named environment exists. It returns true when the config was changed.

func EnvNames

func EnvNames(cfg *Config) []string

EnvNames returns the configured environment names in deterministic order.

func ExtractConfigDefaults added in v0.21.0

func ExtractConfigDefaults(customizations []*modules.ModuleConfigArgument) map[string]any

ExtractConfigDefaults returns constructor arg defaults from customizations.

func FormatConfigPathSegment

func FormatConfigPathSegment(segment string) string

FormatConfigPathSegment formats one TOML dotted-key path segment.

func GitBranchFromHEAD

func GitBranchFromHEAD(data []byte) string

GitBranchFromHEAD parses .git/HEAD contents into the current short branch name. A detached HEAD (or anything else) yields "".

func GitRemoteURL

func GitRemoteURL(gitConfig []byte, remoteName string) (string, bool)

GitRemoteURL extracts the URL of the named remote from git config file contents (.git/config format, with any includes already expanded — see ResolveGitConfigIncludes). Like `git config --get`, the last value wins when the key appears more than once.

func HasOwnWorkspaceSemantics

func HasOwnWorkspaceSemantics(cfg *modules.ModuleConfig) bool

HasOwnWorkspaceSemantics reports whether cfg defines workspace-level semantics of its own — its own toolchains or a blueprint. Such a config cannot be migrated by in-place format conversion; it would need the full workspace treatment (PlanMigration moves and deletes its dagger.json), which would break a referrer that expects the module to stay put. This is deliberately narrower than mustMigrateToWorkspaceConfig, which also fires for a plain module whose source is a non-root subdir (a normal toolchain).

func IsLocalRef

func IsLocalRef(source, pin string) bool

IsLocalRef performs a fast heuristic check to determine whether a module reference string refers to a local path instead of a git source.

func JoinConfigPath

func JoinConfigPath(parts ...string) string

JoinConfigPath formats logical path segments as a TOML dotted key path.

func LegacyLockFilePathForCanonical

func LegacyLockFilePathForCanonical(lockFile string) string

LegacyLockFilePathForCanonical returns the legacy lockfile path that used to sit next to a canonical dagger.lock.

func LocalModuleRefs

func LocalModuleRefs(cfg *modules.ModuleConfig) []*modules.ModuleConfigDependency

LocalModuleRefs returns the local-path module references declared by cfg, drawn from its toolchains and dependencies in a stable order (toolchains first, then dependencies, each in declaration order). Remote (git/registry) references and the blueprint are skipped: migration recurses into the locally-defined modules a config points at, and blueprints are out of scope.

func LookupInputs

func LookupInputs(required []any, options ...LookupOption) []any

LookupInputs combines required positional inputs with optional named inputs.

func ModuleSourceAtRoot

func ModuleSourceAtRoot(cfg *modules.ModuleConfig) bool

ModuleSourceAtRoot reports whether a legacy module config's source lives in the config's own directory — the "repo is just a dagger module" shape, as opposed to a module tucked into a subdirectory of a project repo. Migration treats such a module as the repo itself: its config converts in place and it is neither installed into the workspace nor given an entrypoint.

func NewUndefinedEnvError

func NewUndefinedEnvError(cfg *Config, envName string) error

func NormalizeGitRemote

func NormalizeGitRemote(remote string) string

NormalizeGitRemote converts a Git remote URL in any common form into the canonical workspace key form used by user-level config: host/path with no scheme, no user, no trailing .git, and a lowercased host. For example, "git@github.com:acme/api.git", "https://github.com/acme/api", and "ssh://git@github.com/acme/api" all normalize to "github.com/acme/api".

Local filesystem remotes have no stable cross-machine identity and normalize to "".

func ParseGitDirFile

func ParseGitDirFile(data []byte) (string, bool)

ParseGitDirFile parses a .git *file* (as written for worktrees and submodules) and returns the gitdir path it points to.

func ParseLegacyModuleConfigTolerant

func ParseLegacyModuleConfigTolerant(data []byte) (*modules.ModuleConfig, error)

ParseLegacyModuleConfigTolerant parses a legacy dagger.json into a module config, falling back to a shape-only parse when the config declares a newer engine version than this binary supports. Migration still needs to read such a config's dependency graph to recurse, and to convert what it can.

func ParseLookupInputs

func ParseLookupInputs(inputs []any) ([]any, map[string]any, error)

ParseLookupInputs separates required positional inputs from optional named inputs.

func ReadConfigValue

func ReadConfigValue(data []byte, key string) (string, error)

ReadConfigValue reads a value from config TOML at the given dotted key. When key is empty, it returns the full config contents.

func RemoveEnv

func RemoveEnv(cfg *Config, envName string) error

RemoveEnv removes the named environment from the config.

func ResolveGitConfigIncludes

func ResolveGitConfigIncludes(
	ctx context.Context,
	readFile func(context.Context, string) ([]byte, error),
	state GitConfigState,
	data []byte,
) []byte

ResolveGitConfigIncludes expands include and includeIf directives in git config contents the way git does when reading configuration: each included file is inlined at the location of its directive, recursively, up to git's depth limit. Includes that cannot be read and includeIf sections whose condition does not match are skipped. Conditions with home-relative (~) patterns and hasconfig conditions are treated as non-matching, since the caller's home directory and full config set are not available here.

func ResolveModuleEntrySource

func ResolveModuleEntrySource(configDir, source string) string

ResolveModuleEntrySource converts a workspace-config module source into the path that should actually be loaded or displayed from the workspace root. Relative local sources are resolved from the config directory; absolute local sources are preserved as-is.

func ResolveSDKManagedPath

func ResolveSDKManagedPath(configDir, p string) (string, error)

ResolveSDKManagedPath turns an as-sdk path into the workspace-relative path the engine addresses modules and clients by, following the same rule as every other path a workspace resolves: a leading "/" means the workspace root, anything else is relative to the directory of the config that records it, and escaping the root is refused. Unlike ResolveModuleEntrySource these entries are always paths, never refs, so no ref classification happens here.

func SDKManagedPathFor

func SDKManagedPathFor(configDir, workspacePath string) (string, error)

SDKManagedPathFor is the inverse of ResolveSDKManagedPath: it expresses a workspace-relative path the way an as-sdk entry records it. A target outside the config directory keeps a "../" prefix, as its install source would.

func SerializeConfig

func SerializeConfig(cfg *Config) []byte

SerializeConfig serializes a workspace config into deterministic TOML.

func SplitConfigPath

func SplitConfigPath(key string) ([]string, error)

SplitConfigPath parses a TOML dotted key path into its logical path segments.

func UpdateConfigBytes

func UpdateConfigBytes(existingData []byte, cfg *Config) ([]byte, error)

UpdateConfigBytes rewrites config bytes while preserving existing comments and formatting when a prior file exists.

func WriteConfigValue

func WriteConfigValue(existingData []byte, key string, rawValue string) ([]byte, error)

WriteConfigValue writes a typed value to config TOML at the given dotted key.

func WriteConfigValues

func WriteConfigValues(existingData []byte, key string, values []string) ([]byte, error)

WriteConfigValues writes a string-array value to config TOML at the given dotted key. Elements are stored verbatim, with no comma-splitting or type auto-detection.

func WriteUserConfigValue

func WriteUserConfigValue(existing []byte, workspaceKey, key, rawValue string, values []string) ([]byte, error)

WriteUserConfigValue sets a config value under [workspaces.<workspaceKey>] in user-level config bytes, preserving unrelated sections (e.g. [llm]) and other workspace entries. The workspace key is canonicalized; when an entry for an equivalent remote spelling already exists, it is updated in place rather than duplicated. A non-nil values slice stores a string array verbatim; otherwise rawValue is typed like repository config writes.

Types

type CompatMainModule

type CompatMainModule struct {
	Name       string
	ConfigName string
	Entry      ModuleEntry
}

CompatMainModule is the projected legacy root module. It remains a distinct part of the compat workspace so runtime compat can load it from the original legacy location while migration persists it under .dagger/modules/<name>.

type CompatWorkspace

type CompatWorkspace struct {
	Modules     []CompatWorkspaceModule
	MainModule  *CompatMainModule
	Config      *modules.ModuleConfig
	ConfigPath  string
	ProjectRoot string

	// DiscoveredLocalModule marks a compat workspace that was reached by
	// following a local toolchain/dependency reference from another migrated
	// config (rather than being the selected project). Such a module is
	// converted in place regardless of a non-root source, and is never routed
	// to PlanMigration or a parent plan.
	DiscoveredLocalModule bool
}

CompatWorkspace is the shared projection of legacy dagger.json semantics used by both runtime compat mode and on-disk migration.

func ParseCompatWorkspace

func ParseCompatWorkspace(data []byte) (*CompatWorkspace, error)

ParseCompatWorkspace parses a legacy dagger.json into the migration-compatible compat-workspace representation. Returns nil if the legacy config does not need to migrate into workspace config at its own location.

func ParseCompatWorkspaceAt

func ParseCompatWorkspaceAt(data []byte, configPath string) (*CompatWorkspace, error)

ParseCompatWorkspaceAt parses a legacy dagger.json into the migration-compatible compat-workspace representation, with optional provenance from the config path. Returns nil if the legacy config does not need to migrate into workspace config at its own location.

func ParseMigrationCompatWorkspaceAt

func ParseMigrationCompatWorkspaceAt(data []byte, configPath string) (*CompatWorkspace, error)

ParseMigrationCompatWorkspaceAt parses a legacy dagger.json for migration planning. Unlike runtime loading, migration may need to plan a best-effort diff for a module that requires a newer engine so `dagger setup` (with the migration step's --force flow) can still write reviewable workspace files.

func ParseRuntimeCompatWorkspaceAt

func ParseRuntimeCompatWorkspaceAt(data []byte, configPath string) (*CompatWorkspace, error)

ParseRuntimeCompatWorkspaceAt parses a legacy dagger.json into the runtime compat-workspace representation, with optional provenance from the config path. Returns nil if the legacy config cannot create ambient workspace context.

func (*CompatWorkspace) MustMigrateToWorkspaceConfig

func (compatWorkspace *CompatWorkspace) MustMigrateToWorkspaceConfig() bool

MustMigrateToWorkspaceConfig reports whether this compat workspace was created from a legacy dagger.json that must be replaced by dagger.toml at the same location during migration.

func (*CompatWorkspace) WorkspaceConfig

func (compatWorkspace *CompatWorkspace) WorkspaceConfig() *Config

type CompatWorkspaceModule

type CompatWorkspaceModule struct {
	Name              string
	ConfigName        string
	Source            string
	Pin               string
	Entry             ModuleEntry
	ArgCustomizations []*modules.ModuleConfigArgument
}

CompatWorkspaceModule is one workspace-owned module projected out of a legacy dagger.json.

type Config

type Config struct {
	Modules            map[string]ModuleEntry `json:"modules,omitempty" toml:"modules"`
	Ignore             []string               `json:"ignore,omitempty" toml:"ignore"`
	DefaultsFromDotEnv bool                   `json:"defaults_from_dotenv,omitempty" toml:"defaults_from_dotenv,omitempty"`
	// CheckGenerated controls whether `dagger check` runs generate-as-checks,
	// which fail when generated files are stale. Defaults to true; set false to
	// skip them (like --no-generate). CLI flags override it.
	CheckGenerated *bool                  `json:"check-generated,omitempty" toml:"check-generated,omitempty"`
	Env            map[string]EnvOverlay  `json:"env,omitempty" toml:"env"`
	Ports          map[string]PortMapping `json:"ports,omitempty" toml:"ports,omitempty"`
}

Config represents a parsed dagger.toml workspace configuration.

func ApplyEnvOverlay

func ApplyEnvOverlay(cfg *Config, envName string) (*Config, error)

ApplyEnvOverlay returns a copy of cfg with the named environment overlay applied on top of the base module config.

Environments may override [modules.<name>.settings] of an installed module and may add modules that only exist in the environment (by providing a source). Naming a module that is neither installed in the base config nor given a source is an error.

func ApplyUserOverlay

func ApplyUserOverlay(cfg *Config, overlay *UserWorkspaceOverlay) (*Config, error)

ApplyUserOverlay returns a copy of cfg with the user-level workspace overlay merged over it.

Module overlays follow the same value semantics as environment overlays: settings shadow the base values key by key, and a source (with its pin) adds or replaces a module. Unlike environment overlays, an entry naming a module that is neither installed nor given a source is skipped rather than an error: the same workspace key spans every checkout and branch of a repo, so an always-on user entry must not break checkouts where the module does not exist. Environments are added to the config's env set; a user env that shares a name with a repository env is merged over it with user values winning.

func ParseConfig

func ParseConfig(data []byte) (*Config, error)

ParseConfig parses dagger.toml bytes into a workspace config.

type EnvModuleOverlay

type EnvModuleOverlay struct {
	// Source, when set, installs a module scoped to this environment. It mirrors
	// [modules.<name>.source]: a workspace-relative path or a canonical ref.
	Source string `json:"source,omitempty" toml:"source,omitempty"`
	// Pin is the resolved version for Source, mirroring [modules.<name>.pin].
	Pin      string         `json:"pin,omitempty" toml:"pin,omitempty"`
	Settings map[string]any `json:"settings,omitempty" toml:"settings,omitempty"`
}

EnvModuleOverlay is the environment-specific overlay for one module.

An overlay may override the [modules.<name>.settings] of a module already installed in the base config, and/or *add* a module that only exists in this environment by giving it a Source (and optional Pin). An overlay that names a module missing from the base config without a Source is an error.

type EnvOverlay

type EnvOverlay struct {
	Modules map[string]EnvModuleOverlay `json:"modules,omitempty" toml:"modules"`
}

EnvOverlay is a named workspace environment overlay. It intentionally supports only a constrained subset of the root schema.

type GitConfigState

type GitConfigState struct {
	// ConfigPath is the path of the config file being expanded; relative
	// include paths resolve against its directory.
	ConfigPath string
	// GitDir is the repository's $GIT_DIR (the per-worktree gitdir for linked
	// worktrees), matched by gitdir/gitdir:i conditions.
	GitDir string
	// Branch is the current short branch name, matched by onbranch
	// conditions. Empty when detached or unknown.
	Branch string
}

GitConfigState carries the repository state used to resolve git config include directives and evaluate includeIf conditions.

type LegacyBlueprint

type LegacyBlueprint struct {
	Name   string
	Source string
	Pin    string
}

LegacyBlueprint represents a blueprint extracted from a legacy dagger.json.

func ParseLegacyBlueprint

func ParseLegacyBlueprint(data []byte) (*LegacyBlueprint, error)

ParseLegacyBlueprint parses a legacy dagger.json and extracts its blueprint. Returns nil if no blueprint is present.

type LegacyToolchain

type LegacyToolchain struct {
	Name           string
	Source         string
	Pin            string
	ConfigDefaults map[string]any
	Customizations []*modules.ModuleConfigArgument
}

LegacyToolchain represents a toolchain extracted from a legacy dagger.json, with constructor arg defaults already resolved from customizations.

func ParseLegacyToolchains

func ParseLegacyToolchains(data []byte) ([]LegacyToolchain, error)

ParseLegacyToolchains parses a legacy dagger.json and extracts its toolchains with their constructor arg defaults. Returns nil if no toolchains are present.

type Lock added in v0.21.0

type Lock struct {
	// contains filtered or unexported fields
}

Lock is the workspace lockfile wrapper.

func NewLock added in v0.21.0

func NewLock() *Lock

NewLock returns an empty workspace lock.

func ParseLock added in v0.21.0

func ParseLock(data []byte) (*Lock, error)

ParseLock parses dagger.lock data.

func (*Lock) Clone added in v0.21.0

func (l *Lock) Clone() (*Lock, error)

Clone returns a deep copy of the lock.

func (*Lock) Entries added in v0.21.0

func (l *Lock) Entries() []LookupEntry

Entries returns a deterministic snapshot of all lookup entries.

func (*Lock) GetLookup added in v0.21.0

func (l *Lock) GetLookup(namespace, operation string, inputs []any) (string, bool)

GetLookup retrieves the value for a generic lookup tuple.

func (*Lock) Marshal added in v0.21.0

func (l *Lock) Marshal() ([]byte, error)

Marshal serializes lock entries.

func (*Lock) Merge added in v0.21.0

func (l *Lock) Merge(other *Lock) error

Merge applies all entries from other onto l.

func (*Lock) SetLookup added in v0.21.0

func (l *Lock) SetLookup(namespace, operation string, inputs []any, value string) error

SetLookup sets the value for a generic lookup tuple.

type LookupEntry added in v0.21.0

type LookupEntry struct {
	Namespace string
	Operation string
	Inputs    []any
	Value     string
}

LookupEntry is a structured lockfile lookup tuple.

type LookupOption

type LookupOption struct {
	Name  string
	Value any
}

LookupOption is an optional input to a lock operation. Options are encoded as ordered key-value pairs after the entry value.

type MigrationPlan

type MigrationPlan struct {
	// ProjectRoot is where the workspace config (dagger.toml) and migration
	// report land.
	ProjectRoot string
	// ModuleProjectRoot is where the legacy dagger.json lives: the migrated
	// dagger-module.toml replaces it there and the legacy file is removed
	// there. It equals ProjectRoot except for a hoisted subdirectory project,
	// whose workspace fields migrate to the workspace root while the module
	// config stays in place.
	ModuleProjectRoot        string
	Warnings                 []string
	MigrationGapCount        int
	MigrationReportPath      string
	WorkspaceConfigData      []byte
	MigratedModuleConfigData []byte
	MigratedModuleConfigPath string
	MigrationReportData      []byte
}

MigrationPlan is the pure filesystem plan for migrating a legacy dagger.json project to workspace format.

func PlanMigration

func PlanMigration(compatWorkspace *CompatWorkspace, workspaceRoot string) (*MigrationPlan, error)

PlanMigration computes the pure filesystem plan for migrating a compat workspace into workspace format. workspaceRoot is the workspace boundary: when the legacy config lives below it, the plan is "hoisted" — nested dagger.toml files are never created, so the config's workspace fields (toolchains) are installed into a dagger.toml at the workspace root with their local sources rebased, while the module config still converts in place at its own directory and the module itself is not installed.

When the config has an SDK, its toolchains are also recorded as dependencies of the migrated module config (see buildMigratedModuleConfig).

type ModuleAsSDK

type ModuleAsSDK struct {
	// Name is the user-facing SDK name used by `dagger module init <sdk>` and
	// `dagger api client init <sdk>`. When empty, the module entry name is used.
	Name string `json:"name,omitempty" toml:"name,omitempty"`

	// Modules lists the workspace-local modules this SDK authors and
	// manages. Each entry becomes a [[modules.<name>.as-sdk.modules]] block.
	Modules []SDKManagedModule `json:"modules,omitempty" toml:"modules,omitempty"`

	// Clients lists generated typed bindings this SDK produces in the
	// workspace. Each entry becomes a [[modules.<name>.as-sdk.clients]]
	// block. Shape is intentionally minimal until concrete client SDKs
	// (TypeScript, Go) take shape.
	Clients []SDKManagedClient `json:"clients,omitempty" toml:"clients,omitempty"`
}

ModuleAsSDK carries the per-module SDK-role data: which authored modules and clients this SDK manages in the workspace. Serialized under [modules.<name>.as-sdk] with array-of-tables sub-blocks.

type ModuleEntry

type ModuleEntry struct {
	Source            string         `json:"source" toml:"source"`
	Pin               string         `json:"pin,omitempty" toml:"pin,omitempty"`
	Settings          map[string]any `json:"settings,omitempty" toml:"settings,omitempty"`
	Entrypoint        bool           `json:"entrypoint,omitempty" toml:"entrypoint,omitempty"`
	LegacyDefaultPath bool           `json:"legacy-default-path,omitempty" toml:"legacy-default-path,omitempty"`
	Up                ModuleSkip     `json:"up,omitempty" toml:"up,omitempty"`
	Generate          ModuleSkip     `json:"generate,omitempty" toml:"generate,omitempty"`
	Check             ModuleSkip     `json:"check,omitempty" toml:"check,omitempty"`

	// AsSDK is the SDK-role data for module entries that serve as SDKs in
	// this workspace. Its presence (any populated sub-field) marks the
	// module as installed *as* an SDK; absence means it's a plain installed
	// module. The role data — which authored modules and generated clients
	// this SDK manages locally — lives nested rather than in a parallel
	// top-level section so settings, install, and SDK metadata all
	// converge on a single [modules.<name>.*] entry.
	AsSDK *ModuleAsSDK `json:"as-sdk,omitempty" toml:"as-sdk,omitempty"`
}

ModuleEntry represents a single module entry in the workspace config.

type ModuleSkip

type ModuleSkip struct {
	Skip []string `json:"skip,omitempty" toml:"skip,omitempty"`
}

ModuleSkip carries the per-action skip patterns for a module entry. Patterns may be exact names or globs and apply to the action's leaf nodes scoped under the module (e.g. "redis", "infra:database", "other-generators:*").

type PathExistsFunc

type PathExistsFunc func(ctx context.Context, path string) (parentDir string, exists bool, err error)

PathExistsFunc checks whether a filesystem path exists. Returns the canonical parent directory and whether the path exists.

type PortMapping

type PortMapping struct {
	BackendService string `json:"backendService" toml:"backendService"`
	BackendPort    int    `json:"backendPort" toml:"backendPort"`
}

PortMapping declares a host port that forwards to a workspace service. The map key on Config.Ports is the host port (string for TOML key shape: `[ports.3000]`). BackendService is the service path scoped under a workspace module (e.g. "hello-with-services:web").

type SDKManagedClient

type SDKManagedClient struct {
	Path    string            `json:"path" toml:"path"`
	Module  string            `json:"module" toml:"module"`
	Pin     string            `json:"pin,omitempty" toml:"pin,omitempty"`
	Options map[string]string `json:"options,omitempty" toml:"-"`
}

SDKManagedClient is a generated client produced by an SDK and bound to one module, with its path — and a Module given as a local path — resolved against the directory holding this dagger.toml, a leading "/" anchoring at the workspace root instead. Module also accepts a canonical ref, same resolution as modules.X.source. Shape will evolve as concrete client SDKs implement.

type SDKManagedModule

type SDKManagedModule struct {
	Path string `json:"path" toml:"path"`
}

SDKManagedModule is a path to a module that an SDK authors and manages here, resolved against the directory holding this dagger.toml, with a leading "/" anchoring it at the workspace root instead. The path is the only required field; the module's own engine state lives in <path>/dagger-module.toml.

type UndefinedEnvError

type UndefinedEnvError struct {
	Env     string
	Defined []string
}

UndefinedEnvError reports a selected env that has no env.<name>.* entry in the config. Enumerating the defined envs is the actionable part: a missing env is most often a typo, and the list is what disambiguates. No creation hint — envs come into being through env-scoped writes, but we can't know which write the user meant.

func (*UndefinedEnvError) Error

func (e *UndefinedEnvError) Error() string

func (*UndefinedEnvError) Extensions

func (e *UndefinedEnvError) Extensions() map[string]any

Extensions marks the error for structured detection across the GraphQL boundary: dagql attaches these to the error response for any error in the wrap chain, so the CLI's create-on-write retry can match _type and env instead of parsing the message.

type UserConfig

type UserConfig struct {
	Workspaces map[string]UserWorkspaceOverlay `toml:"workspaces"`
}

UserConfig is the workspace-relevant portion of the user-level Dagger config file (~/.config/dagger/config.toml, or $DAGGER_CONFIG). Only the [workspaces.*] section is modeled here; other sections (e.g. [llm]) are owned by other subsystems and ignored during parsing.

func ParseUserConfig

func ParseUserConfig(data []byte) (*UserConfig, error)

ParseUserConfig parses user-level Dagger config bytes. Unknown sections are ignored so the file can be shared with other subsystems.

func (*UserConfig) MatchWorkspaceOverlay

func (c *UserConfig) MatchWorkspaceOverlay(workspaceKey string) *UserWorkspaceOverlay

MatchWorkspaceOverlay returns the overlay whose key identifies the same remote as workspaceKey, or nil when none matches. Both sides are normalized before comparison so equivalent remote URL forms (https, ssh, scp-style, with or without .git) all match.

type UserWorkspaceOverlay

type UserWorkspaceOverlay struct {
	Modules map[string]EnvModuleOverlay `toml:"modules"`
	Env     map[string]EnvOverlay       `toml:"env"`
}

UserWorkspaceOverlay is one workspace's user-level overlay, keyed in the user config by the workspace's normalized Git remote (see NormalizeGitRemote). It is a constrained subset of the workspace config: always-applied module overlays plus personal environments. User-level values take precedence over the repository's dagger.toml.

type Workspace

type Workspace struct {
	// Root is the workspace boundary: the detected Git root, or an explicit
	// boundary supplied for a remote or legacy workspace.
	Root string

	// HasGitRoot records whether local detection found the boundary by walking
	// up to .git. An explicit legacy boundary remains useful for reading files,
	// but must not be treated as an exportable Git workspace.
	HasGitRoot bool

	// Cwd is the detection start location stored as a clean path relative to Root.
	Cwd string

	// ConfigFile is the selected native dagger.toml path relative to Root.
	// Empty means no native workspace config exists.
	ConfigFile string

	// LockFile is the selected canonical lockfile path relative to Root. It is
	// the nearest existing dagger.lock from Cwd up to Root, or the canonical
	// dagger.lock sibling of the selected config when none exists.
	LockFile string
}

Workspace represents a detected workspace boundary and selected files within it. ConfigFile and LockFile are deliberately separate: dagger.toml may be absent or projected from compat dagger.json, while lockfile read/write capabilities depend on the workspace source.

func Detect

func Detect(
	ctx context.Context,
	pathExists PathExistsFunc,
	cwd string,
) (*Workspace, error)

Detect finds the workspace boundary and selected workspace files from the given working directory.

Workspace root detection finds up to .git. If no git root is found, there is no workspace; callers should treat the nil workspace as a normal no-workspace condition, not an error.

After the boundary is known, ConfigFile is the nearest dagger.toml walking upward from cwd, stopping at the workspace root. LockFile is the canonical dagger.lock write target. Legacy .dagger/lock files influence the selected canonical sibling path when no dagger.lock exists.

func DetectInRoot

func DetectInRoot(
	ctx context.Context,
	pathExists PathExistsFunc,
	cwd string,
	root string,
) (*Workspace, error)

DetectInRoot detects the workspace cwd and selected files within an already known workspace root. This is used for remote workspaces, where the cloned git tree root is already the boundary even when .git is not present in the tree.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL