Files
GSP/toolkit/internal/gsp/load.go

93 lines
2.0 KiB
Go

package gsp
import (
"os"
"path/filepath"
"sort"
"strings"
"gopkg.in/yaml.v3"
)
var ignoredDirs = map[string]bool{
".git": true,
".gsp": true,
"node_modules": true,
"dist": true,
"build": true,
"bin": true,
}
func LoadProject(root string) (*Project, error) {
absRoot, err := filepath.Abs(root)
if err != nil {
return nil, err
}
project := &Project{
Root: absRoot,
ByID: map[string]*Unit{},
Duplicates: map[string][]*Unit{},
}
var files []string
err = filepath.WalkDir(absRoot, func(path string, entry os.DirEntry, walkErr error) error {
if walkErr != nil {
project.LoadIssues = append(project.LoadIssues, Issue{Level: "error", Code: "walk_error", File: path, Message: walkErr.Error()})
return nil
}
if entry.IsDir() {
if ignoredDirs[entry.Name()] {
return filepath.SkipDir
}
return nil
}
if strings.EqualFold(filepath.Ext(entry.Name()), ".gsp") {
files = append(files, path)
}
return nil
})
if err != nil {
return nil, err
}
sort.Strings(files)
for _, file := range files {
unit, err := readUnit(absRoot, file)
if err != nil {
project.LoadIssues = append(project.LoadIssues, Issue{Level: "error", Code: "parse_error", File: relPath(absRoot, file), Message: err.Error()})
continue
}
project.Units = append(project.Units, unit)
if unit.ID == "" {
continue
}
if existing, ok := project.ByID[unit.ID]; ok {
project.Duplicates[unit.ID] = append(project.Duplicates[unit.ID], existing, unit)
continue
}
project.ByID[unit.ID] = unit
}
return project, nil
}
func readUnit(root, file string) (*Unit, error) {
data, err := os.ReadFile(file)
if err != nil {
return nil, err
}
var unit Unit
if err := yaml.Unmarshal(data, &unit); err != nil {
return nil, err
}
unit.File = relPath(root, file)
return &unit, nil
}
func relPath(root, path string) string {
rel, err := filepath.Rel(root, path)
if err != nil {
return path
}
return filepath.ToSlash(rel)
}