Skip to content

Commit 552f916

Browse files
authored
Assume latest tag when not provided (#10)
1 parent f1e3974 commit 552f916

4 files changed

Lines changed: 122 additions & 8 deletions

File tree

cmd/clean_image_reference.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/google/go-containerregistry/pkg/name"
8+
)
9+
10+
func cleanImageReference(userInput string) (string, error) {
11+
ref, err := name.ParseReference(userInput, name.WeakValidation, name.WithDefaultTag("latest"))
12+
if err != nil {
13+
return "", fmt.Errorf("unable to parse image reference: %w", err)
14+
}
15+
16+
if t, ok := ref.(name.Tag); ok {
17+
if !strings.HasSuffix(userInput, t.Identifier()) {
18+
return userInput + ":" + t.Identifier(), nil
19+
}
20+
return userInput, nil
21+
}
22+
23+
if d, ok := ref.(name.Digest); ok {
24+
if !strings.HasSuffix(userInput, d.Identifier()) {
25+
return userInput + "@" + d.Identifier(), nil
26+
}
27+
return userInput, nil
28+
}
29+
30+
return ref.Name(), nil
31+
}

cmd/clean_image_reference_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package cmd
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func Test_cleanImageReference(t *testing.T) {
11+
tests := []struct {
12+
input string
13+
want string
14+
wantErr require.ErrorAssertionFunc
15+
}{
16+
{
17+
input: "alpine:latest",
18+
want: "alpine:latest",
19+
},
20+
{
21+
input: "alpine",
22+
want: "alpine:latest",
23+
},
24+
{
25+
input: "docker",
26+
want: "docker:latest",
27+
},
28+
{
29+
input: "anchore/syft:latest",
30+
want: "anchore/syft:latest",
31+
},
32+
{
33+
input: "anchore/syft:v1.4.5",
34+
want: "anchore/syft:v1.4.5",
35+
},
36+
{
37+
input: "anchore/syft",
38+
want: "anchore/syft:latest",
39+
},
40+
{
41+
input: "docker.io/anchore/syft",
42+
want: "docker.io/anchore/syft:latest",
43+
},
44+
{
45+
input: "registry.upbound.io/crossplane/provider-gcp:stable",
46+
want: "registry.upbound.io/crossplane/provider-gcp:stable",
47+
},
48+
{
49+
input: "registry.upbound.io/crossplane/provider-gcp",
50+
want: "registry.upbound.io/crossplane/provider-gcp:latest",
51+
},
52+
{
53+
input: "anchore/syft@sha256:dba09c285770f58d6685b25a0606d72420b0a7525a2338080807d138a258c671",
54+
want: "anchore/syft@sha256:dba09c285770f58d6685b25a0606d72420b0a7525a2338080807d138a258c671",
55+
},
56+
{
57+
// mix tag and digest
58+
input: "anchore/syft:latest@sha256:8bbaebbd4bfc3fed46227eba1d49643fc1bb79b23378956f96cff4c5d69dd42b",
59+
want: "anchore/syft:latest@sha256:8bbaebbd4bfc3fed46227eba1d49643fc1bb79b23378956f96cff4c5d69dd42b",
60+
},
61+
{
62+
// mix tag and digest
63+
input: "registry.upbound.io/crossplane/provider-gcp:v0.2.0@sha256:8bbaebbd4bfc3fed46227eba1d49643fc1bb79b23378956f96cff4c5d69dd42b",
64+
want: "registry.upbound.io/crossplane/provider-gcp:v0.2.0@sha256:8bbaebbd4bfc3fed46227eba1d49643fc1bb79b23378956f96cff4c5d69dd42b",
65+
},
66+
}
67+
for _, tt := range tests {
68+
t.Run(tt.input, func(t *testing.T) {
69+
if tt.wantErr == nil {
70+
tt.wantErr = require.NoError
71+
}
72+
got, err := cleanImageReference(tt.input)
73+
tt.wantErr(t, err)
74+
assert.Equal(t, tt.want, got)
75+
})
76+
}
77+
}

cmd/root.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,13 @@ func (r runner) run(_ *cobra.Command, args []string) error {
207207
}
208208
}
209209

210+
cleanImageName, err := cleanImageReference(args[0])
211+
if err != nil {
212+
return nil
213+
}
214+
210215
return eventLoop(
211-
sbomExecWorker(args[0], r.client, platform, writer),
216+
sbomExecWorker(cleanImageName, r.client, platform, writer),
212217
setupSignals(),
213218
eventSubscription,
214219
stereoscope.Cleanup,
@@ -249,13 +254,13 @@ func generateSBOM(src *source.Source) (*sbom.SBOM, error) {
249254
return &s, nil
250255
}
251256

252-
func sbomExecWorker(userInput string, dockerCli command.Cli, platform *image.Platform, writer sbom.Writer) <-chan error {
257+
func sbomExecWorker(imageName string, dockerCli command.Cli, platform *image.Platform, writer sbom.Writer) <-chan error {
253258
errs := make(chan error)
254259
go func() {
255260
defer close(errs)
256261

257262
provider := stereoscopeDocker.NewProviderFromDaemon(
258-
userInput,
263+
imageName,
259264
file.NewTempDirGenerator(internal.ApplicationName),
260265
dockerCli.Client(),
261266
platform,
@@ -267,19 +272,19 @@ func sbomExecWorker(userInput string, dockerCli command.Cli, platform *image.Pla
267272
}
268273
}()
269274
if err != nil {
270-
errs <- fmt.Errorf("failed to fetch the image %q: %w", userInput, err)
275+
errs <- fmt.Errorf("failed to fetch the image %q: %w", imageName, err)
271276
return
272277
}
273278

274279
err = img.Read()
275280
if err != nil {
276-
errs <- fmt.Errorf("failed to read the image %q: %w", userInput, err)
281+
errs <- fmt.Errorf("failed to read the image %q: %w", imageName, err)
277282
return
278283
}
279284

280-
src, err := source.NewFromImage(img, userInput)
285+
src, err := source.NewFromImage(img, imageName)
281286
if err != nil {
282-
errs <- fmt.Errorf("failed to construct source from user input %q: %w", userInput, err)
287+
errs <- fmt.Errorf("failed to construct source from user input %q: %w", imageName, err)
283288
return
284289
}
285290
src.Exclusions = appConfig.Exclusions

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ require (
3131
gotest.tools/v3 v3.1.0 // indirect
3232
)
3333

34+
require github.com/google/go-containerregistry v0.8.1-0.20220209165246-a44adc326839
35+
3436
require (
3537
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
3638
github.com/CycloneDX/cyclonedx-go v0.5.0 // indirect
@@ -63,7 +65,6 @@ require (
6365
github.com/golang/protobuf v1.5.2 // indirect
6466
github.com/golang/snappy v0.0.4 // indirect
6567
github.com/google/go-cmp v0.5.7 // indirect
66-
github.com/google/go-containerregistry v0.8.1-0.20220209165246-a44adc326839 // indirect
6768
github.com/google/uuid v1.3.0 // indirect
6869
github.com/gorilla/mux v1.8.0 // indirect
6970
github.com/hashicorp/errwrap v1.1.0 // indirect

0 commit comments

Comments
 (0)