74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package workspace
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"codespace/internal/util"
|
|
)
|
|
|
|
// Manager manages workspace lifecycle.
|
|
type Manager interface {
|
|
Create(id string) (*Workspace, error)
|
|
Get(id string) (*Workspace, error)
|
|
Delete(id string) error
|
|
}
|
|
|
|
// LocalManager implements Manager using the local filesystem.
|
|
type LocalManager struct {
|
|
root string
|
|
}
|
|
|
|
// NewLocalManager creates a LocalManager rooted at root. The root is made
|
|
// absolute and cleaned if possible.
|
|
func NewLocalManager(root string) *LocalManager {
|
|
abs, err := filepath.Abs(root)
|
|
if err != nil {
|
|
abs = filepath.Clean(root)
|
|
}
|
|
return &LocalManager{root: abs}
|
|
}
|
|
|
|
// Create creates a workspace directory and returns the workspace.
|
|
func (m *LocalManager) Create(id string) (*Workspace, error) {
|
|
if !ValidID(id) {
|
|
return nil, util.New(util.CodeBadRequest, "invalid workspace id")
|
|
}
|
|
root := RootFor(m.root, id)
|
|
if err := os.MkdirAll(root, 0o755); err != nil {
|
|
return nil, util.Wrap(util.CodeInternal, "failed to create workspace", err)
|
|
}
|
|
return &Workspace{ID: id, Root: root}, nil
|
|
}
|
|
|
|
// Get returns the workspace if its directory exists.
|
|
func (m *LocalManager) Get(id string) (*Workspace, error) {
|
|
if !ValidID(id) {
|
|
return nil, util.New(util.CodeBadRequest, "invalid workspace id")
|
|
}
|
|
root := RootFor(m.root, id)
|
|
info, err := os.Stat(root)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, util.New(util.CodeNotFound, "workspace not found")
|
|
}
|
|
return nil, util.Wrap(util.CodeInternal, "failed to stat workspace", err)
|
|
}
|
|
if !info.IsDir() {
|
|
return nil, util.New(util.CodeNotFound, "workspace not found")
|
|
}
|
|
return &Workspace{ID: id, Root: root}, nil
|
|
}
|
|
|
|
// Delete removes the workspace directory recursively.
|
|
func (m *LocalManager) Delete(id string) error {
|
|
if !ValidID(id) {
|
|
return util.New(util.CodeBadRequest, "invalid workspace id")
|
|
}
|
|
root := RootFor(m.root, id)
|
|
if err := os.RemoveAll(root); err != nil {
|
|
return util.Wrap(util.CodeInternal, "failed to delete workspace", err)
|
|
}
|
|
return nil
|
|
}
|