Skip to content

Commit 0888dc4

Browse files
committed
dfgitutil: FragmentFormat func
Signed-off-by: CrazyMax <[email protected]>
1 parent 7cf577a commit 0888dc4

File tree

4 files changed

+188
-31
lines changed

4 files changed

+188
-31
lines changed

frontend/dockerfile/dfgitutil/git_ref.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,17 @@ func (gf *GitRef) loadQuery(query url.Values) error {
212212
}
213213
return nil
214214
}
215+
216+
// FragmentFormat returns a simplified git URL in fragment format with only ref.
217+
// If the URL cannot be parsed, the original string is returned with false.
218+
func FragmentFormat(remote string) (string, bool) {
219+
gitRef, _, err := ParseGitRef(remote)
220+
if err != nil || gitRef == nil {
221+
return remote, false
222+
}
223+
u := gitRef.Remote
224+
if gitRef.Ref != "" {
225+
u += "#" + gitRef.Ref
226+
}
227+
return u, true
228+
}

frontend/dockerfile/dfgitutil/git_ref_test.go

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,174 @@ func TestParseGitRef(t *testing.T) {
235235
})
236236
}
237237
}
238+
239+
func TestFragmentFormat(t *testing.T) {
240+
cases := []struct {
241+
ref string
242+
expected string
243+
ok bool
244+
}{
245+
{
246+
ref: "https://example.com/",
247+
expected: "https://example.com/",
248+
ok: false,
249+
},
250+
{
251+
ref: "https://example.com/foo.git",
252+
expected: "https://example.com/foo.git",
253+
ok: true,
254+
},
255+
{
256+
ref: "https://example.com/foo.git#deadbeef",
257+
expected: "https://example.com/foo.git#deadbeef",
258+
ok: true,
259+
},
260+
{
261+
ref: "https://example.com/foo.git#release/1.2",
262+
expected: "https://example.com/foo.git#release/1.2",
263+
ok: true,
264+
},
265+
{
266+
ref: "https://example.com/foo.git/",
267+
expected: "https://example.com/foo.git/",
268+
ok: false,
269+
},
270+
{
271+
ref: "https://example.com/foo.git.bar",
272+
expected: "https://example.com/foo.git.bar",
273+
ok: false,
274+
},
275+
{
276+
ref: "git://example.com/foo",
277+
expected: "git://example.com/foo",
278+
ok: true,
279+
},
280+
{
281+
ref: "github.com/moby/buildkit",
282+
expected: "github.com/moby/buildkit",
283+
ok: true,
284+
},
285+
{
286+
ref: "github.com/moby/buildkit#master",
287+
expected: "github.com/moby/buildkit#master",
288+
ok: true,
289+
},
290+
{
291+
ref: "custom.xyz/moby/buildkit.git",
292+
expected: "custom.xyz/moby/buildkit.git",
293+
ok: false,
294+
},
295+
{
296+
ref: "https://github.com/moby/buildkit",
297+
expected: "https://github.com/moby/buildkit",
298+
ok: false,
299+
},
300+
{
301+
ref: "https://github.com/moby/buildkit.git",
302+
expected: "https://github.com/moby/buildkit.git",
303+
ok: true,
304+
},
305+
{
306+
ref: "https://foo:[email protected]/moby/buildkit.git",
307+
expected: "https://foo:[email protected]/moby/buildkit.git",
308+
ok: true,
309+
},
310+
{
311+
ref: "[email protected]:moby/buildkit",
312+
expected: "[email protected]:moby/buildkit",
313+
ok: true,
314+
},
315+
{
316+
ref: "[email protected]:moby/buildkit.git",
317+
expected: "[email protected]:moby/buildkit.git",
318+
ok: true,
319+
},
320+
{
321+
ref: "[email protected]:atlassianlabs/atlassian-docker.git",
322+
expected: "[email protected]:atlassianlabs/atlassian-docker.git",
323+
ok: true,
324+
},
325+
{
326+
ref: "https://github.com/foo/bar.git#baz/qux:quux/quuz",
327+
expected: "https://github.com/foo/bar.git#baz/qux",
328+
ok: true,
329+
},
330+
{
331+
ref: "http://github.com/docker/docker.git:#branch",
332+
expected: "http://github.com/docker/docker.git:#branch",
333+
ok: false,
334+
},
335+
{
336+
ref: "https://github.com/docker/docker.git#:myfolder",
337+
expected: "https://github.com/docker/docker.git",
338+
ok: true,
339+
},
340+
{
341+
ref: "./.git",
342+
expected: "./.git",
343+
ok: false,
344+
},
345+
{
346+
ref: ".git",
347+
expected: ".git",
348+
ok: false,
349+
},
350+
{
351+
ref: "https://github.com/docker/docker.git?ref=v1.0.0&subdir=/subdir",
352+
expected: "https://github.com/docker/docker.git#v1.0.0",
353+
ok: true,
354+
},
355+
{
356+
ref: "https://github.com/moby/buildkit.git?subdir=/subdir#v1.0.0",
357+
expected: "https://github.com/moby/buildkit.git#v1.0.0",
358+
ok: true,
359+
},
360+
{
361+
ref: "https://github.com/moby/buildkit.git?tag=v1.0.0",
362+
expected: "https://github.com/moby/buildkit.git#refs/tags/v1.0.0",
363+
ok: true,
364+
},
365+
{
366+
ref: "github.com/moby/buildkit?tag=v1.0.0",
367+
expected: "github.com/moby/buildkit#refs/tags/v1.0.0",
368+
ok: true,
369+
},
370+
{
371+
ref: "https://github.com/moby/buildkit.git?branch=v1.0",
372+
expected: "https://github.com/moby/buildkit.git#refs/heads/v1.0",
373+
ok: true,
374+
},
375+
{
376+
ref: "https://github.com/moby/buildkit.git?ref=v1.0.0#v1.2.3",
377+
expected: "https://github.com/moby/buildkit.git?ref=v1.0.0#v1.2.3",
378+
ok: false,
379+
},
380+
{
381+
ref: "https://github.com/moby/buildkit.git?ref=v1.0.0&tag=v1.2.3",
382+
expected: "https://github.com/moby/buildkit.git?ref=v1.0.0&tag=v1.2.3",
383+
ok: false,
384+
},
385+
{
386+
ref: "https://github.com/moby/buildkit.git?tag=v1.0.0&branch=v1.0",
387+
expected: "https://github.com/moby/buildkit.git?tag=v1.0.0&branch=v1.0",
388+
ok: false,
389+
},
390+
{
391+
ref: "[email protected]:moby/buildkit.git?subdir=/subdir#v1.0.0",
392+
expected: "[email protected]:moby/buildkit.git#v1.0.0",
393+
ok: true,
394+
},
395+
{
396+
ref: "https://github.com/moby/buildkit.git?invalid=123",
397+
expected: "https://github.com/moby/buildkit.git?invalid=123",
398+
ok: false,
399+
},
400+
}
401+
for i, tt := range cases {
402+
t.Run(fmt.Sprintf("case%d", i+1), func(t *testing.T) {
403+
got, ok := FragmentFormat(tt.ref)
404+
require.Equal(t, tt.expected, got)
405+
require.Equal(t, tt.ok, ok)
406+
})
407+
}
408+
}

solver/llbsolver/provenance/predicate.go

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"github.com/containerd/platforms"
88
slsa "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
99
slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
10+
"github.com/moby/buildkit/frontend/dockerfile/dfgitutil"
1011
provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types"
11-
"github.com/moby/buildkit/util/gitutil"
1212
"github.com/moby/buildkit/util/purl"
1313
"github.com/moby/buildkit/util/urlutil"
1414
"github.com/package-url/packageurl-go"
@@ -70,35 +70,7 @@ func digestSetForCommit(commit string) slsa.DigestSet {
7070
}
7171

7272
func findMaterial(srcs provenancetypes.Sources, uri string) (*slsa.ProvenanceMaterial, bool) {
73-
// Git URLs in querystring format or subdir need to be converted to fragment format with only ref
74-
gitRef, err := gitutil.ParseURL(uri)
75-
if err == nil && gitRef != nil {
76-
u := gitRef.Remote
77-
var ref string
78-
if gitRef.Opts != nil {
79-
ref = gitRef.Opts.Ref
80-
}
81-
if len(gitRef.Query) > 0 {
82-
for k, v := range gitRef.Query {
83-
if len(v) == 0 {
84-
continue
85-
}
86-
switch k {
87-
case "ref":
88-
ref = v[0]
89-
case "branch":
90-
ref = "refs/heads/" + v[0]
91-
case "tag":
92-
ref = "refs/tags/" + v[0]
93-
}
94-
}
95-
}
96-
if ref != "" {
97-
u += "#" + ref
98-
}
99-
uri = u
100-
}
101-
73+
uri, _ = dfgitutil.FragmentFormat(uri)
10274
for _, s := range srcs.Git {
10375
if s.URL == uri {
10476
return &slsa.ProvenanceMaterial{

util/gitutil/git_url.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var supportedProtos = map[string]struct{}{
3030

3131
var protoRegexp = regexp.MustCompile(`^[a-zA-Z0-9]+://`)
3232

33-
// URL is a custom URL type that points to a remote Git repository.
33+
// GitURL is a custom URL type that points to a remote Git repository.
3434
//
3535
// URLs can be parsed from both standard URLs (e.g.
3636
// "https://github.com/moby/buildkit.git"), as well as SCP-like URLs (e.g.

0 commit comments

Comments
 (0)