mirror of
https://github.com/grdl/git-get.git
synced 2026-03-22 18:05:07 +00:00
Add --skip-host flag to get command (#7)
When set, git-get won't create a directory for the repo host. So instead of `<root>/<host>/<user>/<repo>`, a repo will be cloned into `<root>/<user>/<repo>`. It's useful if all repos some from the same host and that additional folder feels redundant.
This commit is contained in:
committed by
GitHub
parent
0097681f89
commit
0064fc3b8e
@@ -22,6 +22,7 @@ var (
|
||||
KeyDefaultHost = "host"
|
||||
KeyFetch = "fetch"
|
||||
KeyOutput = "out"
|
||||
KeySkipHost = "skip-host"
|
||||
KeyReposRoot = "root"
|
||||
)
|
||||
|
||||
@@ -30,6 +31,7 @@ var Defaults = map[string]string{
|
||||
KeyDefaultHost: "github.com",
|
||||
KeyOutput: OutTree,
|
||||
KeyReposRoot: fmt.Sprintf("~%c%s", filepath.Separator, "repositories"),
|
||||
// KeySkipHost: "false",
|
||||
}
|
||||
|
||||
// Values for the --out flag.
|
||||
@@ -78,6 +80,7 @@ func Init(cfg Gitconfig) {
|
||||
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))
|
||||
@@ -86,6 +89,11 @@ func readGitconfig(cfg Gitconfig) {
|
||||
|
||||
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.
|
||||
|
||||
15
pkg/get.go
15
pkg/get.go
@@ -9,11 +9,12 @@ import (
|
||||
|
||||
// GetCfg provides configuration for the Get command.
|
||||
type GetCfg struct {
|
||||
Branch string
|
||||
DefHost string
|
||||
Dump string
|
||||
Root string
|
||||
URL string
|
||||
Branch string
|
||||
DefHost string
|
||||
Dump string
|
||||
Root string
|
||||
SkipHost bool
|
||||
URL string
|
||||
}
|
||||
|
||||
// Get executes the "git get" command.
|
||||
@@ -40,7 +41,7 @@ func cloneSingleRepo(c *GetCfg) error {
|
||||
|
||||
opts := &git.CloneOpts{
|
||||
URL: url,
|
||||
Path: filepath.Join(c.Root, URLToPath(url)),
|
||||
Path: filepath.Join(c.Root, URLToPath(*url, c.SkipHost)),
|
||||
Branch: c.Branch,
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ func cloneDumpFile(c *GetCfg) error {
|
||||
|
||||
opts := &git.CloneOpts{
|
||||
URL: url,
|
||||
Path: filepath.Join(c.Root, URLToPath(url)),
|
||||
Path: filepath.Join(c.Root, URLToPath(*url, c.SkipHost)),
|
||||
Branch: line.branch,
|
||||
}
|
||||
|
||||
|
||||
39
pkg/url.go
39
pkg/url.go
@@ -2,6 +2,7 @@ package pkg
|
||||
|
||||
import (
|
||||
urlpkg "net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -52,6 +53,12 @@ func ParseURL(rawURL string, defaultHost string) (url *urlpkg.URL, err error) {
|
||||
url.Host = defaultHost
|
||||
}
|
||||
|
||||
// Don't use host when scheme is file://. The fragment detected as url.Host should be a first directory of url.Path
|
||||
if url.Scheme == "file" && url.Host != "" {
|
||||
url.Path = path.Join(url.Host, url.Path)
|
||||
url.Host = ""
|
||||
}
|
||||
|
||||
// Default to https when scheme is empty
|
||||
if url.Scheme == "" {
|
||||
url.Scheme = "https"
|
||||
@@ -60,18 +67,30 @@ func ParseURL(rawURL string, defaultHost string) (url *urlpkg.URL, err error) {
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// URLToPath cleans up the URL and converts it into a path string.
|
||||
// URLToPath cleans up the URL and converts it into a path string with correct separators for the current OS.
|
||||
// Eg, ssh://git@github.com:22/~user/repo.git => github.com/user/repo
|
||||
func URLToPath(url *urlpkg.URL) (repoPath string) {
|
||||
// Remove port numbers from host
|
||||
repoHost := strings.Split(url.Host, ":")[0]
|
||||
//
|
||||
// If skipHost is true, it removes the host part from the path.
|
||||
// Eg, ssh://git@github.com:22/~user/repo.git => user/repo
|
||||
func URLToPath(url urlpkg.URL, skipHost bool) string {
|
||||
// Remove port numbers from host.
|
||||
url.Host = strings.Split(url.Host, ":")[0]
|
||||
|
||||
// Remove trailing ".git" from repo name
|
||||
repoPath = filepath.Join(repoHost, url.Path)
|
||||
repoPath = strings.TrimSuffix(repoPath, ".git")
|
||||
// Remove tilde (~) char from username.
|
||||
url.Path = strings.ReplaceAll(url.Path, "~", "")
|
||||
|
||||
// Remove tilde (~) char from username
|
||||
repoPath = strings.ReplaceAll(repoPath, "~", "")
|
||||
// Remove leading and trailing slashes (correct separator is added by the filepath.Join() below).
|
||||
url.Path = strings.Trim(url.Path, "/")
|
||||
|
||||
return repoPath
|
||||
// Remove trailing ".git" from repo name.
|
||||
url.Path = strings.TrimSuffix(url.Path, ".git")
|
||||
|
||||
// Replace slashes with separator correct for the current OS.
|
||||
url.Path = strings.ReplaceAll(url.Path, "/", string(filepath.Separator))
|
||||
|
||||
if skipHost {
|
||||
url.Host = ""
|
||||
}
|
||||
|
||||
return filepath.Join(url.Host, url.Path)
|
||||
}
|
||||
|
||||
@@ -52,13 +52,58 @@ func TestURLParse(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
url, err := ParseURL(test.in, cfg.Defaults[cfg.KeyDefaultHost])
|
||||
if err != nil {
|
||||
t.Errorf("Error parsing Path: %+v", err)
|
||||
t.Fatalf("got error: %+v", err)
|
||||
}
|
||||
|
||||
got := URLToPath(url)
|
||||
got := URLToPath(*url, false)
|
||||
|
||||
if got != test.want {
|
||||
t.Errorf("Wrong result of parsing Path: %s, got: %s; wantBranch: %s", test.in, got, test.want)
|
||||
t.Errorf("wrong result for %q; expected %q; got %q", test.in, test.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestURLParseSkipHost(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{"ssh://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"ssh://user@github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"ssh://user@github.com:1234/grdl/git-get.git", "grdl/git-get"},
|
||||
{"ssh://user@github.com/~user/grdl/git-get.git", "user/grdl/git-get"},
|
||||
{"git+ssh://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"git@github.com:grdl/git-get.git", "grdl/git-get"},
|
||||
{"git@github.com:/~user/grdl/git-get.git", "user/grdl/git-get"},
|
||||
{"git://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"git://github.com/~user/grdl/git-get.git", "user/grdl/git-get"},
|
||||
{"https://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"http://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"https://github.com/grdl/git-get", "grdl/git-get"},
|
||||
{"https://github.com/git-get.git", "git-get"},
|
||||
{"https://github.com/git-get", "git-get"},
|
||||
{"https://github.com/grdl/sub/path/git-get.git", "grdl/sub/path/git-get"},
|
||||
{"https://github.com:1234/grdl/git-get.git", "grdl/git-get"},
|
||||
{"https://github.com/grdl/git-get.git/", "grdl/git-get"},
|
||||
{"https://github.com/grdl/git-get/", "grdl/git-get"},
|
||||
{"https://github.com/grdl/git-get/////", "grdl/git-get"},
|
||||
{"https://github.com/grdl/git-get.git/////", "grdl/git-get"},
|
||||
{"ftp://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"ftps://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"rsync://github.com/grdl/git-get.git", "grdl/git-get"},
|
||||
{"local/grdl/git-get/", "local/grdl/git-get"},
|
||||
{"file://local/grdl/git-get", "local/grdl/git-get"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
url, err := ParseURL(test.in, cfg.Defaults[cfg.KeyDefaultHost])
|
||||
if err != nil {
|
||||
t.Fatalf("got error: %+v", err)
|
||||
}
|
||||
|
||||
got := URLToPath(*url, true)
|
||||
|
||||
if got != test.want {
|
||||
t.Errorf("wrong result for %q; expected %q; got %q", test.in, test.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,10 +118,10 @@ func TestInvalidURLParse(t *testing.T) {
|
||||
//"git@github.com:1234:grdl/git-get.git",
|
||||
}
|
||||
|
||||
for _, in := range invalidURLs {
|
||||
got, err := ParseURL(in, cfg.Defaults[cfg.KeyDefaultHost])
|
||||
for _, test := range invalidURLs {
|
||||
got, err := ParseURL(test, cfg.Defaults[cfg.KeyDefaultHost])
|
||||
if err == nil {
|
||||
t.Errorf("Wrong result of parsing invalid Path: %s, got: %s, wantBranch: error", in, got)
|
||||
t.Errorf("expected error; got %q", got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user