git: support all git transports

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi
2018-05-28 21:15:05 -07:00
parent 8b131af00d
commit 1067c24df2
5 changed files with 43 additions and 12 deletions

View File

@@ -141,7 +141,19 @@ type ImageInfo struct {
}
func Git(remote, ref string, opts ...GitOption) State {
url := ""
for _, prefix := range []string{
"http://", "https://", "git://", "git@",
} {
if strings.HasPrefix(remote, prefix) {
url = strings.Split(remote, "#")[0]
remote = strings.TrimPrefix(remote, prefix)
}
}
id := remote
if ref != "" {
id += "#" + ref
}
@@ -154,6 +166,9 @@ func Git(remote, ref string, opts ...GitOption) State {
if gi.KeepGitDir {
attrs[pb.AttrKeepGitDir] = "true"
}
if url != "" {
attrs[pb.AttrFullRemoteURL] = url
}
source := NewSource("git://"+id, attrs, gi.Metadata())
return NewState(source.Output())
}

View File

@@ -26,11 +26,11 @@ const (
dockerignoreFilename = ".dockerignore"
buildArgPrefix = "build-arg:"
labelPrefix = "label:"
gitPrefix = "git://"
keyNoCache = "no-cache"
)
var httpPrefix = regexp.MustCompile("^https?://")
var gitUrlPathWithFragmentSuffix = regexp.MustCompile(".git(?:#.+)?$")
func Build(ctx context.Context, c client.Client) error {
opts := c.Opts()
@@ -55,12 +55,10 @@ func Build(ctx context.Context, c client.Client) error {
llb.SharedKeyHint(defaultDockerfileName),
)
var buildContext *llb.State
if strings.HasPrefix(opts[LocalNameContext], gitPrefix) {
src = parseGitSource(opts[LocalNameContext])
if st, ok := detectGitContext(opts[LocalNameContext]); ok {
src = *st
buildContext = &src
}
if httpPrefix.MatchString(opts[LocalNameContext]) {
} else if httpPrefix.MatchString(opts[LocalNameContext]) {
unpack := llb.Image(dockerfile2llb.CopyImage).Run(llb.Shlex("copy --unpack /src/context /out/"), llb.ReadonlyRootFS())
unpack.AddMount("/src", llb.HTTP(opts[LocalNameContext], llb.Filename("context")), llb.Readonly)
src = unpack.AddMount("/out", llb.Scratch())
@@ -196,12 +194,27 @@ func filter(opt map[string]string, key string) map[string]string {
return m
}
func parseGitSource(ref string) llb.State {
ref = strings.TrimPrefix(ref, gitPrefix)
func detectGitContext(ref string) (*llb.State, bool) {
found := false
if httpPrefix.MatchString(ref) && gitUrlPathWithFragmentSuffix.MatchString(ref) {
found = true
}
for _, prefix := range []string{"git://", "github.com/", "git@"} {
if strings.HasPrefix(ref, prefix) {
found = true
break
}
}
if !found {
return nil, false
}
parts := strings.SplitN(ref, "#", 2)
branch := ""
if len(parts) > 1 {
branch = parts[1]
}
return llb.Git(parts[0], branch)
st := llb.Git(parts[0], branch)
return &st, true
}

View File

@@ -1387,7 +1387,7 @@ COPY --from=build foo bar2
)
require.NoError(t, err)
server := httptest.NewServer(http.FileServer(http.Dir(filepath.Join(gitDir, ".git"))))
server := httptest.NewServer(http.FileServer(http.Dir(filepath.Join(gitDir))))
defer server.Close()
destDir, err := ioutil.TempDir("", "buildkit")
@@ -1401,7 +1401,7 @@ COPY --from=build foo bar2
_, err = c.Solve(context.TODO(), nil, client.SolveOpt{
Frontend: "dockerfile.v0",
FrontendAttrs: map[string]string{
"context": "git://" + server.URL + "/#first",
"context": server.URL + "/.git#first",
},
Exporter: client.ExporterLocal,
ExporterOutputDir: destDir,
@@ -1424,7 +1424,7 @@ COPY --from=build foo bar2
_, err = c.Solve(context.TODO(), nil, client.SolveOpt{
Frontend: "dockerfile.v0",
FrontendAttrs: map[string]string{
"context": "git://" + server.URL + "/",
"context": server.URL + "/.git",
},
Exporter: client.ExporterLocal,
ExporterOutputDir: destDir,

View File

@@ -1,6 +1,7 @@
package pb
const AttrKeepGitDir = "git.keepgitdir"
const AttrFullRemoteURL = "git.fullurl"
const AttrLocalSessionID = "local.session"
const AttrIncludePatterns = "local.includepattern"
const AttrExcludePatterns = "local.excludepatterns"

View File

@@ -62,6 +62,8 @@ func FromLLB(op *pb.Op_Source) (Identifier, error) {
if v == "true" {
id.KeepGitDir = true
}
case pb.AttrFullRemoteURL:
id.Remote = v
}
}
}