feat: scaffold codespace backend
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user