Skip to content

Commit 51a677f

Browse files
committed
llb: update Git to allow normalized property passing
Signed-off-by: Tonis Tiigi <[email protected]>
1 parent c8ce372 commit 51a677f

File tree

4 files changed

+147
-18
lines changed

4 files changed

+147
-18
lines changed

client/llb/git_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package llb
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/moby/buildkit/solver/pb"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestGit(t *testing.T) {
12+
t.Parallel()
13+
14+
type tcase struct {
15+
name string
16+
st State
17+
identifier string
18+
attrs map[string]string
19+
}
20+
21+
tcases := []tcase{
22+
{
23+
name: "refarg",
24+
st: Git("github.com/foo/bar.git", "ref"),
25+
identifier: "git://github.com/foo/bar.git#ref",
26+
attrs: map[string]string{
27+
"git.authheadersecret": "GIT_AUTH_HEADER",
28+
"git.authtokensecret": "GIT_AUTH_TOKEN",
29+
"git.fullurl": "https://github.com/foo/bar.git",
30+
},
31+
},
32+
{
33+
name: "refarg with subdir",
34+
st: Git("github.com/foo/bar.git", "ref:subdir"),
35+
identifier: "git://github.com/foo/bar.git#ref:subdir",
36+
attrs: map[string]string{
37+
"git.authheadersecret": "GIT_AUTH_HEADER",
38+
"git.authtokensecret": "GIT_AUTH_TOKEN",
39+
"git.fullurl": "https://github.com/foo/bar.git",
40+
},
41+
},
42+
{
43+
name: "refarg with subdir func",
44+
st: Git("github.com/foo/bar.git", "ref", GitSubDir("subdir")),
45+
identifier: "git://github.com/foo/bar.git#ref:subdir",
46+
attrs: map[string]string{
47+
"git.authheadersecret": "GIT_AUTH_HEADER",
48+
"git.authtokensecret": "GIT_AUTH_TOKEN",
49+
"git.fullurl": "https://github.com/foo/bar.git",
50+
},
51+
},
52+
{
53+
name: "refarg with override",
54+
st: Git("github.com/foo/bar.git", "ref:dir", GitRef("v1.0")),
55+
identifier: "git://github.com/foo/bar.git#v1.0:dir",
56+
attrs: map[string]string{
57+
"git.authheadersecret": "GIT_AUTH_HEADER",
58+
"git.authtokensecret": "GIT_AUTH_TOKEN",
59+
"git.fullurl": "https://github.com/foo/bar.git",
60+
},
61+
},
62+
{
63+
name: "funcs only",
64+
st: Git("github.com/foo/bar.git", "", GitRef("v1.0"), GitSubDir("dir")),
65+
identifier: "git://github.com/foo/bar.git#v1.0:dir",
66+
attrs: map[string]string{
67+
"git.authheadersecret": "GIT_AUTH_HEADER",
68+
"git.authtokensecret": "GIT_AUTH_TOKEN",
69+
"git.fullurl": "https://github.com/foo/bar.git",
70+
},
71+
},
72+
}
73+
74+
for _, tc := range tcases {
75+
t.Run(tc.name, func(t *testing.T) {
76+
st := tc.st
77+
def, err := st.Marshal(context.TODO())
78+
79+
require.NoError(t, err)
80+
81+
m, arr := parseDef(t, def.Def)
82+
require.Equal(t, 2, len(arr))
83+
84+
dgst, idx := last(t, arr)
85+
require.Equal(t, 0, idx)
86+
require.Equal(t, m[dgst], arr[0])
87+
88+
g := arr[0].Op.(*pb.Op_Source).Source
89+
90+
require.Equal(t, tc.identifier, g.Identifier)
91+
require.Equal(t, tc.attrs, g.Attrs)
92+
})
93+
}
94+
}

client/llb/source.go

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ const (
249249
//
250250
// By default the git repository is cloned with `--depth=1` to reduce the amount of data downloaded.
251251
// Additionally the ".git" directory is removed after the clone, you can keep ith with the [KeepGitDir] [GitOption].
252-
func Git(url, ref string, opts ...GitOption) State {
252+
func Git(url, fragment string, opts ...GitOption) State {
253253
remote, err := gitutil.ParseURL(url)
254254
if errors.Is(err, gitutil.ErrUnknownProtocol) {
255255
url = "https://" + url
@@ -259,6 +259,20 @@ func Git(url, ref string, opts ...GitOption) State {
259259
url = remote.Remote
260260
}
261261

262+
gi := &GitInfo{
263+
AuthHeaderSecret: GitAuthHeaderKey,
264+
AuthTokenSecret: GitAuthTokenKey,
265+
}
266+
ref, subdir, ok := strings.Cut(fragment, ":")
267+
if ref != "" {
268+
GitRef(ref).SetGitOption(gi)
269+
}
270+
if ok && subdir != "" {
271+
GitSubDir(subdir).SetGitOption(gi)
272+
}
273+
for _, o := range opts {
274+
o.SetGitOption(gi)
275+
}
262276
var id string
263277
if err != nil {
264278
// If we can't parse the URL, just use the full URL as the ID. The git
@@ -269,18 +283,13 @@ func Git(url, ref string, opts ...GitOption) State {
269283
// for different protocols (e.g. https and ssh) that have the same
270284
// host/path/fragment combination.
271285
id = remote.Host + path.Join("/", remote.Path)
272-
if ref != "" {
273-
id += "#" + ref
286+
if gi.Ref != "" || gi.SubDir != "" {
287+
id += "#" + gi.Ref
288+
if gi.SubDir != "" {
289+
id += ":" + gi.SubDir
290+
}
274291
}
275292
}
276-
277-
gi := &GitInfo{
278-
AuthHeaderSecret: GitAuthHeaderKey,
279-
AuthTokenSecret: GitAuthTokenKey,
280-
}
281-
for _, o := range opts {
282-
o.SetGitOption(gi)
283-
}
284293
attrs := map[string]string{}
285294
if gi.KeepGitDir {
286295
attrs[pb.AttrKeepGitDir] = "true"
@@ -352,6 +361,20 @@ type GitInfo struct {
352361
KnownSSHHosts string
353362
MountSSHSock string
354363
Checksum string
364+
Ref string
365+
SubDir string
366+
}
367+
368+
func GitRef(v string) GitOption {
369+
return gitOptionFunc(func(gi *GitInfo) {
370+
gi.Ref = v
371+
})
372+
}
373+
374+
func GitSubDir(v string) GitOption {
375+
return gitOptionFunc(func(gi *GitInfo) {
376+
gi.SubDir = v
377+
})
355378
}
356379

357380
func KeepGitDir() GitOption {

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,18 +1513,21 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
15131513
return errors.New("source can't be a git ref for COPY")
15141514
}
15151515
// TODO: print a warning (not an error) if gitRef.UnencryptedTCP is true
1516-
commit := gitRef.Ref
1517-
if gitRef.SubDir != "" {
1518-
commit += ":" + gitRef.SubDir
1516+
gitOptions := []llb.GitOption{
1517+
llb.WithCustomName(pgName),
1518+
llb.GitRef(gitRef.Ref),
15191519
}
1520-
gitOptions := []llb.GitOption{llb.WithCustomName(pgName)}
15211520
if cfg.keepGitDir {
15221521
gitOptions = append(gitOptions, llb.KeepGitDir())
15231522
}
15241523
if cfg.checksum != "" {
15251524
gitOptions = append(gitOptions, llb.GitChecksum(cfg.checksum))
15261525
}
1527-
st := llb.Git(gitRef.Remote, commit, gitOptions...)
1526+
if gitRef.SubDir != "" {
1527+
gitOptions = append(gitOptions, llb.GitSubDir(gitRef.SubDir))
1528+
}
1529+
1530+
st := llb.Git(gitRef.Remote, "", gitOptions...)
15281531
opts := append([]llb.CopyOption{&llb.CopyInfo{
15291532
Mode: chopt,
15301533
CreateDestPath: true,

frontend/dockerui/context.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,21 @@ func DetectGitContext(ref string, keepGit bool) (*llb.State, bool) {
149149
if g.SubDir != "" {
150150
commit += ":" + g.SubDir
151151
}
152-
gitOpts := []llb.GitOption{WithInternalName("load git source " + ref)}
152+
gitOpts := []llb.GitOption{
153+
llb.GitRef(commit),
154+
WithInternalName("load git source " + ref),
155+
}
153156
if keepGit {
154157
gitOpts = append(gitOpts, llb.KeepGitDir())
155158
}
159+
if g.SubDir != "" {
160+
gitOpts = append(gitOpts, llb.GitSubDir(g.SubDir))
161+
}
162+
if g.Checksum != "" {
163+
gitOpts = append(gitOpts, llb.GitChecksum(g.Checksum))
164+
}
156165

157-
st := llb.Git(g.Remote, commit, gitOpts...)
166+
st := llb.Git(g.Remote, "", gitOpts...)
158167
return &st, true
159168
}
160169

0 commit comments

Comments
 (0)