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

Enable accessing config from gitconfig file or env variables

This commit is contained in:
Grzegorz Dlugoszewski
2020-05-29 21:19:55 +02:00
parent b72f984512
commit 1798816b6a
6 changed files with 270 additions and 6 deletions

113
pkg/config.go Normal file
View File

@@ -0,0 +1,113 @@
package pkg
import (
"os"
"path"
"strings"
"github.com/go-git/go-git/v5/config"
plumbing "github.com/go-git/go-git/v5/plumbing/format/config"
"github.com/mitchellh/go-homedir"
)
const (
CfgSection = "gitget"
CfgReposRoot = "reposRoot"
CfgDefaultHost = "defaultHost"
EnvReposRoot = "GITGET_REPOSROOT"
EnvDefaultHost = "GITGET_DEFAULTHOST"
DefaultReposRootSubpath = "repositories"
DefaultHost = "github.com"
)
var Cfg *Conf
// Conf provides methods for accessing configuration values
// Values are looked up in the following order: env variable, gitignore file, default value
type Conf struct {
gitconfig *config.Config
}
func LoadConf() {
// We don't care if loading gitconfig file throws an error
// When gitconfig is nil, getters will just return the default values
gitconfig, _ := config.LoadConfig(config.GlobalScope)
Cfg = &Conf{
gitconfig: gitconfig,
}
}
func (c *Conf) ReposRoot() string {
defReposRoot := path.Join(home(), DefaultReposRootSubpath)
reposRoot := os.Getenv(EnvReposRoot)
if reposRoot != "" {
return reposRoot
}
if c.gitconfig == nil {
return defReposRoot
}
gitget := c.findConfigSection(CfgSection)
if gitget == nil {
return defReposRoot
}
reposRoot = gitget.Option(CfgReposRoot)
reposRoot = strings.TrimSpace(reposRoot)
if reposRoot == "" {
return defReposRoot
}
return reposRoot
}
func (c *Conf) DefaultHost() string {
defaultHost := os.Getenv(EnvDefaultHost)
if defaultHost != "" {
return defaultHost
}
if c.gitconfig == nil {
return DefaultHost
}
gitget := c.findConfigSection(CfgSection)
if gitget == nil {
return DefaultHost
}
defaultHost = gitget.Option(CfgDefaultHost)
defaultHost = strings.TrimSpace(defaultHost)
if defaultHost == "" {
return DefaultHost
}
return defaultHost
}
func (c *Conf) findConfigSection(name string) *plumbing.Section {
for _, s := range c.gitconfig.Raw.Sections {
if s.Name == name {
return s
}
}
return nil
}
// home returns path to a home directory or empty string if can't be found
// Using empty string means that in the unlikely situation where home dir can't be found
// and there's no reposRoot specified in the global config, the current dir will be used as repos root.
func home() string {
home, err := homedir.Dir()
if err != nil {
return ""
}
return home
}

146
pkg/config_test.go Normal file
View File

@@ -0,0 +1,146 @@
package pkg
import (
"os"
"path"
"testing"
"github.com/go-git/go-git/v5/config"
)
func newConfigWithFullGitconfig() *Conf {
gitconfig := config.NewConfig()
gitget := gitconfig.Raw.Section(CfgSection)
gitget.AddOption(CfgReposRoot, "file.root")
gitget.AddOption(CfgDefaultHost, "file.host")
return &Conf{
gitconfig: gitconfig,
}
}
func newConfigWithEmptyGitgetSection() *Conf {
gitconfig := config.NewConfig()
_ = gitconfig.Raw.Section(CfgSection)
return &Conf{
gitconfig: gitconfig,
}
}
func newConfigWithEmptyValues() *Conf {
gitconfig := config.NewConfig()
gitget := gitconfig.Raw.Section(CfgSection)
gitget.AddOption(CfgReposRoot, "")
gitget.AddOption(CfgDefaultHost, " ")
return &Conf{
gitconfig: gitconfig,
}
}
func newConfigWithoutGitgetSection() *Conf {
gitconfig := config.NewConfig()
return &Conf{
gitconfig: gitconfig,
}
}
func newConfigWithEmptyGitconfig() *Conf {
return &Conf{
gitconfig: nil,
}
}
func newConfigWithEnvVars() *Conf {
_ = os.Setenv(EnvDefaultHost, "env.host")
_ = os.Setenv(EnvReposRoot, "env.root")
return &Conf{
gitconfig: nil,
}
}
func newConfigWithGitconfigAndEnvVars() *Conf {
gitconfig := config.NewConfig()
gitget := gitconfig.Raw.Section(CfgSection)
gitget.AddOption(CfgReposRoot, "file.root")
gitget.AddOption(CfgDefaultHost, "file.host")
_ = os.Setenv(EnvDefaultHost, "env.host")
_ = os.Setenv(EnvReposRoot, "env.root")
return &Conf{
gitconfig: gitconfig,
}
}
func newConfigWithEmptySectionAndEnvVars() *Conf {
gitconfig := config.NewConfig()
_ = gitconfig.Raw.Section(CfgSection)
_ = os.Setenv(EnvDefaultHost, "env.host")
_ = os.Setenv(EnvReposRoot, "env.root")
return &Conf{
gitconfig: gitconfig,
}
}
func newConfigWithMixed() *Conf {
gitconfig := config.NewConfig()
gitget := gitconfig.Raw.Section(CfgSection)
gitget.AddOption(CfgReposRoot, "file.root")
gitget.AddOption(CfgDefaultHost, "file.host")
_ = os.Setenv(EnvDefaultHost, "env.host")
return &Conf{
gitconfig: gitconfig,
}
}
func TestConfig(t *testing.T) {
defReposRoot := path.Join(home(), DefaultReposRootSubpath)
var tests = []struct {
makeConfig func() *Conf
wantReposRoot string
wantDefaultHost string
}{
{newConfigWithFullGitconfig, "file.root", "file.host"},
{newConfigWithoutGitgetSection, defReposRoot, DefaultHost},
{newConfigWithEmptyGitconfig, defReposRoot, DefaultHost},
{newConfigWithEnvVars, "env.root", "env.host"},
{newConfigWithGitconfigAndEnvVars, "env.root", "env.host"},
{newConfigWithEmptySectionAndEnvVars, "env.root", "env.host"},
{newConfigWithEmptyGitgetSection, defReposRoot, DefaultHost},
{newConfigWithEmptyValues, defReposRoot, DefaultHost},
{newConfigWithMixed, "file.root", "env.host"},
}
for _, test := range tests {
cfg := test.makeConfig()
if cfg.ReposRoot() != test.wantReposRoot {
t.Errorf("Wrong reposRoot value, got: %+v; want: %+v", cfg.ReposRoot(), test.wantReposRoot)
}
if cfg.DefaultHost() != test.wantDefaultHost {
t.Errorf("Wrong defaultHost value, got: %+v; want: %+v", cfg.DefaultHost(), test.wantDefaultHost)
}
// Unset env variables after each test so they don't affect other tests
err := os.Unsetenv(EnvDefaultHost)
checkFatal(t, err)
err = os.Unsetenv(EnvReposRoot)
checkFatal(t, err)
}
}

View File

@@ -14,6 +14,11 @@ import (
"github.com/pkg/errors"
)
const (
testUser = "Test User"
testEmail = "testuser@example.com"
)
func newRepoEmpty(t *testing.T) *Repo {
dir := newTempDir(t)
@@ -162,8 +167,8 @@ func (r *Repo) newCommit(t *testing.T, msg string) {
opts := &git.CommitOptions{
Author: &object.Signature{
Name: "Some Guy",
Email: "someguy@example.com",
Name: testUser,
Email: testEmail,
When: time.Date(2000, 01, 01, 16, 00, 00, 0, time.UTC),
},
}