Documentation
¶
Overview ¶
Package workspace defines workspace values and detached storage locations.
Index ¶
- Constants
- Variables
- func AttachPath(root string, workspaceName Name, path string) error
- func CanonicalPath(path string) (string, error)
- func CanonicalStoredPath(path string) (string, error)
- func ClearCurrentWorkspace(root string) error
- func ManifestPath(repositoryRoot string) (string, error)
- func RegistryLockPath(root string) (string, error)
- func RegistryPath(root string) (string, error)
- func RepositoryPath(storageRoot string, id ID) (string, error)
- func SetCurrentWorkspace(root string, name Name) error
- func StorageRoot() (string, error)
- func UpdateRegistry(root string, mutate func(*Registry) error) error
- func WriteManifest(repositoryRoot string, manifest Manifest) (err error)
- type CreateLocation
- type CreateRequest
- type ID
- type Manifest
- type Name
- type Registry
- type Workspace
- type WorkspaceMatch
Constants ¶
const (
CurrentManifestVersion = 1
)
const (
// CurrentRegistryVersion is the only registry format this package reads and writes.
CurrentRegistryVersion = 1
)
Variables ¶
var ( // ErrInvalidCurrentWorkspace reports malformed or unsupported persisted // current-workspace preference data. ErrInvalidCurrentWorkspace = errors.New("current workspace preference is invalid") // ErrWorkspaceNotRegistered reports a workspace-name lookup that has no // corresponding entry in the detached workspace registry. ErrWorkspaceNotRegistered = errors.New("workspace is not registered") )
var ( ErrInvalidManifest = errors.New("workspace manifest is invalid") ErrManifestNotFound = errors.New("workspace manifest was not found") ErrManifestConflict = errors.New("workspace manifest binds a different workspace") ErrInvalidRepositoryID = errors.New("repository identity is invalid") )
var ( // ErrInvalidName reports a workspace name that cannot safely identify a // registry entry. ErrInvalidName = errors.New("workspace name is invalid") // ErrInvalidID reports a workspace identity that does not match the // generated-ID format. ErrInvalidID = errors.New("workspace identity is invalid") // ErrInvalidWorkspace reports incomplete or unsafe workspace registry data. ErrInvalidWorkspace = errors.New("workspace is invalid") )
var ( // ErrInvalidRegistry reports invalid registry structure or an unsupported version. ErrInvalidRegistry = errors.New("workspace registry is invalid") // ErrPathAlreadyAttached reports an attempt to attach a repository to a second workspace. ErrPathAlreadyAttached = errors.New("repository path is already attached to another workspace") // ErrWorkspaceNotFound reports that no registered workspace owns a working directory. ErrWorkspaceNotFound = errors.New("no workspace matches working directory") )
var ( // ErrInvalidStorageRoot reports a configured XDG data root that is not an // absolute filesystem path. ErrInvalidStorageRoot = errors.New("workspace storage root is invalid") // provide the home directory needed for its default storage location. ErrStorageRootUnavailable = errors.New("workspace storage root is unavailable") )
Functions ¶
func AttachPath ¶
AttachPath canonicalizes path and attaches it to workspace. The workspace must already be present in the registry.
func CanonicalPath ¶
CanonicalPath returns path as an absolute, symlink-evaluated, clean path.
func CanonicalStoredPath ¶
CanonicalStoredPath resolves path the same way CanonicalPath does, but tolerates a path whose target no longer exists on disk (e.g. a previously attached repository that was later deleted or moved outside of Spool). In that case it resolves symlinks for the longest existing ancestor directory and re-appends the missing trailing components verbatim, which matches how the path was canonicalized while it still existed (its leaf directory is not itself a symlink) rather than a plain, symlink-unaware Abs/Clean. This matters on platforms such as macOS where a common ancestor (e.g. /var) is itself a symlink: without resolving it, a deleted attachment would canonicalize to a different string than the one originally stored, so callers like `spl workspace detach` would report it as not attached. Callers that only need to match against an already-persisted canonical path (rather than validate a fresh attachment) should prefer this over CanonicalPath, since a stale attachment must remain resolvable so it can still be found, listed, and detached.
func ClearCurrentWorkspace ¶
ClearCurrentWorkspace removes any persisted active detached workspace preference. Clearing an unset preference succeeds without error.
func ManifestPath ¶ added in v0.0.8
ManifestPath returns the checkout-owned manifest path.
func RegistryLockPath ¶
RegistryLockPath returns the registry lock file below root.
func RegistryPath ¶
RegistryPath returns the registry file below root.
func RepositoryPath ¶
RepositoryPath returns the deterministic detached repository directory for id below storageRoot. It performs no filesystem access or symlink resolution.
func SetCurrentWorkspace ¶
SetCurrentWorkspace durably records name as the active detached workspace for future sessions. The named workspace must already exist in the registry.
func StorageRoot ¶
StorageRoot returns Spool's platform-appropriate detached storage root.
XDG_DATA_HOME, when configured, takes precedence on every platform. Unix defaults to the XDG data location; Windows uses its conventional per-user application-data location when no XDG override is present.
func UpdateRegistry ¶
UpdateRegistry serializes mutations through registry.lock and durably persists the complete replacement registry. The mutation must not retain registry.
func WriteManifest ¶ added in v0.0.8
WriteManifest atomically writes a validated checkout manifest. Existing local repository control state is never overwritten.
Types ¶
type CreateLocation ¶
type CreateLocation struct {
StorageRoot string `json:"storageRoot"`
StateDir string `json:"stateDir"`
ID ID `json:"id"`
}
CreateLocation is the resolved detached location for a workspace creation request.
func ResolveCreateLocation ¶
func ResolveCreateLocation(request CreateRequest) (CreateLocation, error)
ResolveCreateLocation validates request and resolves its detached state directory from the current process environment.
type CreateRequest ¶
CreateRequest identifies the workspace to create. It contains no storage or persistence policy so callers can resolve a location before initialization.
func NewCreateRequest ¶
func NewCreateRequest(name Name) (CreateRequest, error)
NewCreateRequest creates a validated workspace-creation request with a new identity, keeping identity generation separate from the workspace name.
func (CreateRequest) Validate ¶
func (request CreateRequest) Validate() error
Validate reports whether request contains a valid workspace name and ID.
type ID ¶
type ID string
ID identifies a workspace independently of its user-facing name.
func NewID ¶
NewID creates a random durable workspace identity in the form ws_ followed by eight lowercase hexadecimal characters.
type Manifest ¶ added in v0.0.8
type Manifest struct {
FormatVersion int `toml:"format_version"`
RepositoryID string `toml:"repository_id"`
WorkspaceID ID `toml:"workspace_id"`
}
Manifest declares the portable workspace binding for a checkout.
func DiscoverManifest ¶ added in v0.0.8
func DiscoverManifest(workingDirectory string) (repositoryRoot string, manifest Manifest, found bool, err error)
DiscoverManifest searches workingDirectory and its ancestors for a workspace manifest. A local Spool repository config without workspace_id is ignored.
type Name ¶
type Name string
Name identifies a workspace by its stable, user-selected slug.
func CurrentWorkspaceName ¶
CurrentWorkspaceName reads the persisted active detached workspace preference. It reports ok=false when no preference has been set yet.
type Registry ¶
type Registry struct {
Version int `toml:"version"`
Workspaces map[Name]Workspace `toml:"workspaces"`
}
Registry is the versioned central workspace registry stored at registry.toml. Workspace map keys are stable workspace slugs; Workspace.Name is the display name.
func LoadRegistry ¶
LoadRegistry reads the registry rooted at root while holding registry.lock. A missing registry is represented by an empty current-version registry.
func NewRegistry ¶
func NewRegistry() Registry
NewRegistry returns an empty registry using the current format version.
type Workspace ¶
type Workspace struct {
ID ID `toml:"id" json:"id"`
Name string `toml:"name" json:"name"`
StateDir string `toml:"state_dir" json:"stateDir"`
CreatedAt time.Time `toml:"created_at" json:"createdAt"`
Paths []string `toml:"paths" json:"paths"`
}
Workspace is a registered workspace's domain representation.
type WorkspaceMatch ¶
WorkspaceMatch identifies the registry entry that owns a working directory.
func FindWorkspace ¶
func FindWorkspace(root, workingDirectory string) (WorkspaceMatch, error)
FindWorkspace loads the registry below root and returns the workspace whose attached repository path is the longest component-boundary prefix of workingDirectory. It canonicalizes workingDirectory before matching.
It returns ErrWorkspaceNotFound when no attached repository contains workingDirectory. Registry and filesystem errors are returned unchanged or wrapped and are distinct from ErrWorkspaceNotFound.
func FindWorkspaceByID ¶ added in v0.0.8
func FindWorkspaceByID(root string, id ID) (WorkspaceMatch, error)
FindWorkspaceByID loads the registry and returns the unique workspace with id.