Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions frontend/dockerfile/builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
keyNameContext = "contextkey"
keyNameDockerfile = "dockerfilekey"
keyContextSubDir = "contextsubdir"
keyContextKeepGitDir = "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR"
)

var httpPrefix = regexp.MustCompile(`^https?://`)
Expand Down Expand Up @@ -129,7 +130,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) {

var buildContext *llb.State
isScratchContext := false
if st, ok := detectGitContext(opts[localNameContext]); ok {
if st, ok := detectGitContext(opts[localNameContext], opts[keyContextKeepGitDir]); ok {
if !forceLocalDockerfile {
src = *st
}
Expand Down Expand Up @@ -451,12 +452,19 @@ func filter(opt map[string]string, key string) map[string]string {
return m
}

func detectGitContext(ref string) (*llb.State, bool) {
func detectGitContext(ref, gitContext string) (*llb.State, bool) {
found := false
if httpPrefix.MatchString(ref) && gitUrlPathWithFragmentSuffix.MatchString(ref) {
found = true
}

keepGit := false
if gitContext != "" {
if v, err := strconv.ParseBool(gitContext); err == nil {
keepGit = v
}
}

for _, prefix := range []string{"git://", "github.com/", "git@"} {
if strings.HasPrefix(ref, prefix) {
found = true
Expand All @@ -472,7 +480,12 @@ func detectGitContext(ref string) (*llb.State, bool) {
if len(parts) > 1 {
branch = parts[1]
}
st := llb.Git(parts[0], branch, dockerfile2llb.WithInternalName("load git source "+ref))
gitOpts := []llb.GitOption{dockerfile2llb.WithInternalName("load git source " + ref)}
if keepGit {
gitOpts = append(gitOpts, llb.KeepGitDir())
}

st := llb.Git(parts[0], branch, gitOpts...)
return &st, true
}

Expand Down
26 changes: 21 additions & 5 deletions source/git/gitsource.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ type gitSourceHandler struct {
cacheKey string
}

func (gs *gitSourceHandler) shaToCacheKey(sha string) string {
key := sha
if gs.src.KeepGitDir {
key += ".git"
}
return key
}

func (gs *gitSource) Resolve(ctx context.Context, id source.Identifier, _ *session.Manager) (source.SourceInstance, error) {
gitIdentifier, ok := id.(*source.GitIdentifier)
if !ok {
Expand All @@ -175,6 +183,7 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, index int) (string, bo
defer gs.locker.Unlock(remote)

if isCommitSHA(ref) {
ref = gs.shaToCacheKey(ref)
gs.cacheKey = ref
return ref, true, nil
}
Expand All @@ -201,6 +210,7 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, index int) (string, bo
if !isCommitSHA(sha) {
return "", false, errors.Errorf("invalid commit sha %q", sha)
}
sha = gs.shaToCacheKey(sha)
gs.cacheKey = sha
return sha, true, nil
}
Expand Down Expand Up @@ -298,11 +308,15 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context) (out cache.ImmutableRe
}()

if gs.src.KeepGitDir {
_, err = gitWithinDir(ctx, checkoutDir, "", "init")
checkoutDirGit := filepath.Join(checkoutDir, ".git")
if err := os.MkdirAll(checkoutDir, 0711); err != nil {
return nil, err
}
_, err = gitWithinDir(ctx, checkoutDirGit, "", "init")
if err != nil {
return nil, err
}
_, err = gitWithinDir(ctx, checkoutDir, "", "remote", "add", "origin", gitDir)
_, err = gitWithinDir(ctx, checkoutDirGit, "", "remote", "add", "origin", gitDir)
if err != nil {
return nil, err
}
Expand All @@ -313,16 +327,18 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context) (out cache.ImmutableRe
if err != nil {
return nil, err
}
} else {
pullref += ":" + pullref
}
_, err = gitWithinDir(ctx, checkoutDir, "", "fetch", "--depth=1", "origin", pullref)
_, err = gitWithinDir(ctx, checkoutDirGit, "", "fetch", "-u", "--depth=1", "origin", pullref)
if err != nil {
return nil, err
}
_, err = gitWithinDir(ctx, checkoutDir, checkoutDir, "checkout", "FETCH_HEAD")
_, err = gitWithinDir(ctx, checkoutDirGit, checkoutDir, "checkout", "FETCH_HEAD")
if err != nil {
return nil, errors.Wrapf(err, "failed to checkout remote %s", gs.src.Remote)
}
gitDir = checkoutDir
gitDir = checkoutDirGit
} else {
_, err = gitWithinDir(ctx, gitDir, checkoutDir, "checkout", ref, "--", ".")
if err != nil {
Expand Down
23 changes: 19 additions & 4 deletions source/git/gitsource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ func testRepeatedFetch(t *testing.T, keepGitDir bool) {
require.NoError(t, err)
require.True(t, done)

require.Equal(t, 40, len(key1))
expLen := 40
if keepGitDir {
expLen += 4
}

require.Equal(t, expLen, len(key1))

ref1, err := g.Snapshot(ctx)
require.NoError(t, err)
Expand Down Expand Up @@ -171,7 +176,12 @@ func testFetchBySHA(t *testing.T, keepGitDir bool) {
require.NoError(t, err)
require.True(t, done)

require.Equal(t, 40, len(key1))
expLen := 40
if keepGitDir {
expLen += 4
}

require.Equal(t, expLen, len(key1))

ref1, err := g.Snapshot(ctx)
require.NoError(t, err)
Expand Down Expand Up @@ -244,13 +254,18 @@ func testMultipleRepos(t *testing.T, keepGitDir bool) {
g2, err := gs.Resolve(ctx, id2, nil)
require.NoError(t, err)

expLen := 40
if keepGitDir {
expLen += 4
}

key1, _, err := g.CacheKey(ctx, 0)
require.NoError(t, err)
require.Equal(t, 40, len(key1))
require.Equal(t, expLen, len(key1))

key2, _, err := g2.CacheKey(ctx, 0)
require.NoError(t, err)
require.Equal(t, 40, len(key2))
require.Equal(t, expLen, len(key2))

require.NotEqual(t, key1, key2)

Expand Down