113 lines
2.9 KiB
Go
113 lines
2.9 KiB
Go
package figures
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
const (
|
|
CONFIG_DIR_PERMS = 0o755
|
|
CONFIG_FILE_PERMS = 0o600
|
|
)
|
|
|
|
var ConfigFileNotFoundErr = errors.New("config file for provided path not found")
|
|
|
|
// fileExists checks if a file exists at a given path
|
|
func fileExists(path string) bool {
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
type figuration struct {
|
|
applicationName string
|
|
}
|
|
|
|
// NewFiguration creates a new figuration for the provided application
|
|
func NewFiguration(applicationName string) figuration {
|
|
return figuration{
|
|
applicationName: applicationName,
|
|
}
|
|
}
|
|
|
|
// GetConfigFilePath returns the path of a given file within the UserConfigDir.
|
|
func (fig figuration) GetConfigFilePath(filename string) (string, error) {
|
|
configDir, err := os.UserConfigDir()
|
|
if err != nil {
|
|
return "", fmt.Errorf("error getting current config: %w", err)
|
|
}
|
|
|
|
// Get or make config dir path
|
|
configDir = filepath.Join(configDir, fig.applicationName)
|
|
_ = os.MkdirAll(configDir, CONFIG_DIR_PERMS)
|
|
|
|
// Get the path to the provided file name within the config directory
|
|
configFilePath := filepath.Join(configDir, filename)
|
|
|
|
return configFilePath, err
|
|
}
|
|
|
|
// ReadConfig populates a provided struct with the data in config file of a given name
|
|
func (fig figuration) ReadConfig(name string, data interface{}) error {
|
|
configPath, err := fig.GetConfigFilePath(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !fileExists(configPath) {
|
|
return fmt.Errorf("error reading config from file %s: %w", name, ConfigFileNotFoundErr)
|
|
}
|
|
|
|
content, err := ioutil.ReadFile(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("error reading config from file: %w", err)
|
|
}
|
|
|
|
err = json.Unmarshal(content, data)
|
|
if err != nil {
|
|
return fmt.Errorf("failed parsing json from config file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// WriteConfig writes data from the provided struct to the config file with the provided name
|
|
func (fig figuration) WriteConfig(name string, data interface{}) error {
|
|
configPath, err := fig.GetConfigFilePath(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
contents, err := json.Marshal(data)
|
|
if err != nil {
|
|
return fmt.Errorf("failed converting config to json: %w", err)
|
|
}
|
|
|
|
if err = ioutil.WriteFile(configPath, contents, CONFIG_FILE_PERMS); err != nil {
|
|
return fmt.Errorf("error writing config to file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type Config interface {
|
|
ApplicationName() string
|
|
Filename() string
|
|
}
|
|
|
|
// ReadConfig populates the provided struct matching the Config interface with config values from the user's config store
|
|
func ReadConfig(config Config) error {
|
|
return NewFiguration(config.ApplicationName()).ReadConfig(config.Filename(), config)
|
|
}
|
|
|
|
// WriteConfig writes the provided struct matching the Config interface to the users config store
|
|
func WriteConfig(config Config) error {
|
|
return NewFiguration(config.ApplicationName()).WriteConfig(config.Filename(), config)
|
|
}
|