package atlas import ( "bytes" "encoding/json" "fmt" ) // GenerateKeys names the live sources a stage draws nodes from. A stage grew // past one source once stuck-badges landed alongside the existing overlays, so // this accepts either spelling in atlas.json: // // "generate": "ci-jobs" // "generate": ["stuck-badges", "gitea-repos"] // // The bare string is kept rather than migrated: most stages have exactly one // source, and a one-element list reads worse for no benefit. type GenerateKeys []string // Has reports whether the stage draws from the named source. The empty key // never matches, so a stage with no `generate` is inert. func (g GenerateKeys) Has(key string) bool { if key == "" { return false } for _, k := range g { if k == key { return true } } return false } func (g *GenerateKeys) UnmarshalJSON(b []byte) error { b = bytes.TrimSpace(b) if len(b) == 0 || string(b) == "null" { *g = nil return nil } if b[0] == '"' { var one string if err := json.Unmarshal(b, &one); err != nil { return fmt.Errorf("parse generate: %w", err) } *g = GenerateKeys{one} return nil } var many []string if err := json.Unmarshal(b, &many); err != nil { return fmt.Errorf("parse generate: %w", err) } *g = many return nil } // MarshalJSON writes a lone key back as a bare string, so a round-trip through // the API does not rewrite every authored stage into list form. func (g GenerateKeys) MarshalJSON() ([]byte, error) { if len(g) == 1 { return json.Marshal(g[0]) } return json.Marshal([]string(g)) }