Add TOML config file support to mcrctl
Loads defaults from ~/.config/mcrctl.toml (or XDG_CONFIG_HOME). Resolution order: flag > env (MCR_TOKEN) > config file. Adds --config flag to specify an explicit path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
91
cmd/mcrctl/config_test.go
Normal file
91
cmd/mcrctl/config_test.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadConfigExplicitPath(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "mcrctl.toml")
|
||||
data := []byte(`server = "https://reg.example.com"
|
||||
grpc = "reg.example.com:9443"
|
||||
token = "file-token"
|
||||
ca_cert = "/path/to/ca.pem"
|
||||
`)
|
||||
if err := os.WriteFile(path, data, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg, err := loadConfig(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg.Server != "https://reg.example.com" {
|
||||
t.Errorf("Server = %q, want %q", cfg.Server, "https://reg.example.com")
|
||||
}
|
||||
if cfg.GRPC != "reg.example.com:9443" {
|
||||
t.Errorf("GRPC = %q, want %q", cfg.GRPC, "reg.example.com:9443")
|
||||
}
|
||||
if cfg.Token != "file-token" {
|
||||
t.Errorf("Token = %q, want %q", cfg.Token, "file-token")
|
||||
}
|
||||
if cfg.CACert != "/path/to/ca.pem" {
|
||||
t.Errorf("CACert = %q, want %q", cfg.CACert, "/path/to/ca.pem")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigMissingDefaultIsOK(t *testing.T) {
|
||||
// Empty path triggers default search; missing file is not an error.
|
||||
cfg, err := loadConfig("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Server != "" || cfg.GRPC != "" || cfg.Token != "" {
|
||||
t.Errorf("expected zero config from missing default, got %+v", cfg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigMissingExplicitIsError(t *testing.T) {
|
||||
_, err := loadConfig("/nonexistent/mcrctl.toml")
|
||||
if err == nil {
|
||||
t.Fatal("expected error for missing explicit config path")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigInvalidTOML(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "bad.toml")
|
||||
if err := os.WriteFile(path, []byte("not valid [[[ toml"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err := loadConfig(path)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for invalid TOML")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigPartial(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "mcrctl.toml")
|
||||
data := []byte(`server = "https://reg.example.com"
|
||||
`)
|
||||
if err := os.WriteFile(path, data, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg, err := loadConfig(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg.Server != "https://reg.example.com" {
|
||||
t.Errorf("Server = %q, want %q", cfg.Server, "https://reg.example.com")
|
||||
}
|
||||
if cfg.GRPC != "" {
|
||||
t.Errorf("GRPC should be empty, got %q", cfg.GRPC)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user