Files
HomeAgent/cmd/waiter/config.go

175 lines
3.3 KiB
Go

package main
import (
"fmt"
"os"
"path/filepath"
"gopkg.in/yaml.v3"
)
type Connection struct {
Name string `yaml:"name"`
Socket string `yaml:"socket,omitempty"`
Remote string `yaml:"remote,omitempty"`
APIKey string `yaml:"api_key,omitempty"`
}
type Config struct {
Socket string `yaml:"socket"`
Remote string `yaml:"remote"`
APIKey string `yaml:"api_key"`
Default string `yaml:"default"`
Connections []Connection `yaml:"connections,omitempty"`
}
func (c *Config) Active() *Connection {
for i := range c.Connections {
if c.Connections[i].Name == c.Default {
return &c.Connections[i]
}
}
return nil
}
func (c *Config) ApplyDefault() {
conn := c.Active()
if conn == nil {
return
}
if c.Socket == "" && c.Remote == "" {
c.Socket = conn.Socket
c.Remote = conn.Remote
c.APIKey = conn.APIKey
}
}
func discoverConfig(configPath string) *Config {
if configPath != "" {
if cfg := readFile(configPath); cfg != nil {
return cfg
}
}
candidates := configCandidates()
for _, p := range candidates {
if cfg := readFile(p); cfg != nil {
return cfg
}
}
return &Config{}
}
func configCandidates() []string {
var cands []string
home, _ := os.UserHomeDir()
if home != "" {
cands = append(cands, filepath.Join(home, ".config", "homeagent", "waiter.yaml"))
}
cands = append(cands, "/root/.config/homeagent/waiter.yaml")
cands = append(cands, filepath.Join(".", "waiter.yaml"))
if exe, err := os.Executable(); err == nil {
cands = append(cands, filepath.Join(filepath.Dir(exe), "waiter.yaml"))
}
return cands
}
func configPath() string {
home, _ := os.UserHomeDir()
if home == "" {
return ""
}
return filepath.Join(home, ".config", "homeagent", "waiter.yaml")
}
func readFile(path string) *Config {
data, err := os.ReadFile(path)
if err != nil {
return nil
}
var cfg Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
fmt.Fprintf(os.Stderr, "warning: %s: %v\n", path, err)
return nil
}
return &cfg
}
func (c *Config) Save() {
p := configPath()
if p == "" {
return
}
os.MkdirAll(filepath.Dir(p), 0755)
data, err := yaml.Marshal(c)
if err != nil {
return
}
os.WriteFile(p, data, 0644)
}
func (c *Config) MergeCLI(socket, remote, apiKey string) {
if socket != "" {
c.Socket = socket
}
if remote != "" {
c.Remote = remote
}
if apiKey != "" {
c.APIKey = apiKey
}
}
func (c *Config) SaveConnection(name string) {
conn := Connection{
Name: name,
Socket: c.Socket,
Remote: c.Remote,
APIKey: c.APIKey,
}
for i, existing := range c.Connections {
if existing.Name == name {
c.Connections[i] = conn
c.Default = name
c.Save()
return
}
}
c.Connections = append(c.Connections, conn)
c.Default = name
c.Save()
}
func (c *Config) SwitchConnection(name string) bool {
for _, conn := range c.Connections {
if conn.Name == name {
c.Socket = conn.Socket
c.Remote = conn.Remote
c.APIKey = conn.APIKey
c.Default = name
c.Save()
return true
}
}
return false
}
func (c *Config) DeleteConnection(name string) bool {
for i, conn := range c.Connections {
if conn.Name == name {
c.Connections = append(c.Connections[:i], c.Connections[i+1:]...)
if c.Default == name {
c.Default = ""
}
c.Save()
return true
}
}
return false
}