feat(client): config search chain, --repo zero-config override, actionable missing-config error
sync/status now resolve the work repository from a fallback chain: --repo flag > --config flag > AGENT_LIB_CONFIG env > user-level config (XDG / AppData) > admin platform default. --repo works without any config file; tokens fall back to AGENT_LIB_GIT_TOKEN/AGENT_LIB_GIT_USER without ever overriding a configured token. A completely empty chain yields an error listing every searched location, a minimal config example and the --repo shortcut. Closes beads: agent-lib-9o8
This commit is contained in:
+36
-2
@@ -10,9 +10,13 @@ import (
|
||||
"github.com/m3tam3re/agent-lib/internal/target"
|
||||
)
|
||||
|
||||
// SyncOptions parameterize a client sync run.
|
||||
// SyncOptions parameterize a client sync run. RepoURL (with optional Ref)
|
||||
// is the inline --repo override: it works without any config file and beats
|
||||
// a repo_url discovered in the config chain.
|
||||
type SyncOptions struct {
|
||||
ConfigPath string
|
||||
RepoURL string
|
||||
Ref string
|
||||
}
|
||||
|
||||
// prepared is everything sync and status share: the pulled repository, the
|
||||
@@ -28,7 +32,10 @@ type prepared struct {
|
||||
// prepare pulls, inventories, hashes and plans — the complete read-only
|
||||
// front half of a client run.
|
||||
func prepare(opts SyncOptions) (*prepared, error) {
|
||||
cfg, err := LoadClientConfig(opts.ConfigPath)
|
||||
if opts.RepoURL == "" && opts.Ref != "" {
|
||||
return nil, fmt.Errorf("--ref requires --repo (it only overrides the repository to pull)")
|
||||
}
|
||||
cfg, err := resolveRunConfig(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -82,6 +89,33 @@ func prepare(opts SyncOptions) (*prepared, error) {
|
||||
return &prepared{paths: paths, pull: pull, manifest: manifest, items: items, plan: plan}, nil
|
||||
}
|
||||
|
||||
// resolveRunConfig applies the --repo inline override to the config chain:
|
||||
// with --repo, any discovered config only contributes auth (and ref, unless
|
||||
// --ref is also given); without --repo, a config with a repo_url is required.
|
||||
func resolveRunConfig(opts SyncOptions) (*ClientConfig, error) {
|
||||
if opts.RepoURL == "" {
|
||||
cfg, err := LoadClientConfig(opts.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.FillTokenAuth()
|
||||
return cfg, nil
|
||||
}
|
||||
cfg, err := LoadOptionalConfig(opts.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cfg == nil {
|
||||
cfg = &ClientConfig{}
|
||||
}
|
||||
cfg.RepoURL = opts.RepoURL
|
||||
if opts.Ref != "" {
|
||||
cfg.Ref = opts.Ref
|
||||
}
|
||||
cfg.FillTokenAuth()
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// Sync pulls the work repository, plans the sync as a pure function over
|
||||
// (inventory, manifest, disk facts) and executes the plan. Validation and
|
||||
// hashing happen before the first mutation; unreachable repositories fail
|
||||
|
||||
Reference in New Issue
Block a user