Files
task-master/internal/project/store.go
T

89 lines
2.0 KiB
Go

package project
import (
"fmt"
"os"
"path/filepath"
"sort"
)
// Store manages project directories under DataDir/projects.
type Store interface {
List() ([]Project, error)
Ensure(id string) error
Delete(id string) error
}
// DirStore discovers projects as subdirectories of dataDir/projects.
type DirStore struct {
dataDir string
}
// NewDirStore creates a project store rooted at dataDir.
func NewDirStore(dataDir string) *DirStore {
return &DirStore{dataDir: dataDir}
}
func (s *DirStore) projectsRoot() string {
return filepath.Join(s.dataDir, "projects")
}
// List returns all project directories, sorted by name.
func (s *DirStore) List() ([]Project, error) {
root := s.projectsRoot()
entries, err := os.ReadDir(root)
if err != nil {
if os.IsNotExist(err) {
return []Project{}, nil
}
return nil, fmt.Errorf("list projects: %w", err)
}
var projects []Project
for _, e := range entries {
if !e.IsDir() {
continue
}
name := e.Name()
projects = append(projects, Project{ID: name, Name: name})
}
sort.Slice(projects, func(i, j int) bool {
return projects[i].Name < projects[j].Name
})
return projects, nil
}
// Ensure creates the project directory if it does not exist.
func (s *DirStore) Ensure(id string) error {
if id == "" {
return fmt.Errorf("project id is required")
}
dir := filepath.Join(s.projectsRoot(), id)
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("create project %s: %w", id, err)
}
return nil
}
// Delete removes the project directory and all of its files.
func (s *DirStore) Delete(id string) error {
if id == "" {
return fmt.Errorf("project id is required")
}
dir := filepath.Join(s.projectsRoot(), id)
st, err := os.Stat(dir)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("project %s: not found", id)
}
return fmt.Errorf("stat project %s: %w", id, err)
}
if !st.IsDir() {
return fmt.Errorf("project %s: not a directory", id)
}
if err := os.RemoveAll(dir); err != nil {
return fmt.Errorf("delete project %s: %w", id, err)
}
return nil
}