package dorks import ( "embed" "errors" "fmt" "io/fs" "path/filepath" "strings" "gopkg.in/yaml.v3" ) // definitionsFS embeds every file under pkg/dorks/definitions. The trailing // `/*` is deliberate: it tolerates an empty tree containing only a .gitkeep // placeholder, which is the case for this foundation plan before Wave 2 // plans drop in 150+ real dork YAML files. // //go:embed definitions/* var definitionsFS embed.FS // loadDorks walks the embedded definitions tree and returns every Dork found // in a *.yaml file. Non-YAML files (e.g. .gitkeep) are ignored, empty trees // return (nil, nil), and parse or validation errors are wrapped with the // offending file path. func loadDorks() ([]Dork, error) { var dorks []Dork err := fs.WalkDir(definitionsFS, "definitions", func(path string, d fs.DirEntry, err error) error { if err != nil { // Empty definitions directory (only .gitkeep) is valid. if errors.Is(err, fs.ErrNotExist) { return fs.SkipAll } return err } if d.IsDir() { return nil } if !strings.EqualFold(filepath.Ext(path), ".yaml") && !strings.EqualFold(filepath.Ext(path), ".yml") { return nil } data, err := definitionsFS.ReadFile(path) if err != nil { return fmt.Errorf("reading dork file %s: %w", path, err) } // Support two YAML shapes: // 1. A top-level list of Dork entries (preferred, used by Wave 2+ plans). // 2. A single Dork as a top-level mapping (legacy one-per-file form). var list []Dork if err := yaml.Unmarshal(data, &list); err == nil && len(list) > 0 { for _, dk := range list { if err := dk.Validate(); err != nil { return fmt.Errorf("validating dork %s (%s): %w", path, dk.ID, err) } dorks = append(dorks, dk) } return nil } var dk Dork if err := yaml.Unmarshal(data, &dk); err != nil { return fmt.Errorf("parsing dork %s: %w", path, err) } if strings.TrimSpace(dk.ID) == "" { // Empty file or placeholder (e.g., .gitkeep-adjacent empty YAML) — ignore. return nil } if err := dk.Validate(); err != nil { return fmt.Errorf("validating dork %s: %w", path, err) } dorks = append(dorks, dk) return nil }) if err != nil { return nil, err } return dorks, nil }