fix(lib): ExtractWorkspace now recurses into subdirectories
Was skipping directories entirely (`if entry.IsDir() { continue }`),
so .core/reference/ and its contents were never extracted.
Replaced fs.ReadDir loop with fs.WalkDir to handle nested dirs.
Added tests: CreatesFiles, CreatesSubdirectories, TemplateSubstitution.
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
e8ca0d856f
commit
3c5e6d6498
2 changed files with 111 additions and 19 deletions
|
|
@ -139,31 +139,39 @@ type WorkspaceData struct {
|
|||
// Template names: "default", "security", "review".
|
||||
func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) error {
|
||||
wsDir := "workspace/" + tmplName
|
||||
entries, err := fs.ReadDir(workspaceFS, wsDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(targetDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
return fs.WalkDir(workspaceFS, wsDir, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := entry.Name()
|
||||
content, err := fs.ReadFile(workspaceFS, wsDir+"/"+name)
|
||||
// Get relative path from template root
|
||||
rel, err := filepath.Rel(wsDir, path)
|
||||
if err != nil || rel == "." {
|
||||
return nil
|
||||
}
|
||||
|
||||
targetPath := filepath.Join(targetDir, rel)
|
||||
|
||||
if d.IsDir() {
|
||||
return os.MkdirAll(targetPath, 0755)
|
||||
}
|
||||
|
||||
content, err := fs.ReadFile(workspaceFS, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process .tmpl files through text/template
|
||||
outputName := name
|
||||
if core.HasSuffix(name, ".tmpl") {
|
||||
outputName = core.TrimSuffix(name, ".tmpl")
|
||||
tmpl, err := template.New(name).Parse(string(content))
|
||||
outputName := filepath.Base(targetPath)
|
||||
if core.HasSuffix(outputName, ".tmpl") {
|
||||
outputName = core.TrimSuffix(outputName, ".tmpl")
|
||||
targetPath = filepath.Join(filepath.Dir(targetPath), outputName)
|
||||
tmpl, err := template.New(outputName).Parse(string(content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -174,12 +182,8 @@ func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) error {
|
|||
content = buf.Bytes()
|
||||
}
|
||||
|
||||
if err := os.WriteFile(filepath.Join(targetDir, outputName), content, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return os.WriteFile(targetPath, content, 0644)
|
||||
})
|
||||
}
|
||||
|
||||
// --- List Functions ---
|
||||
|
|
|
|||
88
pkg/lib/lib_test.go
Normal file
88
pkg/lib/lib_test.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExtractWorkspace_CreatesFiles(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "test task"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
|
||||
// Check top-level template files exist
|
||||
for _, name := range []string{"CODEX.md", "CLAUDE.md", "PROMPT.md", "TODO.md", "CONTEXT.md"} {
|
||||
path := filepath.Join(dir, name)
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
t.Errorf("expected %s to exist", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractWorkspace_CreatesSubdirectories(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "test-repo", Task: "test task"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
|
||||
// Check .core/reference/ directory exists with files
|
||||
refDir := filepath.Join(dir, ".core", "reference")
|
||||
if _, err := os.Stat(refDir); os.IsNotExist(err) {
|
||||
t.Fatalf(".core/reference/ directory not created")
|
||||
}
|
||||
|
||||
// Check AX spec exists
|
||||
axSpec := filepath.Join(refDir, "RFC-025-AGENT-EXPERIENCE.md")
|
||||
if _, err := os.Stat(axSpec); os.IsNotExist(err) {
|
||||
t.Errorf("AX spec not extracted: %s", axSpec)
|
||||
}
|
||||
|
||||
// Check Core source files exist
|
||||
entries, err := os.ReadDir(refDir)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read reference dir: %v", err)
|
||||
}
|
||||
|
||||
goFiles := 0
|
||||
for _, e := range entries {
|
||||
if filepath.Ext(e.Name()) == ".go" {
|
||||
goFiles++
|
||||
}
|
||||
}
|
||||
if goFiles == 0 {
|
||||
t.Error("no .go files in .core/reference/")
|
||||
}
|
||||
|
||||
// Check docs subdirectory
|
||||
docsDir := filepath.Join(refDir, "docs")
|
||||
if _, err := os.Stat(docsDir); os.IsNotExist(err) {
|
||||
t.Errorf(".core/reference/docs/ not created")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractWorkspace_TemplateSubstitution(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
data := &WorkspaceData{Repo: "my-repo", Task: "fix the bug"}
|
||||
|
||||
err := ExtractWorkspace("default", dir, data)
|
||||
if err != nil {
|
||||
t.Fatalf("ExtractWorkspace failed: %v", err)
|
||||
}
|
||||
|
||||
// TODO.md should contain the task
|
||||
content, err := os.ReadFile(filepath.Join(dir, "TODO.md"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read TODO.md: %v", err)
|
||||
}
|
||||
if len(content) == 0 {
|
||||
t.Error("TODO.md is empty")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue