e3c8979e8d
- cmd/fn/doctor.go - cmd/fn/main.go - cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt - cpp/apps/primitives_gallery/playground/tables/data_table.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.h - cpp/apps/primitives_gallery/playground/tables/self_test.cpp - cpp/apps/primitives_gallery/playground/tables/tql.cpp - cpp/apps/primitives_gallery/playground/tables/viz.cpp - cpp/apps/primitives_gallery/playground/tables/viz.h - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
3.0 KiB
Go
97 lines
3.0 KiB
Go
package infra
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// VaultManifestEntry is a single vault entry parsed from a projects/<proj>/vaults/vault.yaml.
|
|
type VaultManifestEntry struct {
|
|
ProjectID string // basename of projects/<proj>/, inferred from manifest path
|
|
Name string // vault name as declared in vault.yaml
|
|
Description string // human description
|
|
Path string // absolute path to the vault directory
|
|
Tags []string // tags declared in vault.yaml
|
|
ManifestFile string // absolute path to the vault.yaml this entry came from
|
|
}
|
|
|
|
// vaultYAML mirrors the vault.yaml schema (only the fields we care about).
|
|
type vaultYAML struct {
|
|
Vaults []struct {
|
|
Name string `yaml:"name"`
|
|
Description string `yaml:"description"`
|
|
Path string `yaml:"path"`
|
|
Tags []string `yaml:"tags"`
|
|
} `yaml:"vaults"`
|
|
}
|
|
|
|
// VaultManifestRead globs all projects/*/vaults/vault.yaml under repoRoot, parses each
|
|
// manifest and returns a flat slice of VaultManifestEntry.
|
|
//
|
|
// Rules:
|
|
// - If a manifest fails to parse, an error is returned immediately with the file path.
|
|
// - If no manifests are found, an empty slice is returned (not an error).
|
|
// - ProjectID is inferred from the directory component between "projects/" and "/vaults/".
|
|
func VaultManifestRead(repoRoot string) ([]VaultManifestEntry, error) {
|
|
pattern := filepath.Join(repoRoot, "projects", "*", "vaults", "vault.yaml")
|
|
matches, err := filepath.Glob(pattern)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("vault_manifest_read: glob %q: %w", pattern, err)
|
|
}
|
|
|
|
var out []VaultManifestEntry
|
|
for _, manifestPath := range matches {
|
|
entries, err := parseVaultManifest(manifestPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, entries...)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func parseVaultManifest(manifestPath string) ([]VaultManifestEntry, error) {
|
|
data, err := os.ReadFile(manifestPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("vault_manifest_read: read %q: %w", manifestPath, err)
|
|
}
|
|
|
|
var raw vaultYAML
|
|
if err := yaml.Unmarshal(data, &raw); err != nil {
|
|
return nil, fmt.Errorf("vault_manifest_read: parse %q: %w", manifestPath, err)
|
|
}
|
|
|
|
projectID := inferProjectID(manifestPath)
|
|
|
|
entries := make([]VaultManifestEntry, 0, len(raw.Vaults))
|
|
for _, v := range raw.Vaults {
|
|
entries = append(entries, VaultManifestEntry{
|
|
ProjectID: projectID,
|
|
Name: v.Name,
|
|
Description: v.Description,
|
|
Path: v.Path,
|
|
Tags: v.Tags,
|
|
ManifestFile: manifestPath,
|
|
})
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
// inferProjectID extracts the project basename from a path of the form
|
|
// .../projects/<proj>/vaults/vault.yaml.
|
|
func inferProjectID(manifestPath string) string {
|
|
// Normalize separators and split.
|
|
parts := strings.Split(filepath.ToSlash(manifestPath), "/")
|
|
// Walk backwards: vault.yaml -> vaults -> <proj> -> projects -> ...
|
|
for i, p := range parts {
|
|
if p == "projects" && i+1 < len(parts) {
|
|
return parts[i+1]
|
|
}
|
|
}
|
|
return ""
|
|
}
|