CI / Lint (push) Failing after 14m46s
CI / Test (push) Failing after 4m23s
CI / Build (darwin/amd64) (push) Skipped
CI / Build (linux/amd64) (push) Skipped
CI / Build (windows/amd64) (push) Skipped
CI / Build (darwin/arm64) (push) Skipped
CI / Build (linux/arm64) (push) Skipped
CI / Build (windows/arm64) (push) Skipped
CI / Release (push) Skipped
99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
// Package config parses the clip-sync TOML configuration file and applies
|
|
// environment variable overrides.
|
|
//
|
|
// Config file location: ~/.config/clip-sync/peers.toml
|
|
// Environment overrides:
|
|
// CLIP_SYNC_PORT — override daemon.port
|
|
// CLIP_SYNC_POLL_MS — override daemon.poll_interval_ms
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
// Config represents the full clip-sync configuration.
|
|
type Config struct {
|
|
Daemon DaemonConfig `toml:"daemon"`
|
|
Peers []PeerConfig `toml:"peers"`
|
|
}
|
|
|
|
// DaemonConfig holds daemon-level settings.
|
|
type DaemonConfig struct {
|
|
Port int `toml:"port"`
|
|
PollIntervalMs int `toml:"poll_interval_ms"`
|
|
}
|
|
|
|
// PeerConfig represents one remote clip-sync peer.
|
|
type PeerConfig struct {
|
|
Name string `toml:"name"`
|
|
Addr string `toml:"addr"`
|
|
}
|
|
|
|
// Default values.
|
|
const (
|
|
DefaultPort = 9137
|
|
DefaultPollIntervalMs = 500
|
|
ConfigDir = ".config/clip-sync"
|
|
ConfigFile = "peers.toml"
|
|
)
|
|
|
|
// Load reads the config file from ~/.config/clip-sync/peers.toml and applies
|
|
// environment variable overrides.
|
|
func Load() (*Config, error) {
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("config: cannot find home directory: %w", err)
|
|
}
|
|
|
|
cfgPath := filepath.Join(home, ConfigDir, ConfigFile)
|
|
|
|
cfg := &Config{
|
|
Daemon: DaemonConfig{
|
|
Port: DefaultPort,
|
|
PollIntervalMs: DefaultPollIntervalMs,
|
|
},
|
|
}
|
|
|
|
if _, err := toml.DecodeFile(cfgPath, cfg); err != nil {
|
|
if !os.IsNotExist(err) {
|
|
return nil, fmt.Errorf("config: cannot parse %s: %w", cfgPath, err)
|
|
}
|
|
// File doesn't exist — use defaults (no peers configured).
|
|
}
|
|
|
|
// Environment variable overrides.
|
|
if v := os.Getenv("CLIP_SYNC_PORT"); v != "" {
|
|
port, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("config: invalid CLIP_SYNC_PORT: %w", err)
|
|
}
|
|
cfg.Daemon.Port = port
|
|
}
|
|
|
|
if v := os.Getenv("CLIP_SYNC_POLL_MS"); v != "" {
|
|
ms, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("config: invalid CLIP_SYNC_POLL_MS: %w", err)
|
|
}
|
|
cfg.Daemon.PollIntervalMs = ms
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
// PollInterval returns the poll interval as a time.Duration.
|
|
func (c *Config) PollInterval() time.Duration {
|
|
return time.Duration(c.Daemon.PollIntervalMs) * time.Millisecond
|
|
}
|
|
|
|
// ListenAddr returns the HTTP listen address for this daemon.
|
|
func (c *Config) ListenAddr() string {
|
|
return fmt.Sprintf(":%d", c.Daemon.Port)
|
|
}
|