mirror of
https://github.com/grdl/git-get.git
synced 2026-02-16 16:40:17 +00:00
Enable accessing config from gitconfig file or env variables
This commit is contained in:
@@ -8,8 +8,6 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ReposRoot = "/tmp/gitget"
|
|
||||||
|
|
||||||
var cmd = &cobra.Command{
|
var cmd = &cobra.Command{
|
||||||
Use: "git-get <repo>",
|
Use: "git-get <repo>",
|
||||||
Short: "git get",
|
Short: "git get",
|
||||||
@@ -19,14 +17,14 @@ var cmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
//cmd.PersistentFlags().
|
pkg.LoadConf()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(cmd *cobra.Command, args []string) {
|
func Run(cmd *cobra.Command, args []string) {
|
||||||
url, err := pkg.ParseURL(args[0])
|
url, err := pkg.ParseURL(args[0])
|
||||||
exitIfError(err)
|
exitIfError(err)
|
||||||
|
|
||||||
_, err = pkg.CloneRepo(url, ReposRoot, false)
|
_, err = pkg.CloneRepo(url, pkg.Cfg.ReposRoot(), false)
|
||||||
exitIfError(err)
|
exitIfError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -4,6 +4,7 @@ go 1.14
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-git/go-git/v5 v5.1.0
|
github.com/go-git/go-git/v5 v5.1.0
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
)
|
)
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -1,4 +1,5 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
|
|||||||
113
pkg/config.go
Normal file
113
pkg/config.go
Normal 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
146
pkg/config_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,11 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
testUser = "Test User"
|
||||||
|
testEmail = "testuser@example.com"
|
||||||
|
)
|
||||||
|
|
||||||
func newRepoEmpty(t *testing.T) *Repo {
|
func newRepoEmpty(t *testing.T) *Repo {
|
||||||
dir := newTempDir(t)
|
dir := newTempDir(t)
|
||||||
|
|
||||||
@@ -162,8 +167,8 @@ func (r *Repo) newCommit(t *testing.T, msg string) {
|
|||||||
|
|
||||||
opts := &git.CommitOptions{
|
opts := &git.CommitOptions{
|
||||||
Author: &object.Signature{
|
Author: &object.Signature{
|
||||||
Name: "Some Guy",
|
Name: testUser,
|
||||||
Email: "someguy@example.com",
|
Email: testEmail,
|
||||||
When: time.Date(2000, 01, 01, 16, 00, 00, 0, time.UTC),
|
When: time.Date(2000, 01, 01, 16, 00, 00, 0, time.UTC),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user