mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-09-02 07:07:26 -04:00
Switch config format from ini to json (drop ini dependency since json is now used for syncing)
This commit is contained in:
+82
@@ -0,0 +1,82 @@
|
||||
package cfg
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/rwinkhart/libmutton/global"
|
||||
)
|
||||
|
||||
type CfgT struct {
|
||||
Libmutton struct {
|
||||
OfflineMode *bool `json:"offlineMode"`
|
||||
SSHUser *string `json:"sshUser"`
|
||||
SSHIP *string `json:"sshIP"`
|
||||
SSHPort *string `json:"sshPort"`
|
||||
SSHEntryRootPath *string `json:"sshEntryRootPath"`
|
||||
SSHAgeDirPath *string `json:"sshAgeDirPath"`
|
||||
SSHKeyPath *string `json:"sshKeyPath"`
|
||||
SSHKeyProtected *bool `json:"sshKeyProtected"`
|
||||
SSHIsWindows *bool `json:"sshIsWindows"`
|
||||
} `json:"libmutton"`
|
||||
ThirdParty *map[string]any `json:"thirdParty"`
|
||||
}
|
||||
|
||||
// LoadConfig loads libmuttoncfg.json and returns the configuration.
|
||||
func LoadConfig() (*CfgT, error) {
|
||||
cfgBytes, err := os.ReadFile(global.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to load libmuttoncfg.json: " + err.Error())
|
||||
}
|
||||
var cfg CfgT
|
||||
err = json.Unmarshal(cfgBytes, &cfg)
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to unmarshal libmuttoncfg.json: " + err.Error())
|
||||
}
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// WriteConfig writes cfg to libmuttoncfg.json.
|
||||
// If used in append mode, any nil values in the
|
||||
// input cfg will be substituted with the existing values.
|
||||
func WriteConfig(cfg *CfgT, appendMode bool) error {
|
||||
if appendMode {
|
||||
// check if any fields are nil
|
||||
var hasNilFields bool
|
||||
cfgValue := reflect.ValueOf(&cfg.Libmutton).Elem()
|
||||
for i := 0; i < cfgValue.NumField(); i++ {
|
||||
field := cfgValue.Field(i)
|
||||
if field.IsNil() {
|
||||
hasNilFields = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// load old cfg and copy nil fields
|
||||
if hasNilFields {
|
||||
oldCfg, err := LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oldValue := reflect.ValueOf(&oldCfg.Libmutton).Elem()
|
||||
for i := 0; i < cfgValue.NumField(); i++ {
|
||||
field := cfgValue.Field(i)
|
||||
if field.IsNil() {
|
||||
field.Set(oldValue.Field(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cfgBytes, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil {
|
||||
return errors.New("unable to marshal new/updated cfg: " + err.Error())
|
||||
}
|
||||
err = os.WriteFile(global.ConfigPath, cfgBytes, 0600)
|
||||
if err != nil {
|
||||
return errors.New("unable to write new/updated cfg to libmuttoncfg.json: " + err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package cfg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/rwinkhart/libmutton/global"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
// loadConfig loads the libmutton.ini file and returns the configuration.
|
||||
// It is a utility function for ParseConfig and WriteConfig; do not call directly.
|
||||
func loadConfig() (*ini.File, error) {
|
||||
cfg, err := ini.Load(global.ConfigPath)
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to load libmutton.ini: " + err.Error())
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// ParseConfig reads the libmutton.ini file and returns a slice of values for the specified keys.
|
||||
// Requires: valuesRequested (a slice of length 2 arrays each containing a section and a key name).
|
||||
// Returns: config (slice of values for the specified keys).
|
||||
// If requesting SSH config, request "LIBMUTTON/offlineMode" first to avoid errors.
|
||||
func ParseConfig(valuesRequested [][2]string) ([]string, error) {
|
||||
cfg, err := loadConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config []string
|
||||
for _, pair := range valuesRequested {
|
||||
value := cfg.Section(pair[0]).Key(pair[1]).String()
|
||||
// ensure specified key has a value
|
||||
if value == "" {
|
||||
return nil, fmt.Errorf("unable to find value for key \"%s\" in section \"[%s]\" in libmutton.ini", pair[1], pair[0])
|
||||
}
|
||||
config = append(config, value)
|
||||
|
||||
// notify requester immediately if in offline mode
|
||||
if pair[1] == "offlineMode" && pair[0] == "LIBMUTTON" && value == "true" {
|
||||
return config, nil
|
||||
}
|
||||
}
|
||||
|
||||
return config, err
|
||||
}
|
||||
|
||||
// WriteConfig writes the provided key-value pairs under the specified section headers in the libmutton.ini file.
|
||||
// Requires: valuesToWrite (a slice of length 3 arrays each containing a section, a key name, and a value),
|
||||
// prune (a slice similar to valuesToWrite to allow removing the specified keys from an existing config),
|
||||
// append (set to true to append to the existing libmutton.ini file, false to overwrite it).
|
||||
func WriteConfig(valuesToWrite [][3]string, keysToPrune [][2]string, append bool) error {
|
||||
var cfg *ini.File
|
||||
var err error
|
||||
|
||||
if append {
|
||||
// load existing ini file
|
||||
cfg, err = loadConfig()
|
||||
if err != nil {
|
||||
return errors.New("unable to load existing libmutton.ini: " + err.Error())
|
||||
}
|
||||
} else {
|
||||
// create empty ini container
|
||||
cfg = ini.Empty()
|
||||
}
|
||||
|
||||
// set all specified key-value pairs in their respective sections
|
||||
var section *ini.Section
|
||||
for _, trio := range valuesToWrite {
|
||||
if cfg.Section(trio[0]) == nil {
|
||||
// create and acquire section if it doesn't exist
|
||||
section, _ = cfg.NewSection(trio[0])
|
||||
} else {
|
||||
// acquire existing section
|
||||
section = cfg.Section(trio[0])
|
||||
}
|
||||
|
||||
// set key-value pair
|
||||
section.Key(trio[1]).SetValue(trio[2])
|
||||
}
|
||||
|
||||
// prune specified keys from the existing config
|
||||
if append && len(keysToPrune) > 0 {
|
||||
// remove specified keys pairs from the existing config
|
||||
for _, pair := range keysToPrune {
|
||||
cfg.Section(pair[0]).DeleteKey(pair[1])
|
||||
}
|
||||
}
|
||||
|
||||
// save to libmutton.ini
|
||||
setUmask(0077) // only give permissions to owner
|
||||
err = cfg.SaveTo(global.ConfigPath)
|
||||
if err != nil {
|
||||
return errors.New("unable to save libmutton.ini: " + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
//go:build !windows
|
||||
|
||||
package cfg
|
||||
|
||||
import "syscall"
|
||||
|
||||
// setUmask sets the file mode creation mask (umask) for the current process.
|
||||
// The call to syscall.Umask needs to be embedded in another function to allow
|
||||
// compilation on Windows.
|
||||
func setUmask(umask int) {
|
||||
syscall.Umask(umask)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package cfg
|
||||
|
||||
// setUmask is a dummy function on Windows.
|
||||
func setUmask(umask int) {
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user