147 lines
3.0 KiB
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)
|
||
|
}
|
||
|
}
|