package main import ( "encoding/json" "fmt" "os" "path/filepath" ) type AppConfig struct { Storage struct { AppDataDir string `json:"app_data_dir"` InstallDir string `json:"install_dir"` InstancesDir string `json:"instances_dir"` BackupDir string `json:"backup_dir"` ConfigTemplatesDir string `json:"config_templates_dir"` } `json:"storage"` Daemon struct { ListenAddress string `json:"listen_address"` } Instances map[string]VsServerConfigOptions `json:"instances"` } func CreateConfigWithDefaults(configPath string) *AppConfig { home, _ := os.UserHomeDir() basePath := filepath.Join(home, ".local", "share", "vssm") cfg := &AppConfig{} cfg.Storage.AppDataDir = basePath cfg.Storage.InstallDir = filepath.Join(basePath, "installs") cfg.Storage.InstancesDir = filepath.Join(basePath, "instances") cfg.Storage.BackupDir = filepath.Join(basePath, "backups") cfg.Storage.ConfigTemplatesDir = filepath.Join(basePath, "config_templates") cfg.Daemon.ListenAddress = "127.0.0.1:12345" cfg.Instances = make(map[string]VsServerConfigOptions) return cfg } func LoadOrCreateConfig(configPath string) (*AppConfig, error) { if _, err := os.Stat(configPath); os.IsNotExist(err) { cfg := CreateConfigWithDefaults(configPath) if err := os.MkdirAll(filepath.Dir(configPath), 0755); err != nil { return nil, fmt.Errorf("Failed to create config directory: %w", err) } data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return nil, err } if err := os.WriteFile(configPath, data, 0644); err != nil { return nil, fmt.Errorf("Failed to write config file at %s\n", configPath) } } data, err := os.ReadFile(configPath) if err != nil { return nil, err } var cfg AppConfig if err := json.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("Invalid JSON layout in config file: %w", err) } dirs := []string{ cfg.Storage.AppDataDir, cfg.Storage.InstallDir, cfg.Storage.InstancesDir, cfg.Storage.BackupDir, cfg.Storage.ConfigTemplatesDir, } for _, dir := range dirs { if err := os.MkdirAll(dir, 0755); err != nil { return nil, fmt.Errorf("Failed creating workspace directory %s: %w", dir, err) } } return &cfg, nil }