Files
Poulpe 610ec13b19 feat(v0.2.0): config UI panel + folder picker + S3 bucket lister/tester
- Panel Reglages dans l'UI (modal)
- Folder picker natif Wails pour dossier local
- ListS3Buckets via aws-cli (profile-aware)
- TestS3Access pour verifier acces bucket
- Config persistee user config dir (cross-OS): %APPDATA%/field-sync ou ~/.config/field-sync
- Header affiche bucket + dest visibles
- Auto-open modal si bucket vide au premier run

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 22:08:22 +00:00

90 lines
1.9 KiB
Go

package config
import (
"encoding/json"
"os"
"path/filepath"
"strconv"
"github.com/joho/godotenv"
)
// Config holds runtime configuration
type Config struct {
S3Bucket string `json:"s3Bucket"`
LocalDest string `json:"localDest"`
AWSProfile string `json:"awsProfile"`
Concurrency int `json:"concurrency"`
}
// Path returns the cross-OS config file path
func Path() string {
dir, _ := os.UserConfigDir()
return filepath.Join(dir, "field-sync", "config.json")
}
// Save writes config to disk (atomic)
func Save(cfg Config) error {
p := Path()
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
return err
}
data, _ := json.MarshalIndent(cfg, "", " ")
tmp := p + ".tmp"
if err := os.WriteFile(tmp, data, 0644); err != nil {
return err
}
return os.Rename(tmp, p)
}
// LoadFromFile reads from JSON config file (no .env)
func LoadFromFile() Config {
data, err := os.ReadFile(Path())
if err != nil {
return Config{AWSProfile: "cosma", Concurrency: 4, LocalDest: defaultLocalDest()}
}
var c Config
json.Unmarshal(data, &c)
if c.Concurrency == 0 {
c.Concurrency = 4
}
if c.AWSProfile == "" {
c.AWSProfile = "cosma"
}
if c.LocalDest == "" {
c.LocalDest = defaultLocalDest()
}
return c
}
func defaultLocalDest() string {
home, _ := os.UserHomeDir()
return filepath.Join(home, "field-sync-data")
}
// Load reads config from ENV (with optional .env file) — kept for compat
func Load(envFile string) Config {
_ = godotenv.Load(envFile) // ignore if missing
concurrency := 4
if v := os.Getenv("FIELD_SYNC_CONCURRENCY"); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 {
concurrency = n
}
}
return Config{
S3Bucket: getenv("FIELD_SYNC_S3_BUCKET", ""),
LocalDest: getenv("FIELD_SYNC_LOCAL_DEST", os.TempDir()),
AWSProfile: getenv("AWS_PROFILE", "cosma"),
Concurrency: concurrency,
}
}
func getenv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}