Files
clip-sync/internal/config/config.go
T
bruno 5655573fc8
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
feat: implémentation complete v0.1.0 — daemon de sync clipboard bidirectionnel
2026-08-08 15:47:22 -04:00

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)
}