Skip to content

Commit

Permalink
Introduce simple git cloner.
Browse files Browse the repository at this point in the history
  • Loading branch information
monopole committed Nov 22, 2018
1 parent c51646e commit d9ba209
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pkg/loader/fileloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (l *fileLoader) Root() string {

func newLoaderOrDie(fSys fs.FileSystem, path string) *fileLoader {
l, err := newFileLoaderAt(
path, fSys, []string{}, hashicorpGitCloner)
path, fSys, []string{}, clonerToUse())
if err != nil {
log.Fatalf("unable to make loader at '%s'; %v", path, err)
}
Expand Down
70 changes: 60 additions & 10 deletions pkg/loader/gitcloner.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package loader

import (
"bytes"
"github.com/pkg/errors"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"

Expand All @@ -35,22 +38,69 @@ type gitCloner func(url string) (
// Any error encountered when cloning.
err error)

// isRepoUrl checks if a string is a repo Url
func isRepoUrl(s string) bool {
if strings.HasPrefix(s, "https://") {
return true
}
if strings.HasPrefix(s, "git::") {
return true
}
host := strings.SplitN(s, "/", 2)[0]
return strings.Contains(host, ".com") || strings.Contains(host, ".org")
// isRepoUrl checks if a string is likely a github repo Url.
func isRepoUrl(arg string) bool {
arg = strings.ToLower(arg)
return !filepath.IsAbs(arg) &&
(strings.HasPrefix(arg, "git::") ||
strings.HasPrefix(arg, "gh:") ||
strings.HasPrefix(arg, "github.com") ||
strings.HasPrefix(arg, "git@github.com:") ||
strings.Index(arg, "github.com/") > -1)
}

func makeTmpDir() (string, error) {
return ioutil.TempDir("", "kustomize-")
}

func simpleGitCloner(spec string) (
checkoutDir string, pathInCoDir string, err error) {
gitProgram, err := exec.LookPath("git")
if err != nil {
return "", "", errors.Wrap(err, "no 'git' program on path")
}
checkoutDir, err = makeTmpDir()
if err != nil {
return
}
url, pathInCoDir, err := extractGithubRepoName(spec)
cmd := exec.Command(gitProgram, "clone", url, checkoutDir)
var out bytes.Buffer
cmd.Stdout = &out
err = cmd.Run()
if err != nil {
return "", "", errors.Wrapf(err, "trouble cloning %s", spec)
}
return
}

// From strings like git@github.com:someOrg/someRepo.git or
// https://github.com/someOrg/someRepo, extract path.
func extractGithubRepoName(n string) (string, string, error) {
for _, p := range []string{
// Order matters here.
"git::", "gh:", "https://", "http://",
"git@", "github.com:", "github.com/", "gitlab.com/"} {
if strings.ToLower(n[:len(p)]) == p {
n = n[len(p):]
}
}
if strings.HasSuffix(n, ".git") {
n = n[0 : len(n)-len(".git")]
}
i := strings.Index(n, string(filepath.Separator))
if i < 1 {
return "", "", errors.New("no separator")
}
j := strings.Index(n[i+1:], string(filepath.Separator))
if j < 0 {
// No path, so show entire repo.
return n, "", nil
}
j += i + 1
return n[:j], n[j+1:], nil
}

func hashicorpGitCloner(repoUrl string) (
checkoutDir string, pathInCoDir string, err error) {
dir, err := makeTmpDir()
Expand Down
59 changes: 59 additions & 0 deletions pkg/loader/gitcloner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package loader

import (
"fmt"
"path/filepath"
"strings"
"testing"

Expand All @@ -38,6 +40,14 @@ func TestIsRepoURL(t *testing.T) {
input: "github.com/org/repo",
expected: true,
},
{
input: "git@github.com:org/repo",
expected: true,
},
{
input: "gh:org/repo",
expected: true,
},
{
input: "git::https://gitlab.com/org/repo",
expected: true,
Expand Down Expand Up @@ -168,3 +178,52 @@ whatever
coRoot+"/"+pathInRepo, l2.Root())
}
}

var repoNames = []string{"someOrg/someRepo", "kubernetes/website"}

var paths = []string{"", "README.md", "foo/index.md"}

var extractFmts = []string{
"gh:%s",
"GH:%s",
"gitHub.com/%s",
"https://github.com/%s",
"hTTps://github.com/%s",
"git::https://gitlab.com/%s",
"git@gitHUB.com:%s.git",
"github.com:%s",
}

func TestExtractGithubRepoName(t *testing.T) {
for _, repoName := range repoNames {
for _, pathName := range paths {
for _, extractFmt := range extractFmts {
spec := repoName
if len(pathName) > 0 {
spec = filepath.Join(spec, pathName)
}
input := fmt.Sprintf(extractFmt, spec)
if !isRepoUrl(input) {
t.Errorf("Should smell like github arg: %s\n", input)
continue
}
repo, path, err := extractGithubRepoName(input)
if err != nil {
t.Errorf("problem %v", err)
}
if repo != repoName {
t.Errorf("\n"+
" from %s\n"+
" gotRepo %s\n"+
"desiredRepo %s\n", input, repo, repoName)
}
if path != pathName {
t.Errorf("\n"+
" from %s\n"+
" gotPath %s\n"+
"desiredPath %s\n", input, path, pathName)
}
}
}
}
}
15 changes: 13 additions & 2 deletions pkg/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,23 @@ import (
"sigs.k8s.io/kustomize/pkg/ifc"
)

const useHashiCorpCloner = true

func clonerToUse() gitCloner {
if useHashiCorpCloner {
return hashicorpGitCloner
}
return simpleGitCloner
}

// var clonerToUse = simpleGitCloner

// NewLoader returns a Loader.
func NewLoader(root string, fSys fs.FileSystem) (ifc.Loader, error) {
if isRepoUrl(root) {
return newGitLoader(
root, fSys, []string{}, hashicorpGitCloner)
root, fSys, []string{}, clonerToUse())
}
return newFileLoaderAt(
root, fSys, []string{}, hashicorpGitCloner)
root, fSys, []string{}, clonerToUse())
}

0 comments on commit d9ba209

Please sign in to comment.