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) } }