mirror of
https://github.com/anchore/syft.git
synced 2026-10-21 02:22:23 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0891d35e07 | ||
|
|
502971a1b2 | ||
|
|
dc14dbb326 | ||
|
|
bae5a2e741 | ||
|
|
220655743b | ||
|
|
9fce006b8f | ||
|
|
d91c2dd842 |
+1
-1
@@ -29,7 +29,7 @@ tools:
|
||||
|
||||
- name: cosign
|
||||
version:
|
||||
want: v2.2.0
|
||||
want: v2.2.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: sigstore/cosign
|
||||
|
||||
@@ -62,7 +62,7 @@ require (
|
||||
github.com/sergi/go-diff v1.3.1
|
||||
github.com/spdx/tools-golang v0.5.3
|
||||
github.com/spf13/afero v1.10.0
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/vbatts/go-mtree v0.5.3
|
||||
github.com/vifraa/gopom v1.0.0
|
||||
|
||||
@@ -202,6 +202,7 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
@@ -713,8 +714,8 @@ github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
|
||||
@@ -3,5 +3,5 @@ package internal
|
||||
const (
|
||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||
JSONSchemaVersion = "12.0.0"
|
||||
JSONSchemaVersion = "12.0.1"
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,8 @@ type LocationData struct {
|
||||
Coordinates `cyclonedx:""` // Empty string here means there is no intermediate property name, e.g. syft:locations:0:path without "coordinates"
|
||||
// note: it is IMPORTANT to ignore anything but the coordinates for a Location when considering the ID (hash value)
|
||||
// since the coordinates are the minimally correct ID for a location (symlinks should not come into play)
|
||||
VirtualPath string `hash:"ignore" json:"-"` // The path to the file which may or may not have hardlinks / symlinks
|
||||
ref file.Reference `hash:"ignore"` // The file reference relative to the stereoscope.FileCatalog that has more information about this location.
|
||||
VirtualPath string `hash:"ignore" json:"accessPath"` // The path to the file which may or may not have hardlinks / symlinks
|
||||
ref file.Reference `hash:"ignore"` // The file reference relative to the stereoscope.FileCatalog that has more information about this location.
|
||||
}
|
||||
|
||||
func (l LocationData) Reference() file.Reference {
|
||||
@@ -179,7 +179,7 @@ func (l Location) String() string {
|
||||
|
||||
str += fmt.Sprintf("RealPath=%q", l.RealPath)
|
||||
|
||||
if l.VirtualPath != "" {
|
||||
if l.VirtualPath != "" && l.VirtualPath != l.RealPath {
|
||||
str += fmt.Sprintf(" VirtualPath=%q", l.VirtualPath)
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +213,12 @@ func extractComponents(meta *cyclonedx.Metadata) source.Description {
|
||||
|
||||
switch c.Type {
|
||||
case cyclonedx.ComponentTypeContainer:
|
||||
var labels map[string]string
|
||||
|
||||
if meta.Properties != nil {
|
||||
labels = decodeProperties(*meta.Properties, "syft:image:labels:")
|
||||
}
|
||||
|
||||
return source.Description{
|
||||
ID: "",
|
||||
// TODO: can we decode alias name-version somehow? (it isn't be encoded in the first place yet)
|
||||
@@ -221,6 +227,7 @@ func extractComponents(meta *cyclonedx.Metadata) source.Description {
|
||||
UserInput: c.Name,
|
||||
ID: c.BOMRef,
|
||||
ManifestDigest: c.Version,
|
||||
Labels: labels,
|
||||
},
|
||||
}
|
||||
case cyclonedx.ComponentTypeFile:
|
||||
|
||||
@@ -97,7 +97,6 @@ func Test_decode(t *testing.T) {
|
||||
CPE: "cpe:2.3:*:another:package:2:*:*:*:*:*:*:*",
|
||||
PackageURL: "pkg:apk/alpine/alpine-baselayout@3.2.0-r16?arch=x86_64&upstream=alpine-baselayout&distro=alpine-3.14.2",
|
||||
Properties: &[]cyclonedx.Property{
|
||||
|
||||
{
|
||||
Name: "foundBy",
|
||||
Value: "apkdb-cataloger",
|
||||
|
||||
@@ -121,7 +121,8 @@ func toBomDescriptor(name, version string, srcMetadata source.Description) *cycl
|
||||
Version: version,
|
||||
},
|
||||
},
|
||||
Component: toBomDescriptorComponent(srcMetadata),
|
||||
Properties: toBomProperties(srcMetadata),
|
||||
Component: toBomDescriptorComponent(srcMetadata),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +191,15 @@ func toDependencies(relationships []artifact.Relationship) []cyclonedx.Dependenc
|
||||
return result
|
||||
}
|
||||
|
||||
func toBomProperties(srcMetadata source.Description) *[]cyclonedx.Property {
|
||||
metadata, ok := srcMetadata.Metadata.(source.StereoscopeImageSourceMetadata)
|
||||
if ok {
|
||||
props := encodeProperties(metadata.Labels, "syft:image:labels")
|
||||
return &props
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func toBomDescriptorComponent(srcMetadata source.Description) *cyclonedx.Component {
|
||||
name := srcMetadata.Name
|
||||
version := srcMetadata.Version
|
||||
|
||||
@@ -5,12 +5,14 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func Test_formatCPE(t *testing.T) {
|
||||
@@ -138,3 +140,95 @@ func Test_relationships(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_toBomDescriptor(t *testing.T) {
|
||||
type args struct {
|
||||
name string
|
||||
version string
|
||||
srcMetadata source.Description
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *cyclonedx.Metadata
|
||||
}{
|
||||
{
|
||||
name: "with image labels source metadata",
|
||||
args: args{
|
||||
name: "test-image",
|
||||
version: "1.0.0",
|
||||
srcMetadata: source.Description{
|
||||
Metadata: source.StereoscopeImageSourceMetadata{
|
||||
Labels: map[string]string{
|
||||
"key1": "value1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &cyclonedx.Metadata{
|
||||
Timestamp: "",
|
||||
Lifecycles: nil,
|
||||
Tools: &[]cyclonedx.Tool{
|
||||
{
|
||||
Vendor: "anchore",
|
||||
Name: "test-image",
|
||||
Version: "1.0.0",
|
||||
Hashes: nil,
|
||||
ExternalReferences: nil,
|
||||
},
|
||||
},
|
||||
Authors: nil,
|
||||
Component: &cyclonedx.Component{
|
||||
BOMRef: "",
|
||||
MIMEType: "",
|
||||
Type: "container",
|
||||
Supplier: nil,
|
||||
Author: "",
|
||||
Publisher: "",
|
||||
Group: "",
|
||||
Name: "",
|
||||
Version: "",
|
||||
Description: "",
|
||||
Scope: "",
|
||||
Hashes: nil,
|
||||
Licenses: nil,
|
||||
Copyright: "",
|
||||
CPE: "",
|
||||
PackageURL: "",
|
||||
SWID: nil,
|
||||
Modified: nil,
|
||||
Pedigree: nil,
|
||||
ExternalReferences: nil,
|
||||
Properties: nil,
|
||||
Components: nil,
|
||||
Evidence: nil,
|
||||
ReleaseNotes: nil,
|
||||
},
|
||||
Manufacture: nil,
|
||||
Supplier: nil,
|
||||
Licenses: nil,
|
||||
Properties: &[]cyclonedx.Property{
|
||||
{
|
||||
Name: "syft:image:labels:key1",
|
||||
Value: "value1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
subject := toBomDescriptor(tt.args.name, tt.args.version, tt.args.srcMetadata)
|
||||
|
||||
require.NotEmpty(t, subject.Component.BOMRef)
|
||||
subject.Timestamp = "" // not under test
|
||||
|
||||
require.NotNil(t, subject.Component)
|
||||
require.NotEmpty(t, subject.Component.BOMRef)
|
||||
subject.Component.BOMRef = "" // not under test
|
||||
|
||||
if d := cmp.Diff(tt.want, subject); d != "" {
|
||||
t.Errorf("toBomDescriptor() mismatch (-want +got):\n%s", d)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cyclonedxhelpers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
|
||||
"github.com/anchore/syft/syft/format/common"
|
||||
@@ -19,3 +21,14 @@ func encodeProperties(obj interface{}, prefix string) (out []cyclonedx.Property)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func decodeProperties(properties []cyclonedx.Property, prefix string) map[string]string {
|
||||
labels := make(map[string]string)
|
||||
for _, property := range properties {
|
||||
if strings.HasPrefix(property.Name, prefix) {
|
||||
labelName := strings.TrimPrefix(property.Name, prefix)
|
||||
labels[labelName] = property.Value
|
||||
}
|
||||
}
|
||||
return labels
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/CycloneDX/cyclonedx-go"
|
||||
|
||||
@@ -75,7 +74,7 @@ func (d decoder) Identify(reader io.ReadSeeker) (sbom.FormatID, string) {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
id, version := getFormatInfo(doc.JSONSchema, doc.BOMFormat, doc.SpecVersion)
|
||||
id, version := getFormatInfo(doc.BOMFormat, doc.SpecVersion)
|
||||
if version == "" || id != ID {
|
||||
// not a cyclonedx json document that we support
|
||||
return "", ""
|
||||
@@ -84,18 +83,13 @@ func (d decoder) Identify(reader io.ReadSeeker) (sbom.FormatID, string) {
|
||||
return id, version
|
||||
}
|
||||
|
||||
func getFormatInfo(schemaURI, bomFormat string, specVersion any) (sbom.FormatID, string) {
|
||||
if !strings.Contains(schemaURI, "cyclonedx.org/schema/bom") {
|
||||
// not a cyclonedx json document
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func getFormatInfo(bomFormat string, specVersion any) (sbom.FormatID, string) {
|
||||
if bomFormat != "CycloneDX" {
|
||||
// not a cyclonedx json document
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// by this point this looks to be valid cyclonedx json, but we need to know the version
|
||||
// by this point, it looks to be cyclonedx json, but we need to know the version
|
||||
|
||||
var (
|
||||
version string
|
||||
|
||||
@@ -103,6 +103,21 @@ func TestDecoder_Identify(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
cases = append(cases, []testCase{
|
||||
{
|
||||
name: "no-schema-1.4",
|
||||
file: "test-fixtures/identify/micronaut-1.4.json",
|
||||
id: ID,
|
||||
version: "1.4",
|
||||
},
|
||||
{
|
||||
name: "no-schema-1.5",
|
||||
file: "test-fixtures/identify/micronaut-1.5.json",
|
||||
id: ID,
|
||||
version: "1.5",
|
||||
},
|
||||
}...)
|
||||
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
reader, err := os.Open(test.file)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.4",
|
||||
"version": 1,
|
||||
"components": [
|
||||
{
|
||||
"type": "library",
|
||||
"group": "io.netty",
|
||||
"name": "netty-codec-http2",
|
||||
"version": "4.1.73.Final",
|
||||
"properties": [
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:codec:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:netty-codec-http2:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:netty_codec_http2:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"serialNumber": "urn:uuid:43538af4-f715-3d85-9629-336fdd3790ad"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.5",
|
||||
"version": 1,
|
||||
"components": [
|
||||
{
|
||||
"type": "library",
|
||||
"group": "io.netty",
|
||||
"name": "netty-codec-http2",
|
||||
"version": "4.1.73.Final",
|
||||
"properties": [
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:codec:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:netty-codec-http2:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:netty_codec_http2:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"serialNumber": "urn:uuid:f4-f715-3d85-9629-336fdd3790ad"
|
||||
}
|
||||
@@ -117,7 +117,7 @@ func TestEncodeFullJSONDocument(t *testing.T) {
|
||||
Artifacts: sbom.Artifacts{
|
||||
Packages: catalog,
|
||||
FileMetadata: map[file.Coordinates]file.Metadata{
|
||||
file.NewLocation("/a/place").Coordinates: {
|
||||
file.NewVirtualLocation("/a/place", "/a/symlink/to/place").Coordinates: {
|
||||
FileInfo: stereoFile.ManualInfo{
|
||||
NameValue: "/a/place",
|
||||
ModeValue: 0775,
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
"foundBy": "the-cataloger-1",
|
||||
"locations": [
|
||||
{
|
||||
"path": "/some/path/pkg1"
|
||||
"path": "/some/path/pkg1",
|
||||
"accessPath": "/some/path/pkg1"
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
@@ -48,7 +49,8 @@
|
||||
"foundBy": "the-cataloger-2",
|
||||
"locations": [
|
||||
{
|
||||
"path": "/some/path/pkg1"
|
||||
"path": "/some/path/pkg1",
|
||||
"accessPath": "/some/path/pkg1"
|
||||
}
|
||||
],
|
||||
"licenses": [],
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
"foundBy": "the-cataloger-1",
|
||||
"locations": [
|
||||
{
|
||||
"path": "/a/place/a"
|
||||
"path": "/a/place/a",
|
||||
"accessPath": "/a/place/a"
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
@@ -43,7 +44,8 @@
|
||||
"foundBy": "the-cataloger-2",
|
||||
"locations": [
|
||||
{
|
||||
"path": "/b/place/b"
|
||||
"path": "/b/place/b",
|
||||
"accessPath": "/b/place/b"
|
||||
}
|
||||
],
|
||||
"licenses": [],
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"locations": [
|
||||
{
|
||||
"path": "/somefile-1.txt",
|
||||
"layerID": "sha256:100d5a55f9032faead28b7427fa3e650e4f0158f86ea89d06e1489df00cb8c6f"
|
||||
"layerID": "sha256:100d5a55f9032faead28b7427fa3e650e4f0158f86ea89d06e1489df00cb8c6f",
|
||||
"accessPath": "/somefile-1.txt"
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
@@ -45,7 +46,8 @@
|
||||
"locations": [
|
||||
{
|
||||
"path": "/somefile-2.txt",
|
||||
"layerID": "sha256:000fb9200890d3a19138478b20023023c0dce1c54352007c2863716780f049eb"
|
||||
"layerID": "sha256:000fb9200890d3a19138478b20023023c0dce1c54352007c2863716780f049eb",
|
||||
"accessPath": "/somefile-2.txt"
|
||||
}
|
||||
],
|
||||
"licenses": [],
|
||||
|
||||
@@ -444,7 +444,7 @@ func (j *archiveParser) discoverPkgsFromAllMavenFiles(parentPkg *pkg.Package) ([
|
||||
pomProject = proj
|
||||
}
|
||||
|
||||
pkgFromPom := newPackageFromMavenData(propertiesObj, pomProject, parentPkg, j.location)
|
||||
pkgFromPom := newPackageFromMavenData(propertiesObj, pomProject, parentPkg, j.location, j.cfg)
|
||||
if pkgFromPom != nil {
|
||||
pkgs = append(pkgs, *pkgFromPom)
|
||||
}
|
||||
@@ -635,7 +635,7 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP
|
||||
|
||||
// newPackageFromMavenData processes a single Maven POM properties for a given parent package, returning all listed Java packages found and
|
||||
// associating each discovered package to the given parent package. Note the pom.xml is optional, the pom.properties is not.
|
||||
func newPackageFromMavenData(pomProperties pkg.JavaPomProperties, parsedPomProject *parsedPomProject, parentPkg *pkg.Package, location file.Location) *pkg.Package {
|
||||
func newPackageFromMavenData(pomProperties pkg.JavaPomProperties, parsedPomProject *parsedPomProject, parentPkg *pkg.Package, location file.Location, cfg Config) *pkg.Package {
|
||||
// keep the artifact name within the virtual path if this package does not match the parent package
|
||||
vPathSuffix := ""
|
||||
groupID := ""
|
||||
@@ -660,6 +660,9 @@ func newPackageFromMavenData(pomProperties pkg.JavaPomProperties, parsedPomProje
|
||||
var pkgPomProject *pkg.JavaPomProject
|
||||
licenses := make([]pkg.License, 0)
|
||||
if parsedPomProject != nil {
|
||||
if cfg.UseNetwork {
|
||||
findPomLicenses(parsedPomProject, cfg)
|
||||
}
|
||||
pkgPomProject = parsedPomProject.JavaPomProject
|
||||
licenses = append(licenses, parsedPomProject.Licenses...)
|
||||
}
|
||||
|
||||
@@ -1089,7 +1089,7 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
}
|
||||
test.expectedParent.Locations = locations
|
||||
|
||||
actualPackage := newPackageFromMavenData(test.props, test.project, test.parent, file.NewLocation(virtualPath))
|
||||
actualPackage := newPackageFromMavenData(test.props, test.project, test.parent, file.NewLocation(virtualPath), Config{})
|
||||
if test.expectedPackage == nil {
|
||||
require.Nil(t, actualPackage)
|
||||
} else {
|
||||
|
||||
@@ -108,10 +108,6 @@ func deriveIDFromFile(cfg FileConfig) (artifact.ID, string) {
|
||||
info += fmt.Sprintf(":%s@%s", cfg.Alias.Name, cfg.Alias.Version)
|
||||
}
|
||||
|
||||
if d != "" {
|
||||
d = fmt.Sprintf("sha256:%s", d)
|
||||
}
|
||||
|
||||
return artifactIDFromDigest(digest.SHA256.FromString(info).String()), d
|
||||
}
|
||||
|
||||
|
||||
@@ -211,10 +211,11 @@ func createArchive(t testing.TB, sourceDirPath, destinationArchivePath string, l
|
||||
|
||||
func Test_FileSource_ID(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cfg FileConfig
|
||||
want artifact.ID
|
||||
wantErr require.ErrorAssertionFunc
|
||||
name string
|
||||
cfg FileConfig
|
||||
want artifact.ID
|
||||
wantDigest string
|
||||
wantErr require.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
@@ -236,9 +237,10 @@ func Test_FileSource_ID(t *testing.T) {
|
||||
wantErr: require.Error,
|
||||
},
|
||||
{
|
||||
name: "with path",
|
||||
cfg: FileConfig{Path: "./test-fixtures/image-simple/Dockerfile"},
|
||||
want: artifact.ID("db7146472cf6d49b3ac01b42812fb60020b0b4898b97491b21bb690c808d5159"),
|
||||
name: "with path",
|
||||
cfg: FileConfig{Path: "./test-fixtures/image-simple/Dockerfile"},
|
||||
want: artifact.ID("db7146472cf6d49b3ac01b42812fb60020b0b4898b97491b21bb690c808d5159"),
|
||||
wantDigest: "sha256:38601c0bb4269a10ce1d00590ea7689c1117dd9274c758653934ab4f2016f80f",
|
||||
},
|
||||
{
|
||||
name: "with path and alias",
|
||||
@@ -249,7 +251,8 @@ func Test_FileSource_ID(t *testing.T) {
|
||||
Version: "version-me-this!",
|
||||
},
|
||||
},
|
||||
want: artifact.ID("3c713003305ac6605255cec8bf4ea649aa44b2b9a9f3a07bd683869d1363438a"),
|
||||
want: artifact.ID("3c713003305ac6605255cec8bf4ea649aa44b2b9a9f3a07bd683869d1363438a"),
|
||||
wantDigest: "sha256:38601c0bb4269a10ce1d00590ea7689c1117dd9274c758653934ab4f2016f80f",
|
||||
},
|
||||
{
|
||||
name: "other fields do not affect ID",
|
||||
@@ -259,7 +262,8 @@ func Test_FileSource_ID(t *testing.T) {
|
||||
Paths: []string{"a", "b"},
|
||||
},
|
||||
},
|
||||
want: artifact.ID("db7146472cf6d49b3ac01b42812fb60020b0b4898b97491b21bb690c808d5159"),
|
||||
want: artifact.ID("db7146472cf6d49b3ac01b42812fb60020b0b4898b97491b21bb690c808d5159"),
|
||||
wantDigest: "sha256:38601c0bb4269a10ce1d00590ea7689c1117dd9274c758653934ab4f2016f80f",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -272,7 +276,8 @@ func Test_FileSource_ID(t *testing.T) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
assert.Equalf(t, tt.want, s.ID(), "ID()")
|
||||
assert.Equalf(t, tt.want, s.ID(), "ID() mismatch")
|
||||
assert.Equalf(t, tt.wantDigest, s.digestForVersion, "digestForVersion mismatch")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ type StereoscopeImageSourceMetadata struct {
|
||||
Architecture string `json:"architecture"`
|
||||
Variant string `json:"architectureVariant,omitempty"`
|
||||
OS string `json:"os"`
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
// StereoscopeLayerMetadata represents all static metadata that defines what a container image layer is.
|
||||
@@ -48,6 +49,7 @@ func NewStereoscopeImageMetadata(img *image.Image, userInput string) Stereoscope
|
||||
Architecture: img.Metadata.Architecture,
|
||||
Variant: img.Metadata.Variant,
|
||||
OS: img.Metadata.OS,
|
||||
Labels: img.Metadata.Config.Config.Labels,
|
||||
}
|
||||
|
||||
// populate image metadata
|
||||
|
||||
@@ -192,6 +192,7 @@ func imageMetadataFromStereoscopeImage(img *image.Image, reference string) Stere
|
||||
Architecture: img.Metadata.Architecture,
|
||||
Variant: img.Metadata.Variant,
|
||||
OS: img.Metadata.OS,
|
||||
Labels: img.Metadata.Config.Config.Labels,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user