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 }