// Package cfg represents the overall wem application configuration.
package cfg
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/pelletier/go-toml"
)
const WemName = "wem"
const WemVersion = "0.8.3"
type WemConfig struct {
CacheDir string
ProtonDir string
WineBuildDir string
WineEnvDir string
WineSrcDir string
}
func (w *WemConfig) ApplyArgs(cacheDir, protonDir, wineBuildDir, wineEnvDir, wineSrcDir string) {
if cacheDir != "" {
w.CacheDir = cacheDir
}
if protonDir != "" {
w.ProtonDir = protonDir
}
if wineBuildDir != "" {
w.WineBuildDir = wineBuildDir
}
if wineEnvDir != "" {
w.WineEnvDir = wineEnvDir
}
if wineSrcDir != "" {
w.WineSrcDir = wineSrcDir
}
}
func (w *WemConfig) AsToml() (string, error) {
b, err := toml.Marshal(w)
if err != nil {
return "", err
}
return string(b), nil
}
// EnsureDirs ensures that all dirs defined in
// the config exist, creating them as needed.
func (w *WemConfig) EnsureDirs() error {
for _, dirPath := range []string{w.CacheDir, w.ProtonDir, w.WineBuildDir, w.WineEnvDir, w.WineSrcDir} {
_, err := os.Stat(dirPath)
if err != nil {
err = os.MkdirAll(dirPath, 0755)
if err != nil {
return err
}
}
}
return nil
}
// Validate indicates if there are any missing config options.
func (w *WemConfig) Validate() error {
if w.CacheDir == "" {
return errors.New("CacheDir is not set")
}
if w.ProtonDir == "" {
return errors.New("ProtonDir is not set")
}
if w.WineBuildDir == "" {
return errors.New("WineBuildDir is not set")
}
if w.WineEnvDir == "" {
return errors.New("WineEnvDir is not set")
}
if w.WineSrcDir == "" {
return errors.New("WineSrcDir is not set")
}
return nil
}
func defaultWemConfig() string {
c := fmt.Sprintf(`# Full path to the directory where archives should be cached to.
CacheDir = "%s/.local/share/wem/cache"
# Full path to the directory where Proton installations should go.
ProtonDir = "%s/.local/share/wem/proton"
# Full path to the directory where wem-built wine installations should go.
WineBuildDir = "%s/.local/share/wem/builds"
# Full path to the directory where wem envs will be created by default.
WineEnvDir = "%s/.local/share/wem/envs"
# Full path to the directory where wine source code is kept.
WineSrcDir = "%s/.local/share/wem/src"
`, os.Getenv("HOME"), os.Getenv("HOME"), os.Getenv("HOME"), os.Getenv("HOME"), os.Getenv("HOME"))
return c
}
func CfgDir() string {
return filepath.Join(os.Getenv("HOME"), ".config", "wem")
}
func GetConfig() (*WemConfig, error) {
cfgPath := filepath.Join(CfgDir(), "wem.cfg")
_, err := os.Stat(cfgPath)
if err != nil {
err = os.MkdirAll(filepath.Dir(cfgPath), 0755)
if err != nil {
return nil, err
}
f, err := os.Create(cfgPath)
if err != nil {
return nil, err
}
defer f.Close()
// We do this instead of toml.Marshal()ing a struct because
// it's nice to provide comments in the config file.
f.WriteString(defaultWemConfig())
}
c, err := ioutil.ReadFile(cfgPath)
if err != nil {
return nil, err
}
cfgStr := os.ExpandEnv(string(c))
wc := &WemConfig{}
toml.Unmarshal([]byte(cfgStr), wc)
err = wc.Validate()
if err == nil {
return wc, nil
}
return nil, err
}