Documentation
¶
Index ¶
- Variables
- func GenerateID(projectRoot string) string
- func InferID(configDir, dir, cwd string) (string, error)
- func Slugify(name string) string
- type LifecycleHook
- type Lock
- type LookupOptions
- type ResolveResult
- type Result
- type Store
- func (s *Store) BaseDir() string
- func (s *Store) ClearHookMarkers(id string) error
- func (s *Store) Delete(id string) error
- func (s *Store) Exists(id string) bool
- func (s *Store) IsExplicitHome() bool
- func (s *Store) IsHookDone(id, hookName string) bool
- func (s *Store) List() ([]string, error)
- func (s *Store) Load(id string) (*Workspace, error)
- func (s *Store) LoadResult(id string) (*Result, error)
- func (s *Store) Lock(ctx context.Context, id string) (*Lock, error)
- func (s *Store) MarkHookDone(id, hookName string) error
- func (s *Store) Save(ws *Workspace) error
- func (s *Store) SaveResult(id string, result *Result) error
- func (s *Store) WorkspaceDir(id string) string
- type Workspace
Constants ¶
This section is empty.
Variables ¶
var ErrNoDevContainer = errors.New("no devcontainer configuration found")
ErrNoDevContainer is returned when no devcontainer configuration is found walking up from the start directory.
var ErrWorkspaceNotFound = errors.New("workspace not found")
ErrWorkspaceNotFound is returned when a workspace does not exist in the store.
Functions ¶
func GenerateID ¶ added in v0.7.0
GenerateID creates a workspace ID from the project root's absolute path. Format: {slugified-basename}-{7-char-sha256-of-full-path}. The hash suffix guarantees uniqueness across directories with the same name.
func InferID ¶ added in v0.8.0
InferID derives a workspace ID from the given directories without requiring workspace state to exist. It first tries normal devcontainer resolution (which walks up to find .devcontainer/), and falls back to slugifying the directory name if no devcontainer config is found. This allows cache commands to work even if the project was deleted or was never set up with crib.
Precedence: configDir > dir > cwd. When all three are empty, os.Getwd() is used as a fallback. Pass the working directory explicitly to avoid that call.
Types ¶
type LifecycleHook ¶ added in v0.7.1
LifecycleHook is a map of named command entries. String/array hooks use the "" key; object hooks use named keys that run in parallel. This mirrors config.LifecycleHook but is redeclared here to avoid a dependency on the config package from workspace.
type Lock ¶ added in v0.8.0
type Lock struct {
// contains filtered or unexported fields
}
Lock is a workspace file lock. Call Unlock to release it.
type LookupOptions ¶ added in v0.8.0
type LookupOptions struct {
ConfigDir string // explicit devcontainer config directory (from --config or .cribrc)
Dir string // explicit project directory (from --dir)
Cwd string // working directory fallback when ConfigDir and Dir are both empty
Version string // crib binary version recorded in the workspace CribVersion field
Create bool // create the workspace if it does not exist in the store
}
LookupOptions controls how Lookup resolves and (optionally) creates a workspace.
type ResolveResult ¶
type ResolveResult struct {
// ProjectRoot is the absolute path to the project root directory.
ProjectRoot string
// ConfigPath is the absolute path to the devcontainer.json file.
ConfigPath string
// RelativeConfigPath is the config path relative to ProjectRoot.
RelativeConfigPath string
// WorkspaceID is the derived workspace identifier.
WorkspaceID string
}
ResolveResult holds the outcome of workspace resolution.
func Resolve ¶
func Resolve(startDir string) (*ResolveResult, error)
Resolve walks up from startDir looking for a .devcontainer/ directory or .devcontainer.json file. Returns the project root, config path, and derived workspace ID.
func ResolveConfigDir ¶
func ResolveConfigDir(configDir string) (*ResolveResult, error)
ResolveConfigDir resolves workspace info when the devcontainer config directory is explicitly given (bypasses the walk-up). The config directory must contain a devcontainer.json directly. The project root is the parent of configDir.
type Result ¶
type Result struct {
// ContainerID is the Docker/Podman container ID.
ContainerID string `json:"containerID"`
// ImageName is the name of the built/pulled image.
ImageName string `json:"imageName"`
// MergedConfig is the devcontainer config after merging with image metadata.
// Stored as raw JSON to avoid a dependency on the config package.
MergedConfig json.RawMessage `json:"mergedConfig"`
// WorkspaceFolder is the path inside the container where the project is mounted.
WorkspaceFolder string `json:"workspaceFolder"`
// RemoteEnv holds the resolved remoteEnv variables from devcontainer.json.
// ${containerEnv:VAR} references are already substituted.
// These should be injected via -e flags when running docker/podman exec.
RemoteEnv map[string]string `json:"remoteEnv,omitempty"`
// RemoteUser is the user to run commands as inside the container.
// Passed as -u to docker/podman exec.
RemoteUser string `json:"remoteUser,omitempty"`
// SnapshotImage is the name of the snapshot image created after create-time
// hooks completed. Used by restart to skip re-running those hooks.
SnapshotImage string `json:"snapshotImage,omitempty"`
// SnapshotHookHash is a hash of the create-time hook definitions at the time
// the snapshot was taken. If hooks change, the snapshot is stale.
SnapshotHookHash string `json:"snapshotHookHash,omitempty"`
// HasFeatureEntrypoints is true when the image was built with features
// that declare entrypoints (e.g. docker-in-docker). Used by restart
// paths to know whether to override the container entrypoint.
HasFeatureEntrypoints bool `json:"hasFeatureEntrypoints,omitempty"`
// ComposeFilesHash is a short fingerprint (truncated SHA-256) of the
// compose file contents at the time the result was saved. Used by restart
// to detect changes inside compose files (volumes, ports, etc.) that are
// invisible to devcontainer.json config comparison.
ComposeFilesHash string `json:"composeFilesHash,omitempty"`
// Feature lifecycle hooks, stored so the resume/restart path can dispatch
// them without re-resolving features from OCI registries. These are the
// hooks declared in devcontainer-feature.json files, NOT the user's hooks
// from devcontainer.json. Per the spec, feature hooks run before user hooks.
FeatureOnCreateCommands []LifecycleHook `json:"featureOnCreateCommands,omitempty"`
FeatureUpdateContentCommands []LifecycleHook `json:"featureUpdateContentCommands,omitempty"`
FeaturePostCreateCommands []LifecycleHook `json:"featurePostCreateCommands,omitempty"`
FeaturePostStartCommands []LifecycleHook `json:"featurePostStartCommands,omitempty"`
FeaturePostAttachCommands []LifecycleHook `json:"featurePostAttachCommands,omitempty"`
}
Result stores the outcome of a successful `crib up` run.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store manages workspace state on disk at a base directory.
func NewStore ¶
NewStore creates a Store at the default location (~/.crib/workspaces). The CRIB_HOME env var overrides the base directory: $CRIB_HOME/workspaces.
func NewStoreAt ¶
NewStoreAt creates a Store with a custom base directory. Useful for testing.
func (*Store) BaseDir ¶ added in v0.8.0
BaseDir returns the store's base directory (e.g. ~/.crib/workspaces).
func (*Store) ClearHookMarkers ¶
ClearHookMarkers removes all lifecycle hook markers for a workspace, allowing hooks to run again (used on recreate).
func (*Store) IsExplicitHome ¶ added in v0.8.0
IsExplicitHome reports whether the store's base directory was set via the CRIB_HOME environment variable (as opposed to the default ~/.crib path).
func (*Store) IsHookDone ¶
IsHookDone checks whether a lifecycle hook has already been executed.
func (*Store) LoadResult ¶
LoadResult reads a build result from disk. Returns nil, nil if not found.
func (*Store) Lock ¶ added in v0.8.0
Lock acquires an exclusive file lock for a workspace, preventing concurrent mutations (up, down, rebuild, restart, remove) from racing. The caller must defer lock.Unlock() to release it. The lock respects context cancellation so Ctrl+C works while waiting for a competing process.
func (*Store) MarkHookDone ¶
MarkHookDone records that a lifecycle hook has been executed for a workspace.
func (*Store) SaveResult ¶
SaveResult writes a build result to disk.
func (*Store) WorkspaceDir ¶ added in v0.4.0
WorkspaceDir returns the on-disk directory for a workspace.
type Workspace ¶
type Workspace struct {
// ID is the workspace identifier, derived from the project directory name.
ID string `json:"id"`
// Source is the absolute path to the project root directory.
Source string `json:"source"`
// DevContainerPath is the relative path to the devcontainer config
// from the project root (e.g., ".devcontainer/devcontainer.json").
DevContainerPath string `json:"devContainerPath,omitempty"`
// CribVersion is the version of crib that last touched this workspace.
CribVersion string `json:"cribVersion,omitempty"`
// CreatedAt is when this workspace was first created.
CreatedAt time.Time `json:"createdAt"`
// LastUsedAt is when this workspace was last accessed.
LastUsedAt time.Time `json:"lastUsedAt"`
}
Workspace represents a crib workspace, which maps a local project directory to a devcontainer.
func Lookup ¶ added in v0.8.0
Lookup resolves a workspace from the given options. It checks ConfigDir, Dir, and Cwd (in that order) to locate the devcontainer config, then loads the workspace from the store. If the workspace does not exist and Create is true, it creates a new one. If Create is false, it returns ErrWorkspaceNotFound.