2024-02-22 18:58:58 -07:00
|
|
|
package config
|
2024-02-16 13:21:19 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2024-02-19 13:10:53 -07:00
|
|
|
"strconv"
|
2024-02-16 13:21:19 -07:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/mitchellh/go-homedir"
|
|
|
|
"github.com/sethvargo/go-envconfig"
|
|
|
|
"gopkg.in/ini.v1"
|
|
|
|
)
|
|
|
|
|
2024-02-19 13:10:53 -07:00
|
|
|
const LegacyVersionFileDefault = false
|
|
|
|
const AlwaysKeepDownloadDefault = false
|
|
|
|
const DisablePluginShortNameRepositoryDefault = false
|
|
|
|
const ForcePrependDefault = false
|
|
|
|
const DataDirDefault = "~/.asdf"
|
|
|
|
const ConfigFileDefault = "~/.asdfrc"
|
|
|
|
const DefaultToolVersionsFilenameDefault = ".tool-versions"
|
|
|
|
|
|
|
|
/* Struct to represent the remote plugin repo check duration (never or every N
|
|
|
|
* seconds). It's not clear to me how this should be represented in Golang so
|
|
|
|
* using a struct for maximum flexibility. */
|
|
|
|
type PluginRepoCheckDuration struct {
|
|
|
|
Never bool
|
|
|
|
Every int
|
|
|
|
}
|
|
|
|
|
|
|
|
var PluginRepoCheckDurationDefault = PluginRepoCheckDuration{Every: 60}
|
2024-02-16 13:21:19 -07:00
|
|
|
|
|
|
|
type Settings struct {
|
2024-02-19 13:10:53 -07:00
|
|
|
Loaded bool
|
2024-02-16 13:21:19 -07:00
|
|
|
LegacyVersionFile bool
|
|
|
|
// I don't think this setting should be supported in the Golang implementation
|
|
|
|
//UseReleaseCandidates bool
|
|
|
|
AlwaysKeepDownload bool
|
2024-02-19 13:10:53 -07:00
|
|
|
PluginRepositoryLastCheckDuration PluginRepoCheckDuration
|
2024-02-16 13:21:19 -07:00
|
|
|
DisablePluginShortNameRepository bool
|
|
|
|
}
|
|
|
|
|
|
|
|
type Config struct {
|
|
|
|
Home string
|
2024-02-19 13:10:53 -07:00
|
|
|
ConfigFile string `env:"ASDF_CONFIG_FILE, overwrite"`
|
|
|
|
DefaultToolVersionsFilename string `env:"ASDF_DEFAULT_TOOL_VERSIONS_FILENAME, overwrite"`
|
2024-02-16 13:21:19 -07:00
|
|
|
// Unclear if this value will be needed with the golang implementation.
|
|
|
|
//AsdfDir string
|
2024-02-19 13:10:53 -07:00
|
|
|
DataDir string `env:"ASDF_DATA_DIR, overwrite"`
|
|
|
|
ForcePrepend bool `env:"ASDF_FORCE_PREPEND, overwrite"`
|
|
|
|
// Field that stores the settings struct if it is loaded
|
|
|
|
Settings Settings
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPluginRepoCheckDuration(checkDuration string) PluginRepoCheckDuration {
|
|
|
|
if strings.ToLower(checkDuration) == "never" {
|
|
|
|
return PluginRepoCheckDuration{Never: true}
|
|
|
|
}
|
2024-03-20 18:05:03 -07:00
|
|
|
|
|
|
|
every, err := strconv.Atoi(checkDuration)
|
|
|
|
if err != nil {
|
|
|
|
// if error parsing config use default value
|
|
|
|
return PluginRepoCheckDurationDefault
|
|
|
|
}
|
|
|
|
|
|
|
|
return PluginRepoCheckDuration{Every: every}
|
2024-02-16 13:21:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func LoadConfig() (Config, error) {
|
|
|
|
config, err := loadConfigEnv()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return config, err
|
|
|
|
}
|
|
|
|
|
|
|
|
homeDir, err := homedir.Dir()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return config, err
|
|
|
|
}
|
|
|
|
|
|
|
|
config.Home = homeDir
|
|
|
|
|
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
2024-02-19 13:10:53 -07:00
|
|
|
// Methods on the Config struct that allow it to load and cache values from the
|
|
|
|
// Settings struct, which is loaded from file on disk and therefor somewhat
|
|
|
|
// "expensive".
|
|
|
|
func (c *Config) LegacyVersionFile() (bool, error) {
|
|
|
|
err := c.loadSettings()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.Settings.LegacyVersionFile, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Config) AlwaysKeepDownload() (bool, error) {
|
|
|
|
err := c.loadSettings()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.Settings.AlwaysKeepDownload, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Config) PluginRepositoryLastCheckDuration() (PluginRepoCheckDuration, error) {
|
|
|
|
err := c.loadSettings()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return NewPluginRepoCheckDuration(""), err
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.Settings.PluginRepositoryLastCheckDuration, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Config) DisablePluginShortNameRepository() (bool, error) {
|
|
|
|
err := c.loadSettings()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.Settings.DisablePluginShortNameRepository, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Config) loadSettings() error {
|
|
|
|
if c.Settings.Loaded {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
settings, err := loadSettings(c.ConfigFile)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Settings = settings
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-02-16 13:21:19 -07:00
|
|
|
func loadConfigEnv() (Config, error) {
|
2024-02-19 13:10:53 -07:00
|
|
|
dataDir, err := homedir.Expand(DataDirDefault)
|
|
|
|
if err != nil {
|
|
|
|
return Config{}, err
|
|
|
|
}
|
2024-02-16 13:21:19 -07:00
|
|
|
|
2024-02-19 13:10:53 -07:00
|
|
|
configFile, err := homedir.Expand(ConfigFileDefault)
|
|
|
|
if err != nil {
|
|
|
|
return Config{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
config := Config{
|
|
|
|
ForcePrepend: ForcePrependDefault,
|
|
|
|
DataDir: dataDir,
|
|
|
|
ConfigFile: configFile,
|
|
|
|
DefaultToolVersionsFilename: DefaultToolVersionsFilenameDefault,
|
|
|
|
}
|
|
|
|
|
|
|
|
context := context.Background()
|
|
|
|
err = envconfig.Process(context, &config)
|
2024-02-16 13:21:19 -07:00
|
|
|
|
|
|
|
return config, err
|
|
|
|
}
|
|
|
|
|
2024-02-19 13:10:53 -07:00
|
|
|
func loadSettings(asdfrcPath string) (Settings, error) {
|
2024-02-16 13:21:19 -07:00
|
|
|
// asdfrc is effectively formatted as ini
|
|
|
|
config, err := ini.Load(asdfrcPath)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return Settings{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
mainConf := config.Section("")
|
2024-02-19 13:10:53 -07:00
|
|
|
checkDuration := NewPluginRepoCheckDuration(mainConf.Key("plugin_repository_last_check_duration").String())
|
2024-02-16 13:21:19 -07:00
|
|
|
|
|
|
|
return Settings{
|
2024-02-19 13:10:53 -07:00
|
|
|
Loaded: true,
|
|
|
|
LegacyVersionFile: yesNoToBool(mainConf, "legacy_version_file", LegacyVersionFileDefault),
|
|
|
|
AlwaysKeepDownload: yesNoToBool(mainConf, "use_release_candidates", AlwaysKeepDownloadDefault),
|
2024-02-16 13:21:19 -07:00
|
|
|
PluginRepositoryLastCheckDuration: checkDuration,
|
2024-02-19 13:10:53 -07:00
|
|
|
DisablePluginShortNameRepository: yesNoToBool(mainConf, "disable_plugin_short_name_repository", DisablePluginShortNameRepositoryDefault),
|
2024-02-16 13:21:19 -07:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2024-02-19 13:10:53 -07:00
|
|
|
func yesNoToBool(section *ini.Section, key string, defaultValue bool) bool {
|
2024-02-16 13:21:19 -07:00
|
|
|
yesOrNo := section.Key(key).String()
|
|
|
|
lcYesOrNo := strings.ToLower(yesOrNo)
|
|
|
|
if lcYesOrNo == "yes" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if lcYesOrNo == "no" {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return defaultValue
|
|
|
|
}
|