a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
package agents
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
toml "github.com/pelletier/go-toml/v2"
|
|
)
|
|
|
|
// MergeTOML is the TOML cousin of MergeJSON: read an existing
|
|
// TOML file (if any), pass the decoded map to mutate, and write
|
|
// back atomically when mutate reports a change. Used by the Codex
|
|
// CLI adapter — Codex config lives in ~/.codex/config.toml and no
|
|
// other adapter currently needs TOML support.
|
|
//
|
|
// Malformed TOML is preserved as a .bak sibling before we
|
|
// overwrite, same policy as MergeJSON.
|
|
func MergeTOML(w io.Writer, path string, mutate func(root map[string]any, existed bool) (changed bool, err error), opts ApplyOpts) (FileAction, error) {
|
|
existed := false
|
|
root := make(map[string]any)
|
|
var backupPath string
|
|
|
|
if data, err := os.ReadFile(path); err == nil {
|
|
existed = true
|
|
if err := toml.Unmarshal(data, &root); err != nil {
|
|
backupPath = path + ".bak"
|
|
_ = os.WriteFile(backupPath, data, 0o644)
|
|
root = make(map[string]any)
|
|
}
|
|
} else if !errors.Is(err, os.ErrNotExist) {
|
|
return FileAction{}, fmt.Errorf("read %s: %w", path, err)
|
|
}
|
|
|
|
changed, err := mutate(root, existed)
|
|
if err != nil {
|
|
return FileAction{}, err
|
|
}
|
|
if !changed {
|
|
return FileAction{Path: path, Action: ActionSkip, Reason: "already-configured"}, nil
|
|
}
|
|
|
|
keys := sortedMapKeys(root)
|
|
|
|
if opts.DryRun {
|
|
action := ActionWouldCreate
|
|
if existed {
|
|
action = ActionWouldMerge
|
|
}
|
|
return FileAction{Path: path, Action: action, Keys: keys}, nil
|
|
}
|
|
|
|
out, err := toml.Marshal(root)
|
|
if err != nil {
|
|
return FileAction{}, fmt.Errorf("marshal %s: %w", path, err)
|
|
}
|
|
if err := AtomicWriteFile(path, out, 0o644); err != nil {
|
|
return FileAction{}, err
|
|
}
|
|
|
|
action := ActionCreate
|
|
if existed {
|
|
action = ActionMerge
|
|
}
|
|
if backupPath != "" {
|
|
logf(w, "[gortex init] %s was malformed TOML; backup saved to %s", path, backupPath)
|
|
}
|
|
logf(w, "[gortex init] %s %s", actionVerb(action), path)
|
|
return FileAction{Path: path, Action: action, Keys: keys}, nil
|
|
}
|