6
0
mirror of https://github.com/grdl/git-get.git synced 2026-02-04 18:34:51 +00:00
Files
git-get/pkg/cfg/config.go

107 lines
3.0 KiB
Go

// Package cfg provides common configuration to all commands.
// It contains config key names, default values and provides methods to read values from global gitconfig file.
package cfg
import (
"bytes"
"fmt"
"path/filepath"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
)
// GitgetPrefix is the name of the gitconfig section name and the env var prefix.
const GitgetPrefix = "gitget"
// CLI flag keys.
var (
KeyBranch = "branch"
KeyDump = "dump"
KeyDefaultHost = "host"
KeyFetch = "fetch"
KeyOutput = "out"
KeyDefaultScheme = "scheme"
KeySkipHost = "skip-host"
KeyReposRoot = "root"
)
// Defaults is a map of default values for config keys.
var Defaults = map[string]string{
KeyDefaultHost: "github.com",
KeyOutput: OutTree,
KeyReposRoot: fmt.Sprintf("~%c%s", filepath.Separator, "repositories"),
KeyDefaultScheme: "ssh",
}
// Values for the --out flag.
const (
OutDump = "dump"
OutFlat = "flat"
OutTree = "tree"
)
// AllowedOut are allowed values for the --out flag.
var AllowedOut = []string{OutDump, OutFlat, OutTree}
// Version metadata set by ldflags during the build.
var (
version string
commit string
date string
)
// Version returns a string with version metadata: version number, git sha and build date.
// It returns "development" if version variables are not set during the build.
func Version() string {
if version == "" {
return "development"
}
return fmt.Sprintf("%s - revision %s built at %s", version, commit[:6], date)
}
// Gitconfig represents gitconfig file
type Gitconfig interface {
Get(key string) string
}
// Init initializes viper config registry. Values are looked up in the following order: cli flag, env variable, gitconfig file, default value.
func Init(cfg Gitconfig) {
readGitconfig(cfg)
viper.SetEnvPrefix(strings.ToUpper(GitgetPrefix))
viper.AutomaticEnv()
}
// readGitConfig loads values from gitconfig file into viper's registry.
// Viper doesn't support the gitconfig format so we load it using "git config --global" command and populate a temporary "env" string,
// which is then feed to Viper.
func readGitconfig(cfg Gitconfig) {
var lines []string
// TODO: Can we somehow iterate over all possible flags?
for key := range Defaults {
if val := cfg.Get(fmt.Sprintf("%s.%s", GitgetPrefix, key)); val != "" {
lines = append(lines, fmt.Sprintf("%s=%s", key, val))
}
}
viper.SetConfigType("env")
viper.ReadConfig(bytes.NewBuffer([]byte(strings.Join(lines, "\n"))))
// TODO: A hacky way to read boolean flag from gitconfig. Find a cleaner way.
if val := cfg.Get(fmt.Sprintf("%s.%s", GitgetPrefix, KeySkipHost)); strings.ToLower(val) == "true" {
viper.Set(KeySkipHost, true)
}
}
// Expand applies the variables expansion to a viper config of given key.
// If expansion fails or is not needed, the config is not modified.
func Expand(key string) {
if expanded, err := homedir.Expand(viper.GetString(key)); err == nil {
viper.Set(key, expanded)
}
}