mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-13 01:50:55 +00:00
Introduce simple git cloner.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,11 @@ limitations under the License.
|
||||
package loader
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/pkg/errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package loader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -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,
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user