package consumers import ( "embed" "errors" "io/fs" "path" configkit "gitea.maximumdirect.net/eric/ConfigKit" ) //go:embed testdata/native-source testdata/layered-bundle var bundledFiles embed.FS // BundledConfig is a small configuration loaded directly from an embedded file. type BundledConfig struct { Name string `yaml:"name"` Enabled bool `yaml:"enabled"` } // LoadBundled demonstrates a native filesystem source without layered options. func LoadBundled() (*configkit.Result[BundledConfig], error) { files, err := fs.Sub(bundledFiles, "testdata/native-source") if err != nil { return nil, err } return configkit.Load[BundledConfig](configkit.NewFilesystem("bundled", files).File("config.yml")) } // CatalogConfig keeps resource names and domain rules in the application. type CatalogConfig struct { Mode string `yaml:"mode"` Enabled bool `yaml:"enabled"` Workers int `yaml:"workers"` Templates map[string]string `yaml:"templates"` Labels map[string]string `yaml:"labels"` } // LoadCatalog combines two underlay tiers beneath an independently located // host main file. ConfigKit assembles and validates the complete result once. func LoadCatalog(mainPath string) (*configkit.Result[CatalogConfig], error) { files, err := fs.Sub(bundledFiles, "testdata/layered-bundle") if err != nil { return nil, err } bundle := configkit.NewFilesystem("catalog bundle", files) return configkit.LoadLayered(configkit.Input{Source: configkit.File(mainPath)}, configkit.LayeredOptions[CatalogConfig]{ Underlays: []configkit.Underlay{ {Inputs: []configkit.Input{{Source: bundle.File("defaults/config.yml"), Imports: true}}}, {Inputs: []configkit.Input{{Source: configkit.Mapping("local policy", map[string]any{ "workers": 2, "labels": map[string]any{"tenant": "example"}, })}}}, }, Definition: configkit.Definition[CatalogConfig]{ Defaults: func() CatalogConfig { return CatalogConfig{Mode: "demo"} }, Validate: validateCatalog, }, }) } func validateCatalog(configuration *CatalogConfig, validation *configkit.Validation) { if configuration.Mode != "demo" && configuration.Mode != "production" { validation.Error(configkit.Keys("mode"), "must be demo or production") } if configuration.Workers < 0 { validation.Error(configkit.Keys("workers"), "must be nonnegative") } if name := configuration.Templates["welcome"]; name == "." || !fs.ValidPath(name) { validation.Error(configkit.Keys("templates", "welcome"), "must be a relative resource name") } } // ReadWelcome follows the effective template field's one declaring source to // its retained resource context. Opening and interpreting the resource remain // application work; this does not reopen configuration or change metadata. func ReadWelcome(result *configkit.Result[CatalogConfig]) (string, error) { if result == nil { return "", errors.New("catalog result is nil") } info, found := result.Metadata().Lookup(configkit.Keys("templates", "welcome")) if !found || len(info.Origin.Locations) != 1 { return "", errors.New("welcome template has no single declaring source") } context, found := result.SourceContext(info.Origin.Locations[0].SourceID) if !found { return "", errors.New("welcome template has no resource context") } data, err := fs.ReadFile(context.FS, path.Join(context.BaseDir, result.Config.Templates["welcome"])) if err != nil { return "", err } return string(data), nil }