Documentation
¶
Overview ¶
Package config reads and writes the ana CLI configuration file.
The on-disk shape holds one or more named profiles, each carrying an endpoint + token pair. API keys are org-scoped, so users targeting more than one TextQL org need one profile per org. A single "active" pointer selects which profile is used by default.
Index ¶
Constants ¶
const DefaultEndpoint = "https://app.textql.com"
DefaultEndpoint is used by Resolve when no endpoint is configured.
Variables ¶
var ErrUnknownProfile = errors.New("config: unknown profile")
ErrUnknownProfile is returned by Resolve when the caller explicitly asked for a profile by name (via --profile) that does not exist in the loaded config AND no ANA_ENDPOINT/ANA_TOKEN env fallback was provided. Wrapped with %w so callers can detect it via errors.Is.
Functions ¶
func DefaultPath ¶
DefaultPath returns the default path for the config file.
It prefers $XDG_CONFIG_HOME/ana/config.json; falling back to $HOME/.config/ana/config.json. If neither variable is set, an error is returned.
env is the environment lookup function (injected so tests do not touch the real process environment); callers typically pass os.Getenv.
Types ¶
type Config ¶
type Config struct {
Profiles map[string]Profile `json:"profiles"`
Active string `json:"active"`
UpdateCheckInterval *string `json:"updateCheckInterval,omitempty"`
}
Config is the persisted CLI configuration. Profiles maps profile name to its Profile. Active names the profile selected by default.
UpdateCheckInterval controls the passive self-update nudge cadence (see internal/update.ParseInterval). A pointer + omitempty keeps the on-disk shape backward-compatible: existing files never acquire the field and a nil value means "use the built-in default".
func Load ¶
Load reads a config file from path. A missing file yields a zero-value Config and a nil error (first-run case). Other IO or JSON errors are wrapped and returned.
If the file is a legacy {endpoint, token} document (no "profiles" key), it is migrated in-memory to a single "default" profile. The migration is not persisted automatically — the next Save overwrites in the new shape.
When the new shape is present with an empty Active and exactly one profile, Active is inferred from that profile's name. With two or more profiles Active stays empty and callers must pick one.
func (Config) ActiveProfile ¶
ActiveProfile returns the currently active profile. ok is false when Active is unset or points at a profile that is not in the map.
type Profile ¶
type Profile struct {
Endpoint string `json:"endpoint"`
Token cli.Token `json:"token"`
OrgName string `json:"orgName,omitempty"`
}
Profile is a single named {endpoint, token} pair. OrgName is a human label captured at login time; it is purely informational and never affects resolution.
func Resolve ¶
Resolve selects a profile and applies environment overrides.
Profile selection priority (first non-empty wins):
- profileName argument (from --profile)
- env("ANA_PROFILE")
- loaded.Active
- first key of loaded.Profiles, sorted for determinism
- "default"
A selected name that does not exist in loaded.Profiles yields an empty Profile{} — this is not an error because first-run/login writes into a named slot that doesn't exist yet. The one exception: when the caller passed an explicit profileName that is missing AND no ANA_ENDPOINT / ANA_TOKEN env override is present, that's a user mistake (e.g. `--profile prod` when `prod` is not configured) and ErrUnknownProfile is returned with the bad name in the message.
ANA_ENDPOINT and ANA_TOKEN override whatever was resolved from the profile. If the final Endpoint is still empty, DefaultEndpoint fills it.