package config import ( "errors" "fmt" "os" "sort" configkit "gitea.maximumdirect.net/eric/ConfigKit" renderformat "gitea.maximumdirect.net/eric/scriptorium/internal/format" ) // LoadOptions selects one application source and explicit configuration values. type LoadOptions struct { Path string Explicit bool Overlay string Overrides []configkit.Override } // Load resolves one ConfigKit document and retains its inspection snapshot. func Load(options LoadOptions) (*configkit.Result[Document], error) { var source configkit.Source if options.Explicit { source = configkit.File(options.Path) } else { selected := "" for _, candidate := range defaultConfigSearchPaths { if _, err := os.Stat(candidate); err == nil { selected = candidate break } else if !errors.Is(err, os.ErrNotExist) { reason := "filesystem error" if errors.Is(err, os.ErrPermission) { reason = "permission denied" } return nil, fmt.Errorf("cannot inspect configuration path %q: %s", candidate, reason) } } if selected == "" { source = configkit.NoSource() } else { source = configkit.File(selected) } } result, err := configkit.Load(source, configkit.Options[Document]{ Definition: documentDefinition(), Overrides: options.Overrides, }) if err != nil { return nil, fmt.Errorf("load application configuration: %w", err) } return result, nil } // Settings converts a validated document without another merge or normalization. func Settings(document Document) AppSettings { settings := AppSettings{ PromptDir: document.PromptDir, ProfileDir: document.ProfileDir, SchemaDir: document.SchemaDir, ServerAddr: document.Server.Addr, ArtifactRoot: document.Server.ArtifactRoot, MaxRequestBytes: document.Server.MaxRequestBytes, MaxArtifactBytes: document.Server.MaxArtifactBytes, MaxResponseBytes: document.Server.MaxResponseBytes, DefaultRenderFormat: renderformat.PreparedRunOutputFormat(document.Defaults.RenderFormat), TransientRetries: document.TransientRetries, } if document.Backends != nil { ids := make([]string, 0, len(document.Backends)) for id := range document.Backends { ids = append(ids, id) } sort.Strings(ids) settings.Backends = make([]BackendSettings, 0, len(ids)) for _, id := range ids { backend := document.Backends[id] settings.Backends = append(settings.Backends, BackendSettings{ ID: id, Endpoint: backend.Endpoint, APIKeyEnv: backend.APIKeyEnv, ExtraParams: backend.ExtraParams, ConcurrencyLimit: backend.ConcurrencyLimit, QueueCapacity: backend.QueueCapacity, }) } } return settings }