refactor: move V1 code into v1/ subdirectory
- git mv cmd/ internal/ pkg/ test/ go.mod go.sum Makefile build.sh docs/ v1/ - Create v1/README.md with V1 documentation - Update root README for V1 + V2 structure - V1 still builds (cd v1 && go build ./cmd/hostkeeper) and 105 tests pass - Root is now clean for V2 development
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"git.tukangketik.id/swanadiva/hostkeeper/internal/models"
|
||||
)
|
||||
|
||||
// Config manages application configuration and paths
|
||||
type Config struct {
|
||||
appName string
|
||||
configDir string
|
||||
dataDir string
|
||||
appConfig *models.AppConfig
|
||||
}
|
||||
|
||||
// New creates a new Config instance
|
||||
func New() (*Config, error) {
|
||||
appName := "hostkeeper"
|
||||
|
||||
configDir, err := getConfigDir(appName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get config directory: %w", err)
|
||||
}
|
||||
|
||||
dataDir := filepath.Join(configDir, "data")
|
||||
|
||||
c := &Config{
|
||||
appName: appName,
|
||||
configDir: configDir,
|
||||
dataDir: dataDir,
|
||||
}
|
||||
|
||||
// Create directories
|
||||
if err := os.MkdirAll(configDir, 0700); err != nil {
|
||||
return nil, fmt.Errorf("failed to create config directory: %w", err)
|
||||
}
|
||||
if err := os.MkdirAll(dataDir, 0700); err != nil {
|
||||
return nil, fmt.Errorf("failed to create data directory: %w", err)
|
||||
}
|
||||
|
||||
// Load or create config
|
||||
if err := c.load(); err != nil {
|
||||
return nil, fmt.Errorf("failed to load config: %w", err)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// getConfigDir returns the OS-appropriate config directory for the app
|
||||
func getConfigDir(appName string) (string, error) {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(home, "Library", "Application Support", appName), nil
|
||||
case "linux":
|
||||
if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" {
|
||||
return filepath.Join(xdg, appName), nil
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(home, ".config", appName), nil
|
||||
case "windows":
|
||||
appData := os.Getenv("APPDATA")
|
||||
if appData != "" {
|
||||
return filepath.Join(appData, appName), nil
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(home, "AppData", "Roaming", appName), nil
|
||||
default:
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(home, "."+appName), nil
|
||||
}
|
||||
}
|
||||
|
||||
// load reads the config file, or creates a default one if it doesn't exist
|
||||
func (c *Config) load() error {
|
||||
configPath := c.GetConfigFilePath()
|
||||
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Create default config
|
||||
c.appConfig = models.DefaultConfig()
|
||||
return c.Save()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
c.appConfig = models.DefaultConfig()
|
||||
if err := json.Unmarshal(data, c.appConfig); err != nil {
|
||||
return fmt.Errorf("failed to parse config: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save writes the current configuration to disk
|
||||
func (c *Config) Save() error {
|
||||
configPath := c.GetConfigFilePath()
|
||||
|
||||
data, err := json.MarshalIndent(c.appConfig, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal config: %w", err)
|
||||
}
|
||||
|
||||
return os.WriteFile(configPath, data, 0600)
|
||||
}
|
||||
|
||||
// GetAppConfig returns the application configuration
|
||||
func (c *Config) GetAppConfig() *models.AppConfig {
|
||||
return c.appConfig
|
||||
}
|
||||
|
||||
// UpdateAppConfig updates the application configuration
|
||||
func (c *Config) UpdateAppConfig(cfg *models.AppConfig) error {
|
||||
c.appConfig = cfg
|
||||
return c.Save()
|
||||
}
|
||||
|
||||
// GetConfigDir returns the configuration directory path
|
||||
func (c *Config) GetConfigDir() string {
|
||||
return c.configDir
|
||||
}
|
||||
|
||||
// GetDataDir returns the data directory path
|
||||
func (c *Config) GetDataDir() string {
|
||||
return c.dataDir
|
||||
}
|
||||
|
||||
// GetConfigFilePath returns the full path to the config JSON file
|
||||
func (c *Config) GetConfigFilePath() string {
|
||||
return filepath.Join(c.configDir, "config.json")
|
||||
}
|
||||
|
||||
// GetHostsFilePath returns the full path to the hosts JSON file
|
||||
func (c *Config) GetHostsFilePath() string {
|
||||
return filepath.Join(c.dataDir, "hosts.json")
|
||||
}
|
||||
|
||||
// GetKeysFilePath returns the full path to the keys JSON file
|
||||
func (c *Config) GetKeysFilePath() string {
|
||||
return filepath.Join(c.dataDir, "keys.json")
|
||||
}
|
||||
|
||||
// GetSnippetsFilePath returns the full path to the snippets JSON file
|
||||
func (c *Config) GetSnippetsFilePath() string {
|
||||
return filepath.Join(c.dataDir, "snippets.json")
|
||||
}
|
||||
Reference in New Issue
Block a user