Files
talk/internal/config/path.go
T

65 lines
1.8 KiB
Go
Raw Permalink Normal View History

package config
import (
"errors"
"path/filepath"
"runtime"
)
// fileName is the config file's name inside the config directory.
const fileName = "config.toml"
// ErrNoHome reports that the home directory cannot be determined (no HOME or
// APPDATA environment variable).
var ErrNoHome = errors.New("config directory unknown (HOME or APPDATA not set)")
// Dir returns talk's platform-native config directory: ~/.config/talk on
// Linux (or $XDG_CONFIG_HOME/talk), ~/Library/Application Support/talk on
// macOS, %APPDATA%\talk on Windows.
func Dir(getenv func(string) string) (string, error) {
return dirFor(runtime.GOOS, getenv)
}
// dirFor is the testable platform logic behind Dir: goos is a parameter so
// all platforms can be table-tested from one host.
//
// XDG_CONFIG_HOME is honoured only when it holds an absolute path (XDG
// spec); relative values are ignored.
func dirFor(goos string, getenv func(string) string) (string, error) {
if getenv == nil {
return "", ErrNoHome
}
switch goos {
case "windows":
appdata := getenv("APPDATA")
if appdata == "" {
return "", ErrNoHome
}
return filepath.Join(appdata, "talk"), nil
case "darwin":
home := getenv("HOME")
if home == "" {
return "", ErrNoHome
}
return filepath.Join(home, "Library", "Application Support", "talk"), nil
default: // linux and other unix-likes
if xdg := getenv("XDG_CONFIG_HOME"); xdg != "" && filepath.IsAbs(xdg) {
return filepath.Join(xdg, "talk"), nil
}
home := getenv("HOME")
if home == "" {
return "", ErrNoHome
}
return filepath.Join(home, ".config", "talk"), nil
}
}
// Path returns the full path of config.toml in the config directory
// (diagnostics, setup).
func Path(getenv func(string) string) (string, error) {
dir, err := Dir(getenv)
if err != nil {
return "", err
}
return filepath.Join(dir, fileName), nil
}