gpm/config/config.go

147 lines
3.0 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"path"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/pelletier/go-toml"
"go.jolheiser.com/beaver"
)
var Version = "develop"
type Config struct {
path string
GPMURL string `toml:"gpm-url" json:"gpm_url"`
Packages Packages `toml:"package" json:"packages"`
}
type Package struct {
Name string `toml:"name" json:"name"`
Import string `toml:"import" json:"import"`
}
type Packages []Package
func Load() (*Config, error) {
home, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("could not get user home dir: %v", err)
}
home = path.Join(home, ".gpm")
homeEnv := os.Getenv("GPM_HOME")
if homeEnv != "" {
home = homeEnv
}
configPath := path.Join(home, "gpm.toml")
configEnv := os.Getenv("GPM_CONFIG")
if configEnv != "" {
configPath = configEnv
}
if _, err := os.Stat(configPath); os.IsNotExist(err) {
if err := os.MkdirAll(path.Dir(configPath), os.ModePerm); err != nil {
return nil, fmt.Errorf("could not create gpm home: %v", err)
}
if _, err := os.Create(configPath); err != nil {
return nil, fmt.Errorf("could not create gpm config: %v", err)
}
}
var cfg Config
tree, err := toml.LoadFile(configPath)
if err != nil {
return nil, fmt.Errorf("could not decode gpm config: %v", err)
}
if err = tree.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("could not unmarshal config: %v", err)
}
dupe := make(map[string]bool)
for _, pkg := range cfg.Packages {
name := strings.ToLower(pkg.Name)
if ok := dupe[name]; ok {
return nil, fmt.Errorf("duplicate package for %s", pkg.Name)
}
dupe[name] = true
}
cfg.path = configPath
return &cfg, nil
}
func (c *Config) Save() error {
fi, err := os.Create(c.path)
if err != nil {
return err
}
defer fi.Close()
if err := toml.NewEncoder(fi).Encode(c); err != nil {
return err
}
return nil
}
func (c *Config) Export() (string, error) {
data, err := json.Marshal(c.Packages)
return string(data), err
}
func (p Packages) Slice() []string {
pkgs := make([]string, len(p))
for idx, pkg := range p {
pkgs[idx] = fmt.Sprintf("%s (%s)", pkg.Name, pkg.Import)
}
return pkgs
}
func (p Packages) Map() map[string]Package {
pkgs := make(map[string]Package)
for _, pkg := range p {
pkgs[pkg.Name] = pkg
}
return pkgs
}
func (c *Config) AddPackages(force bool, pkgs ...Package) {
for _, pkg := range pkgs {
for idx, p := range c.Packages {
if strings.EqualFold(p.Name, pkg.Name) {
if force {
c.Packages[idx] = pkg
break
}
forceQuestion := &survey.Confirm{
Message: fmt.Sprintf("Package `%s` (%s) already exists. Overwrite with `%s`?", p.Name, p.Import, p.Import),
Default: false,
}
var forceAnswer bool
if err := survey.AskOne(forceQuestion, &forceAnswer); err != nil {
beaver.Error(err)
break
}
if !forceAnswer {
beaver.Errorf("leaving package `%s` as-is", pkg.Name)
break
}
c.Packages[idx] = pkg
break
}
}
c.Packages = append(c.Packages, pkg)
}
}