Something went wrong. Try again.
An unofficial terminal client for Tangled, optimized for humans and agents. tgcli.wisp.place
cli atproto go tangled
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119package cli
import ( "errors" "fmt" "os" "path/filepath" "strings"
"github.com/spf13/viper")
const ( defaultAppview = "https://api.tangled.org" configName = "config" configType = "toml")
// config resolves values with the following precedence (highest to lowest):// command-line flags, environment variables prefixed TG_, config file, defaults.type settings struct { FosterKnot string Appview string Account string Knot string SSHPort string Protocol string}
type flagSettings struct { FosterKnot string FosterKnotSet bool ConfigPath string Appview string Account string ConfigSet bool AppviewSet bool AccountSet bool}
func loadConfig(flags flagSettings) (settings, error) { config := viper.NewWithOptions(viper.KeyDelimiter(".")) configPath := flags.ConfigPath explicitConfig := flags.ConfigSet if !explicitConfig && configPath == "" { configPath = os.Getenv("TG_CONFIG") explicitConfig = configPath != "" } config.SetConfigName(configName) config.SetConfigType(configType)
if configPath != "" { config.SetConfigFile(configPath) } else { for _, dir := range configSearchDirs() { config.AddConfigPath(dir) } }
config.SetEnvPrefix("TG") config.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) config.AutomaticEnv() config.SetDefault("appview", defaultAppview) config.SetDefault("foster-knot", "") config.SetDefault("account", "") config.SetDefault("knot", "") config.SetDefault("ssh-port", "22") config.SetDefault("protocol", "ssh")
if err := config.ReadInConfig(); err != nil { if _, ok := errors.AsType[viper.ConfigFileNotFoundError](err); ok { if explicitConfig { return settings{}, fmt.Errorf("read config %q: %w", configPath, err) } return applyFlagSettings(settings{ Appview: config.GetString("appview"), FosterKnot: config.GetString("foster-knot"), Account: config.GetString("account"), Knot: config.GetString("knot"), SSHPort: config.GetString("ssh-port"), Protocol: config.GetString("protocol"), }, flags), nil } return settings{}, fmt.Errorf("read config: %w", err) } resolved := settings{ Appview: config.GetString("appview"), FosterKnot: config.GetString("foster-knot"), Account: config.GetString("account"), Knot: config.GetString("knot"), SSHPort: config.GetString("ssh-port"), Protocol: config.GetString("protocol"), } return applyFlagSettings(resolved, flags), nil}
func applyFlagSettings(resolved settings, flags flagSettings) settings { if flags.FosterKnotSet { resolved.FosterKnot = flags.FosterKnot } if flags.AppviewSet { resolved.Appview = flags.Appview } if flags.AccountSet { resolved.Account = flags.Account } return resolved}
func configSearchDirs() []string { var dirs []string if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" { dirs = append(dirs, filepath.Join(xdg, "tg")) } else if home, err := os.UserHomeDir(); err == nil { dirs = append(dirs, filepath.Join(home, ".config", "tg")) } return dirs}