From bafc14c77763a77dbe58d39f1f7c8873b30339e0 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 10 Oct 2023 17:25:41 -0400 Subject: [PATCH 1/4] add relationships for deb packages Signed-off-by: Alex Goodman --- syft/pkg/cataloger/deb/cataloger_test.go | 6 + syft/pkg/cataloger/deb/package.go | 16 +- syft/pkg/cataloger/deb/parse_dpkg_db.go | 140 +++++++++++++++- syft/pkg/cataloger/deb/parse_dpkg_db_test.go | 157 +++++++++++++++++- .../status/coreutils-relationships | 114 +++++++++++++ .../deb/test-fixtures/status/doc-examples | 46 +++++ .../deb/test-fixtures/status/libpam-runtime | 23 +++ syft/pkg/dpkg_metadata.go | 51 +++++- 8 files changed, 529 insertions(+), 24 deletions(-) create mode 100644 syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships create mode 100644 syft/pkg/cataloger/deb/test-fixtures/status/doc-examples create mode 100644 syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime diff --git a/syft/pkg/cataloger/deb/cataloger_test.go b/syft/pkg/cataloger/deb/cataloger_test.go index 6e035be874d..e547206e59b 100644 --- a/syft/pkg/cataloger/deb/cataloger_test.go +++ b/syft/pkg/cataloger/deb/cataloger_test.go @@ -44,6 +44,11 @@ func TestDpkgCataloger(t *testing.T) { Contains configuration files and directories required for authentication to work on Debian systems. This package is required on almost all installations.`, + Depends: []string{ + "debconf (>= 0.5) | debconf-2.0", + "debconf (>= 1.5.19) | cdebconf", + "libpam-modules (>= 1.0.1-6)", + }, Files: []pkg.DpkgFileRecord{ { Path: "/etc/pam.conf", @@ -112,6 +117,7 @@ func TestDpkgCataloger(t *testing.T) { SQLite is a C library that implements an SQL database engine. Programs that link with the SQLite library can have SQL database access without running a separate RDBMS process.`, + Depends: []string{"libc6 (>= 2.29)"}, Files: []pkg.DpkgFileRecord{ {Path: "/usr/lib/aarch64-linux-gnu/libsqlite3.so.0.8.6", Digest: &file.Digest{ Algorithm: "md5", diff --git a/syft/pkg/cataloger/deb/package.go b/syft/pkg/cataloger/deb/package.go index ebd72a77af2..eb9b551c9be 100644 --- a/syft/pkg/cataloger/deb/package.go +++ b/syft/pkg/cataloger/deb/package.go @@ -36,13 +36,15 @@ func newDpkgPackage(d pkg.DpkgMetadata, dbLocation file.Location, resolver file. Metadata: d, } - // the current entry only has what may have been listed in the status file, however, there are additional - // files that are listed in multiple other locations. We should retrieve them all and merge the file lists - // together. - mergeFileListing(resolver, dbLocation, &p) - - // fetch additional data from the copyright file to derive the license information - addLicenses(resolver, dbLocation, &p) + if resolver != nil { + // the current entry only has what may have been listed in the status file, however, there are additional + // files that are listed in multiple other locations. We should retrieve them all and merge the file lists + // together. + mergeFileListing(resolver, dbLocation, &p) + + // fetch additional data from the copyright file to derive the license information + addLicenses(resolver, dbLocation, &p) + } p.SetID() diff --git a/syft/pkg/cataloger/deb/parse_dpkg_db.go b/syft/pkg/cataloger/deb/parse_dpkg_db.go index 0a7dccb2d30..719cba1182f 100644 --- a/syft/pkg/cataloger/deb/parse_dpkg_db.go +++ b/syft/pkg/cataloger/deb/parse_dpkg_db.go @@ -35,7 +35,7 @@ func parseDpkgDB(resolver file.Resolver, env *generic.Environment, reader file.L pkgs = append(pkgs, newDpkgPackage(m, reader.Location, resolver, env.LinuxRelease)) } - return pkgs, nil, nil + return pkgs, associateRelationships(pkgs), nil } // parseDpkgStatus is a parser function for Debian DB status contents, returning all Debian packages listed. @@ -63,6 +63,22 @@ func parseDpkgStatus(reader io.Reader) ([]pkg.DpkgMetadata, error) { return metadata, nil } +// dpkgExtractedMetadata is an adapter struct to capture the fields from the dpkg status file, however, the final +// pkg.DpkgMetadata struct has different types for some fields (e.g. Provides, Depends, and PreDepends is []string, not a string). +type dpkgExtractedMetadata struct { + Package string `mapstructure:"Package"` + Source string `mapstructure:"Source"` + Version string `mapstructure:"Version"` + SourceVersion string `mapstructure:"SourceVersion"` + Architecture string `mapstructure:"Architecture"` + Maintainer string `mapstructure:"Maintainer"` + InstalledSize int `mapstructure:"InstalledSize"` + Description string `mapstructure:"Description"` + Provides string `mapstructure:"Provides"` + Depends string `mapstructure:"Depends"` + PreDepends string `mapstructure:"PreDepends"` // note: original doc is Pre-Depends +} + // parseDpkgStatusEntry returns an individual Dpkg entry, or returns errEndOfPackages if there are no more packages to parse from the reader. func parseDpkgStatusEntry(reader *bufio.Reader) (*pkg.DpkgMetadata, error) { var retErr error @@ -77,22 +93,36 @@ func parseDpkgStatusEntry(reader *bufio.Reader) (*pkg.DpkgMetadata, error) { retErr = err } - entry := pkg.DpkgMetadata{} - err = mapstructure.Decode(dpkgFields, &entry) + raw := dpkgExtractedMetadata{} + err = mapstructure.Decode(dpkgFields, &raw) if err != nil { return nil, err } - sourceName, sourceVersion := extractSourceVersion(entry.Source) + sourceName, sourceVersion := extractSourceVersion(raw.Source) if sourceVersion != "" { - entry.SourceVersion = sourceVersion - entry.Source = sourceName + raw.SourceVersion = sourceVersion + raw.Source = sourceName } - if entry.Package == "" { + if raw.Package == "" { return nil, retErr } + entry := pkg.DpkgMetadata{ + Package: raw.Package, + Source: raw.Source, + Version: raw.Version, + SourceVersion: raw.SourceVersion, + Architecture: raw.Architecture, + Maintainer: raw.Maintainer, + InstalledSize: raw.InstalledSize, + Description: raw.Description, + Provides: splitPkgList(raw.Provides), + Depends: splitPkgList(raw.Depends), + PreDepends: splitPkgList(raw.PreDepends), + } + // there may be an optional conffiles section that we should persist as files if conffilesSection, exists := dpkgFields["Conffiles"]; exists && conffilesSection != nil { if sectionStr, ok := conffilesSection.(string); ok { @@ -108,6 +138,17 @@ func parseDpkgStatusEntry(reader *bufio.Reader) (*pkg.DpkgMetadata, error) { return &entry, retErr } +func splitPkgList(pkgList string) (ret []string) { + fields := strings.Split(pkgList, ",") + for _, field := range fields { + field = strings.TrimSpace(field) + if field != "" { + ret = append(ret, field) + } + } + return ret +} + func extractAllFields(reader *bufio.Reader) (map[string]interface{}, error) { dpkgFields := make(map[string]interface{}) var key string @@ -195,3 +236,88 @@ func handleNewKeyValue(line string) (key string, val interface{}, err error) { return "", nil, fmt.Errorf("cannot parse field from line: '%s'", line) } + +// associateRelationships will create relationships between packages based on the "Depends", "Pre-Depends", and "Provides" +// fields for installed packages. if there is an installed package that has a dependency that is (somehow) not installed, +// then that relationship (between the installed and uninstalled package) will NOT be created. +func associateRelationships(pkgs []pkg.Package) (relationships []artifact.Relationship) { + // map["provides" + "package"] -> packages that provide that package + lookup := make(map[string][]pkg.Package) + + // read provided and add as keys for lookup keys as well as package names + for _, p := range pkgs { + meta, ok := p.Metadata.(pkg.DpkgMetadata) + if !ok { + log.Warnf("cataloger failed to extract dpkg 'provides' metadata for package %+v", p.Name) + continue + } + lookup[p.Name] = append(lookup[p.Name], p) + for _, provides := range meta.Provides { + k := stripVersionSpecifier(provides) + lookup[k] = append(lookup[k], p) + } + } + + // read "Depends" and "Pre-Depends" and match with keys + for _, p := range pkgs { + meta, ok := p.Metadata.(pkg.DpkgMetadata) + if !ok { + log.Warnf("cataloger failed to extract dpkg 'dependency' metadata for package %+v", p.Name) + continue + } + + for _, depSpecifier := range meta.PreDepends { + deps := splitPackageChoice(depSpecifier) + for _, dep := range deps { + for _, depPkg := range lookup[dep] { + relationships = append(relationships, artifact.Relationship{ + From: depPkg, + To: p, + Type: artifact.DependencyOfRelationship, + }) + } + } + } + + for _, depSpecifier := range meta.Depends { + deps := splitPackageChoice(depSpecifier) + for _, dep := range deps { + for _, depPkg := range lookup[dep] { + relationships = append(relationships, artifact.Relationship{ + From: depPkg, + To: p, + Type: artifact.DependencyOfRelationship, + }) + } + } + } + } + return relationships +} + +func stripVersionSpecifier(s string) string { + // examples: + // libgmp10 (>= 2:6.2.1+dfsg1) --> libgmp10 + // libgmp10 --> libgmp10 + // foo [i386] --> foo + // default-mta | mail-transport-agent --> default-mta | mail-transport-agent + // kernel-headers-2.2.10 [!hurd-i386] --> kernel-headers-2.2.10 + + items := internal.SplitAny(s, "[(<>=") + if len(items) == 0 { + return s + } + + return strings.TrimSpace(items[0]) +} + +func splitPackageChoice(s string) (ret []string) { + fields := strings.Split(s, "|") + for _, field := range fields { + field = strings.TrimSpace(field) + if field != "" { + ret = append(ret, stripVersionSpecifier(field)) + } + } + return ret +} diff --git a/syft/pkg/cataloger/deb/parse_dpkg_db_test.go b/syft/pkg/cataloger/deb/parse_dpkg_db_test.go index 0a2c58bd895..b2d72f287a5 100644 --- a/syft/pkg/cataloger/deb/parse_dpkg_db_test.go +++ b/syft/pkg/cataloger/deb/parse_dpkg_db_test.go @@ -11,9 +11,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/linux" "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/generic" "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" ) @@ -48,6 +50,18 @@ func Test_parseDpkgStatus(t *testing.T) { * apt-cdrom to use removable media as a source for packages * apt-config as an interface to the configuration settings * apt-key as an interface to manage authentication keys`, + Provides: []string{"apt-transport-https (= 1.8.2)"}, + Depends: []string{ + "adduser", + "gpgv | gpgv2 | gpgv1", + "debian-archive-keyring", + "libapt-pkg5.0 (>= 1.7.0~alpha3~)", + "libc6 (>= 2.15)", + "libgcc1 (>= 1:3.0)", + "libgnutls30 (>= 3.6.6)", + "libseccomp2 (>= 1.0.1)", + "libstdc++6 (>= 5.2)", + }, Files: []pkg.DpkgFileRecord{ { Path: "/etc/apt/apt.conf.d/01autoremove", @@ -110,6 +124,18 @@ func Test_parseDpkgStatus(t *testing.T) { * apt-cdrom to use removable media as a source for packages * apt-config as an interface to the configuration settings * apt-key as an interface to manage authentication keys`, + Provides: []string{"apt-transport-https (= 1.8.2)"}, + Depends: []string{ + "adduser", + "gpgv | gpgv2 | gpgv1", + "debian-archive-keyring", + "libapt-pkg5.0 (>= 1.7.0~alpha3~)", + "libc6 (>= 2.15)", + "libgcc1 (>= 1:3.0)", + "libgnutls30 (>= 3.6.6)", + "libseccomp2 (>= 1.0.1)", + "libstdc++6 (>= 5.2)", + }, Files: []pkg.DpkgFileRecord{}, }, }, @@ -135,7 +161,9 @@ func Test_parseDpkgStatus(t *testing.T) { globe. It is updated periodically to reflect changes made by political bodies to time zone boundaries, UTC offsets, and daylight-saving rules.`, - Files: []pkg.DpkgFileRecord{}, + Provides: []string{"tzdata-buster"}, + Depends: []string{"debconf (>= 0.5) | debconf-2.0"}, + Files: []pkg.DpkgFileRecord{}, }, { Package: "util-linux", @@ -149,6 +177,14 @@ func Test_parseDpkgStatus(t *testing.T) { important utilities included in this package allow you to view kernel messages, create new filesystems, view block device information, interface with real time clock, etc.`, + Depends: []string{"fdisk", "login (>= 1:4.5-1.1~)"}, + PreDepends: []string{ + "libaudit1 (>= 1:2.2.1)", "libblkid1 (>= 2.31.1)", "libc6 (>= 2.25)", + "libcap-ng0 (>= 0.7.9)", "libmount1 (>= 2.25)", "libpam0g (>= 0.99.7.1)", + "libselinux1 (>= 2.6-3~)", "libsmartcols1 (>= 2.33)", "libsystemd0", + "libtinfo6 (>= 6)", "libudev1 (>= 183)", "libuuid1 (>= 2.16)", + "zlib1g (>= 1:1.1.4)", + }, Files: []pkg.DpkgFileRecord{ { Path: "/etc/default/hwclock", @@ -397,3 +433,122 @@ func Test_handleNewKeyValue(t *testing.T) { }) } } + +func Test_stripVersionSpecifier(t *testing.T) { + + tests := []struct { + name string + input string + want string + }{ + { + name: "package name only", + input: "test", + want: "test", + }, + { + name: "with version", + input: "test (1.2.3)", + want: "test", + }, + { + name: "multiple packages", + input: "test | other", + want: "test | other", + }, + { + name: "with architecture specifiers", + input: "test [amd64 i386]", + want: "test", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, stripVersionSpecifier(tt.input)) + }) + } +} + +func Test_associateRelationships(t *testing.T) { + tests := []struct { + name string + fixture string + wantRelationships map[string][]string + }{ + { + name: "relationships for coreutils", + fixture: "test-fixtures/status/coreutils-relationships", + wantRelationships: map[string][]string{ + "coreutils": {"libacl1", "libattr1", "libc6", "libgmp10", "libselinux1"}, + "libacl1": {"libc6"}, + "libattr1": {"libc6"}, + "libc6": {"libgcc-s1"}, + "libgcc-s1": {"gcc-12-base", "libc6"}, + "libgmp10": {"libc6"}, + "libpcre2-8-0": {"libc6"}, + "libselinux1": {"libc6", "libpcre2-8-0"}, + }, + }, + { + name: "relationships from dpkg example docs", + fixture: "test-fixtures/status/doc-examples", + wantRelationships: map[string][]string{ + "made-up-package-1": {"kernel-headers-2.2.10", "hurd-dev", "gnumach-dev"}, + "made-up-package-2": {"libluajit5.1-dev", "liblua5.1-dev"}, + "made-up-package-3": {"foo", "bar"}, + // note that the "made-up-package-4" depends on "made-up-package-5" but not via the direct + // package name, but through the "provides" virtual package name "virtual-package-5". + "made-up-package-4": {"made-up-package-5"}, + // note that though there is a "default-mta | mail-transport-agent | not-installed" + // dependency choice we raise up the packages that are installed for every choice. + // In this case that means that "default-mta" and "mail-transport-agent". + "mutt": {"libc6", "default-mta", "mail-transport-agent"}, + }, + }, + { + name: "relationships for libpam-runtime", + fixture: "test-fixtures/status/libpam-runtime", + wantRelationships: map[string][]string{ + "libpam-runtime": {"debconf1", "debconf-2.0", "debconf2", "cdebconf", "libpam-modules"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f, err := os.Open(tt.fixture) + require.NoError(t, err) + + reader := file.NewLocationReadCloser(file.NewLocation(tt.fixture), f) + + pkgs, relationships, err := parseDpkgDB(nil, &generic.Environment{}, reader) + require.NotEmpty(t, pkgs) + require.NotEmpty(t, relationships) + require.NoError(t, err) + + if d := cmp.Diff(tt.wantRelationships, abstractRelationships(t, relationships)); d != "" { + t.Errorf("unexpected relationships (-want +got):\n%s", d) + } + }) + } +} + +func abstractRelationships(t testing.TB, relationships []artifact.Relationship) map[string][]string { + t.Helper() + + abstracted := make(map[string][]string) + for _, relationship := range relationships { + fromPkg, ok := relationship.From.(pkg.Package) + if !ok { + continue + } + toPkg, ok := relationship.To.(pkg.Package) + if !ok { + continue + } + + // we build this backwards since we use DependencyOfRelationship instead of DependsOn + abstracted[toPkg.Name] = append(abstracted[toPkg.Name], fromPkg.Name) + } + + return abstracted +} diff --git a/syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships b/syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships new file mode 100644 index 00000000000..1097fea5641 --- /dev/null +++ b/syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships @@ -0,0 +1,114 @@ +Package: coreutils +Essential: yes +Status: install ok installed +Priority: required +Section: utils +Installed-Size: 20272 +Maintainer: Michael Stone +Architecture: arm64 +Multi-Arch: foreign +Version: 9.1-1 +Pre-Depends: libacl1 (>= 2.2.23), libattr1 (>= 1:2.4.44), libc6 (>= 2.34), libgmp10 (>= 2:6.2.1+dfsg1), libselinux1 (>= 3.1~) + +Package: libacl1 +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 101 +Maintainer: Guillem Jover +Architecture: arm64 +Multi-Arch: same +Source: acl +Version: 2.3.1-3 +Depends: libc6 (>= 2.33) + +Package: libc6 +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 23127 +Maintainer: GNU Libc Maintainers +Architecture: arm64 +Multi-Arch: same +Source: glibc +Version: 2.36-9+deb12u1 +Depends: libgcc-s1 +Recommends: libidn2-0 (>= 2.0.5~) +Suggests: glibc-doc, debconf | debconf-2.0, libc-l10n, locales, libnss-nis, libnss-nisplus +Breaks: aide (<< 0.17.3-4+b3), busybox (<< 1.30.1-6), chrony (<< 4.2-3~), fakechroot (<< 2.19-3.5), firefox (<< 91~), firefox-esr (<< 91~), gnumach-image-1.8-486 (<< 2:1.8+git20210923~), gnumach-image-1.8-486-dbg (<< 2:1.8+git20210923~), gnumach-image-1.8-xen-486 (<< 2:1.8+git20210923~), gnumach-image-1.8-xen-486-dbg (<< 2:1.8+git20210923~), hurd (<< 1:0.9.git20220301-2), ioquake3 (<< 1.36+u20200211.f2c61c1~dfsg-2~), iraf-fitsutil (<< 2018.07.06-4), libgegl-0.4-0 (<< 0.4.18), libtirpc1 (<< 0.2.3), locales (<< 2.36), locales-all (<< 2.36), macs (<< 2.2.7.1-3~), nocache (<< 1.1-1~), nscd (<< 2.36), openarena (<< 0.8.8+dfsg-4~), openssh-server (<< 1:8.1p1-5), python3-iptables (<< 1.0.0-2), r-cran-later (<< 0.7.5+dfsg-2), tinydns (<< 1:1.05-14), valgrind (<< 1:3.19.0-1~), wcc (<< 0.0.2+dfsg-3) + +Package: libgcc-s1 +Protected: yes +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 147 +Maintainer: Debian GCC Maintainers +Architecture: arm64 +Multi-Arch: same +Source: gcc-12 +Version: 12.2.0-14 +Replaces: libgcc1 (<< 1:10) +Provides: libgcc1 (= 1:12.2.0-14) +Depends: gcc-12-base (= 12.2.0-14), libc6 (>= 2.35) + +Package: gcc-12-base +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 100 +Maintainer: Debian GCC Maintainers +Architecture: arm64 +Multi-Arch: same +Source: gcc-12 +Version: 12.2.0-14 +Breaks: gnat (<< 7) + +Package: libattr1 +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 99 +Maintainer: Guillem Jover +Architecture: arm64 +Multi-Arch: same +Source: attr +Version: 1:2.5.1-4 +Depends: libc6 (>= 2.17) + +Package: libgmp10 +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 855 +Maintainer: Debian Science Team +Architecture: arm64 +Multi-Arch: same +Source: gmp +Version: 2:6.2.1+dfsg1-1.1 +Depends: libc6 (>= 2.17) +Breaks: libmath-gmp-perl (<< 2.20-1), libmath-prime-util-gmp-perl (<< 0.51-2), postgresql-pgmp (<< 1.0.3-1) + +Package: libselinux1 +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 223 +Maintainer: Debian SELinux maintainers +Architecture: arm64 +Multi-Arch: same +Source: libselinux (3.4-1) +Version: 3.4-1+b6 +Depends: libc6 (>= 2.34), libpcre2-8-0 (>= 10.22) + +Package: libpcre2-8-0 +Status: install ok installed +Priority: optional +Section: libs +Installed-Size: 649 +Maintainer: Matthew Vernon +Architecture: arm64 +Multi-Arch: same +Source: pcre2 +Version: 10.42-1 +Depends: libc6 (>= 2.34) diff --git a/syft/pkg/cataloger/deb/test-fixtures/status/doc-examples b/syft/pkg/cataloger/deb/test-fixtures/status/doc-examples new file mode 100644 index 00000000000..6b9fe186f71 --- /dev/null +++ b/syft/pkg/cataloger/deb/test-fixtures/status/doc-examples @@ -0,0 +1,46 @@ +Package: mutt +Version: 1.3.17-1 +Depends: libc6 (>= 2.2.1), default-mta | mail-transport-agent | not-installed + +Package: made-up-package-1 +Version: 1.0.0 +Source: glibc +Depends: kernel-headers-2.2.10 [!hurd-i386], + hurd-dev [hurd-i386], gnumach-dev [hurd-i386] + +Package: made-up-package-2 +Version: 2.0.0 +Depends: + libluajit5.1-dev [i386 amd64 kfreebsd-i386 armel armhf powerpc mips], + liblua5.1-dev [hurd-i386 ia64 kfreebsd-amd64 s390x sparc], + +Package: made-up-package-3 +Version: 3.0.0 +Depends: foo [i386], bar [amd64] + +Package: made-up-package-4 +Version: 3.0.0 +Depends: virtual-package-5 + +Package: made-up-package-5 +Provides: virtual-package-5 (=1.0) + +Package: foo + +Package: bar + +Package: kernel-headers-2.2.10 + +Package: hurd-dev + +Package: gnumach-dev + +Package: default-mta + +Package: mail-transport-agent + +Package: libc6 + +Package: libluajit5.1-dev + +Package: liblua5.1-dev diff --git a/syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime b/syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime new file mode 100644 index 00000000000..73aaf69789b --- /dev/null +++ b/syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime @@ -0,0 +1,23 @@ +Package: libpam-runtime +Status: install ok installed +Priority: required +Section: admin +Installed-Size: 876 +Maintainer: Sam Hartman +Architecture: all +Multi-Arch: foreign +Source: pam +Version: 1.5.2-6+deb12u1 +Replaces: libpam0g-dev, libpam0g-util +Depends: debconf1 (>= 0.5) | debconf-2.0, debconf2 (>= 1.5.19) | cdebconf, libpam-modules (>= 1.0.1-6) +Conflicts: libpam0g-util + +Package: debconf1 + +Package: debconf2 + +Package: debconf-2.0 + +Package: cdebconf + +Package: libpam-modules diff --git a/syft/pkg/dpkg_metadata.go b/syft/pkg/dpkg_metadata.go index 2ad5de2dbce..5b38be03b1a 100644 --- a/syft/pkg/dpkg_metadata.go +++ b/syft/pkg/dpkg_metadata.go @@ -14,16 +14,49 @@ var _ FileOwner = (*DpkgMetadata)(nil) // DpkgMetadata represents all captured data for a Debian package DB entry; available fields are described // at http://manpages.ubuntu.com/manpages/xenial/man1/dpkg-query.1.html in the --showformat section. +// Additional information about how these fields are used can be found at +// - https://www.debian.org/doc/debian-policy/ch-controlfields.html +// - https://www.debian.org/doc/debian-policy/ch-relationships.html +// - https://www.debian.org/doc/debian-policy/ch-binary.html#s-virtual-pkg +// - https://www.debian.org/doc/debian-policy/ch-relationships.html#s-virtual + type DpkgMetadata struct { - Package string `mapstructure:"Package" json:"package"` - Source string `mapstructure:"Source" json:"source" cyclonedx:"source"` - Version string `mapstructure:"Version" json:"version"` - SourceVersion string `mapstructure:"SourceVersion" json:"sourceVersion" cyclonedx:"sourceVersion"` - Architecture string `mapstructure:"Architecture" json:"architecture"` - Maintainer string `mapstructure:"Maintainer" json:"maintainer"` - InstalledSize int `mapstructure:"InstalledSize" json:"installedSize" cyclonedx:"installedSize"` - Description string `mapstructure:"Description" hash:"ignore" json:"-"` - Files []DpkgFileRecord `json:"files"` + Package string `json:"package"` + Source string `json:"source" cyclonedx:"source"` + Version string `json:"version"` + SourceVersion string `json:"sourceVersion" cyclonedx:"sourceVersion"` + + // Architecture can include the following sets of values depending on context and the control file used: + // - a unique single word identifying a Debian machine architecture as described in Architecture specification string (https://www.debian.org/doc/debian-policy/ch-customized-programs.html#s-arch-spec) . + // - an architecture wildcard identifying a set of Debian machine architectures, see Architecture wildcards (https://www.debian.org/doc/debian-policy/ch-customized-programs.html#s-arch-wildcard-spec). any matches all Debian machine architectures and is the most frequently used. + // - "all", which indicates an architecture-independent package. + // - "source", which indicates a source package. + Architecture string `json:"architecture"` + + // Maintainer is the package maintainer’s name and email address. The name must come first, then the email + // address inside angle brackets <> (in RFC822 format). + Maintainer string `json:"maintainer"` + + InstalledSize int `json:"installedSize" cyclonedx:"installedSize"` + + // Description contains a description of the binary package, consisting of two parts, the synopsis or the short + // description, and the long description (in a multiline format). + Description string `hash:"ignore" json:"-"` + + // Provides is a virtual package that is provided by one or more packages. A virtual package is one which appears + // in the Provides control field of another package. The effect is as if the package(s) which provide a particular + // virtual package name had been listed by name everywhere the virtual package name appears. (See also Virtual packages) + Provides []string `json:"provides,omitempty"` + + // Depends This declares an absolute dependency. A package will not be configured unless all of the packages listed in + // its Depends field have been correctly configured (unless there is a circular dependency). + Depends []string `json:"depends,omitempty"` + + // PreDepends is like Depends, except that it also forces dpkg to complete installation of the packages named + // before even starting the installation of the package which declares the pre-dependency. + PreDepends []string `json:"preDepends,omitempty"` + + Files []DpkgFileRecord `json:"files"` } // DpkgFileRecord represents a single file attributed to a debian package. From c6af81d0997c862ad5c416d589fa8fcff0b8e8af Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 10 Oct 2023 17:55:00 -0400 Subject: [PATCH 2/4] update snapshots Signed-off-by: Alex Goodman --- syft/formats/cyclonedxxml/encoder_test.go | 2 +- .../snapshot/TestCycloneDxDirectoryEncoder.golden | 2 +- .../test-fixtures/snapshot/TestCycloneDxImageEncoder.golden | 2 +- .../snapshot/TestSPDXJSONDirectoryEncoder.golden | 4 ++-- .../test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden | 4 ++-- .../test-fixtures/snapshot/TestSPDXRelationshipOrder.golden | 4 ++-- .../test-fixtures/snapshot/TestSPDXRelationshipOrder.golden | 4 ++-- .../snapshot/TestSPDXTagValueDirectoryEncoder.golden | 4 ++-- .../snapshot/TestSPDXTagValueImageEncoder.golden | 4 ++-- .../test-fixtures/snapshot/TestDirectoryEncoder.golden | 2 +- .../test-fixtures/snapshot/TestEncodeFullJSONDocument.golden | 2 +- .../syftjson/test-fixtures/snapshot/TestImageEncoder.golden | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/syft/formats/cyclonedxxml/encoder_test.go b/syft/formats/cyclonedxxml/encoder_test.go index 5b8781affe5..17e1eb5974d 100644 --- a/syft/formats/cyclonedxxml/encoder_test.go +++ b/syft/formats/cyclonedxxml/encoder_test.go @@ -57,7 +57,7 @@ func redactor(values ...string) testutils.Redactor { `sha256:[A-Za-z0-9]{64}`: `sha256:redacted`, // BOM refs - `bom-ref="[a-zA-Z0-9\-:]+"`: `bom-ref:redacted`, + `bom-ref="[a-zA-Z0-9\-:]+"`: `bom-ref="redacted"`, }, ) } diff --git a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden index 592072d2005..bbba1803408 100644 --- a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden +++ b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden @@ -32,7 +32,7 @@ /some/path/pkg1 - + package-2 2.0.1 cpe:2.3:*:some:package:2:*:*:*:*:*:*:* diff --git a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden index 95701d1005d..914602f17eb 100644 --- a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden +++ b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden @@ -34,7 +34,7 @@ /somefile-1.txt - + package-2 2.0.1 cpe:2.3:*:some:package:2:*:*:*:*:*:*:* diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden index dac57a1da9e..b5f1c29a72a 100644 --- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden +++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden @@ -39,7 +39,7 @@ }, { "name": "package-2", - "SPDXID": "SPDXRef-Package-deb-package-2-db4abfe497c180d3", + "SPDXID": "SPDXRef-Package-deb-package-2-ad5013466727018f", "versionInfo": "2.0.1", "supplier": "NOASSERTION", "downloadLocation": "NOASSERTION", @@ -78,7 +78,7 @@ }, { "spdxElementId": "SPDXRef-DocumentRoot-Directory-some-path", - "relatedSpdxElement": "SPDXRef-Package-deb-package-2-db4abfe497c180d3", + "relatedSpdxElement": "SPDXRef-Package-deb-package-2-ad5013466727018f", "relationshipType": "CONTAINS" }, { diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden index 73e27667e00..009333c6d3b 100644 --- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden +++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden @@ -39,7 +39,7 @@ }, { "name": "package-2", - "SPDXID": "SPDXRef-Package-deb-package-2-958443e2d9304af4", + "SPDXID": "SPDXRef-Package-deb-package-2-f27313b22a5ba330", "versionInfo": "2.0.1", "supplier": "NOASSERTION", "downloadLocation": "NOASSERTION", @@ -92,7 +92,7 @@ }, { "spdxElementId": "SPDXRef-DocumentRoot-Image-user-image-input", - "relatedSpdxElement": "SPDXRef-Package-deb-package-2-958443e2d9304af4", + "relatedSpdxElement": "SPDXRef-Package-deb-package-2-f27313b22a5ba330", "relationshipType": "CONTAINS" }, { diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden index 80e5b269a46..260d4cba0a2 100644 --- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden +++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden @@ -39,7 +39,7 @@ }, { "name": "package-2", - "SPDXID": "SPDXRef-Package-deb-package-2-958443e2d9304af4", + "SPDXID": "SPDXRef-Package-deb-package-2-f27313b22a5ba330", "versionInfo": "2.0.1", "supplier": "NOASSERTION", "downloadLocation": "NOASSERTION", @@ -214,7 +214,7 @@ }, { "spdxElementId": "SPDXRef-DocumentRoot-Image-user-image-input", - "relatedSpdxElement": "SPDXRef-Package-deb-package-2-958443e2d9304af4", + "relatedSpdxElement": "SPDXRef-Package-deb-package-2-f27313b22a5ba330", "relationshipType": "CONTAINS" }, { diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden index 764ac9830c1..8b42da86140 100644 --- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden @@ -61,7 +61,7 @@ ExternalRef: PACKAGE-MANAGER purl pkg:oci/user-image-input@sha256:2731251dc34951 ##### Package: package-2 PackageName: package-2 -SPDXID: SPDXRef-Package-deb-package-2-958443e2d9304af4 +SPDXID: SPDXRef-Package-deb-package-2-f27313b22a5ba330 PackageVersion: 2.0.1 PackageSupplier: NOASSERTION PackageDownloadLocation: NOASSERTION @@ -97,6 +97,6 @@ Relationship: SPDXRef-Package-python-package-1-125840abc1c66dd7 CONTAINS SPDXRef Relationship: SPDXRef-Package-python-package-1-125840abc1c66dd7 CONTAINS SPDXRef-File-d1-f3-c6f5b29dca12661f Relationship: SPDXRef-Package-python-package-1-125840abc1c66dd7 CONTAINS SPDXRef-File-f2-f9e49132a4b96ccd Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-python-package-1-125840abc1c66dd7 -Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-958443e2d9304af4 +Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-f27313b22a5ba330 Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Image-user-image-input diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden index e50194535d6..7cfc999cbc8 100644 --- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden @@ -20,7 +20,7 @@ FilesAnalyzed: false ##### Package: package-2 PackageName: package-2 -SPDXID: SPDXRef-Package-deb-package-2-db4abfe497c180d3 +SPDXID: SPDXRef-Package-deb-package-2-ad5013466727018f PackageVersion: 2.0.1 PackageSupplier: NOASSERTION PackageDownloadLocation: NOASSERTION @@ -50,6 +50,6 @@ ExternalRef: PACKAGE-MANAGER purl a-purl-2 ##### Relationships Relationship: SPDXRef-DocumentRoot-Directory-some-path CONTAINS SPDXRef-Package-python-package-1-9265397e5e15168a -Relationship: SPDXRef-DocumentRoot-Directory-some-path CONTAINS SPDXRef-Package-deb-package-2-db4abfe497c180d3 +Relationship: SPDXRef-DocumentRoot-Directory-some-path CONTAINS SPDXRef-Package-deb-package-2-ad5013466727018f Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Directory-some-path diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden index 3c640ea726e..8c3d1f705b6 100644 --- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden +++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden @@ -23,7 +23,7 @@ ExternalRef: PACKAGE-MANAGER purl pkg:oci/user-image-input@sha256:2731251dc34951 ##### Package: package-2 PackageName: package-2 -SPDXID: SPDXRef-Package-deb-package-2-958443e2d9304af4 +SPDXID: SPDXRef-Package-deb-package-2-f27313b22a5ba330 PackageVersion: 2.0.1 PackageSupplier: NOASSERTION PackageDownloadLocation: NOASSERTION @@ -53,6 +53,6 @@ ExternalRef: PACKAGE-MANAGER purl a-purl-1 ##### Relationships Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-python-package-1-125840abc1c66dd7 -Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-958443e2d9304af4 +Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-f27313b22a5ba330 Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Image-user-image-input diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden index 61bb2efe42d..11674865f44 100644 --- a/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden +++ b/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden @@ -41,7 +41,7 @@ } }, { - "id": "db4abfe497c180d3", + "id": "ad5013466727018f", "name": "package-2", "version": "2.0.1", "type": "deb", diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden index f83789be5ec..10a5cc12cfc 100644 --- a/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden +++ b/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden @@ -36,7 +36,7 @@ } }, { - "id": "9fd0b9f41034991d", + "id": "aa0ca2c331576dfd", "name": "package-2", "version": "2.0.1", "type": "deb", diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden index 518a90ab50d..ba156fb881f 100644 --- a/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden +++ b/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden @@ -37,7 +37,7 @@ } }, { - "id": "958443e2d9304af4", + "id": "f27313b22a5ba330", "name": "package-2", "version": "2.0.1", "type": "deb", From b8c120f40d5eee369db43c609133947380a89728 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 10 Oct 2023 18:01:22 -0400 Subject: [PATCH 3/4] bump json schema Signed-off-by: Alex Goodman --- internal/constants.go | 2 +- schema/json/schema-11.0.1.json | 2003 ++++++++++++++++++++++++++++++++ 2 files changed, 2004 insertions(+), 1 deletion(-) create mode 100644 schema/json/schema-11.0.1.json diff --git a/internal/constants.go b/internal/constants.go index 794da714a86..0f7c9cc0fac 100644 --- a/internal/constants.go +++ b/internal/constants.go @@ -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 = "11.0.0" + JSONSchemaVersion = "11.0.1" ) diff --git a/schema/json/schema-11.0.1.json b/schema/json/schema-11.0.1.json new file mode 100644 index 00000000000..cd3e2b8da54 --- /dev/null +++ b/schema/json/schema-11.0.1.json @@ -0,0 +1,2003 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "anchore.io/schema/syft/json/11.0.1/document", + "$ref": "#/$defs/Document", + "$defs": { + "AlpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "gid": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "size": { + "type": "string" + }, + "link": { + "type": "string" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object" + }, + "AlpmMetadata": { + "properties": { + "basepackage": { + "type": "string" + }, + "package": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "packager": { + "type": "string" + }, + "url": { + "type": "string" + }, + "validation": { + "type": "string" + }, + "reason": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + }, + "backup": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "basepackage", + "package", + "version", + "description", + "architecture", + "size", + "packager", + "url", + "validation", + "reason", + "files", + "backup" + ] + }, + "ApkFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "ownerUid": { + "type": "string" + }, + "ownerGid": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "ApkMetadata": { + "properties": { + "package": { + "type": "string" + }, + "originPackage": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "version": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "url": { + "type": "string" + }, + "description": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "installedSize": { + "type": "integer" + }, + "pullDependencies": { + "items": { + "type": "string" + }, + "type": "array" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "pullChecksum": { + "type": "string" + }, + "gitCommitOfApkPort": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/ApkFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "originPackage", + "maintainer", + "version", + "architecture", + "url", + "description", + "size", + "installedSize", + "pullDependencies", + "provides", + "pullChecksum", + "gitCommitOfApkPort", + "files" + ] + }, + "BinaryMetadata": { + "properties": { + "matches": { + "items": { + "$ref": "#/$defs/ClassifierMatch" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "matches" + ] + }, + "CargoPackageMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + }, + "checksum": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "checksum", + "dependencies" + ] + }, + "ClassifierMatch": { + "properties": { + "classifier": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Location" + } + }, + "type": "object", + "required": [ + "classifier", + "location" + ] + }, + "CocoapodsMetadata": { + "properties": { + "checksum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "checksum" + ] + }, + "ConanLockMetadata": { + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + }, + "prev": { + "type": "string" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "build_requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "py_requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "options": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "path": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "ConanMetadata": { + "properties": { + "ref": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "Coordinates": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "DartPubMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "hosted_url": { + "type": "string" + }, + "vcs_url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Descriptor": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "configuration": true + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Digest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "Document": { + "properties": { + "artifacts": { + "items": { + "$ref": "#/$defs/Package" + }, + "type": "array" + }, + "artifactRelationships": { + "items": { + "$ref": "#/$defs/Relationship" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/File" + }, + "type": "array" + }, + "secrets": { + "items": { + "$ref": "#/$defs/Secrets" + }, + "type": "array" + }, + "source": { + "$ref": "#/$defs/Source" + }, + "distro": { + "$ref": "#/$defs/LinuxRelease" + }, + "descriptor": { + "$ref": "#/$defs/Descriptor" + }, + "schema": { + "$ref": "#/$defs/Schema" + } + }, + "type": "object", + "required": [ + "artifacts", + "artifactRelationships", + "source", + "distro", + "descriptor", + "schema" + ] + }, + "DotnetDepsMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "path": { + "type": "string" + }, + "sha512": { + "type": "string" + }, + "hashPath": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "path", + "sha512", + "hashPath" + ] + }, + "DotnetPortableExecutableMetadata": { + "properties": { + "assemblyVersion": { + "type": "string" + }, + "legalCopyright": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "internalName": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "productName": { + "type": "string" + }, + "productVersion": { + "type": "string" + } + }, + "type": "object", + "required": [ + "assemblyVersion", + "legalCopyright", + "companyName", + "productName", + "productVersion" + ] + }, + "DpkgFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "isConfigFile": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "path", + "isConfigFile" + ] + }, + "DpkgMetadata": { + "properties": { + "package": { + "type": "string" + }, + "source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "installedSize": { + "type": "integer" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "preDepends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/DpkgFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "source", + "version", + "sourceVersion", + "architecture", + "maintainer", + "installedSize", + "files" + ] + }, + "File": { + "properties": { + "id": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Coordinates" + }, + "metadata": { + "$ref": "#/$defs/FileMetadataEntry" + }, + "contents": { + "type": "string" + }, + "digests": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + }, + "licenses": { + "items": { + "$ref": "#/$defs/FileLicense" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "id", + "location" + ] + }, + "FileLicense": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "evidence": { + "$ref": "#/$defs/FileLicenseEvidence" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type" + ] + }, + "FileLicenseEvidence": { + "properties": { + "confidence": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "extent": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "confidence", + "offset", + "extent" + ] + }, + "FileMetadataEntry": { + "properties": { + "mode": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "linkDestination": { + "type": "string" + }, + "userID": { + "type": "integer" + }, + "groupID": { + "type": "integer" + }, + "mimeType": { + "type": "string" + }, + "size": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "mode", + "type", + "userID", + "groupID", + "mimeType", + "size" + ] + }, + "GemMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "GolangBinMetadata": { + "properties": { + "goBuildSettings": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "goCompiledVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "h1Digest": { + "type": "string" + }, + "mainModule": { + "type": "string" + }, + "goCryptoSettings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "goCompiledVersion", + "architecture" + ] + }, + "GolangModMetadata": { + "properties": { + "h1Digest": { + "type": "string" + } + }, + "type": "object" + }, + "HackageMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "snapshotURL": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "IDLikes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "JavaManifest": { + "properties": { + "main": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "namedSections": { + "patternProperties": { + ".*": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "JavaMetadata": { + "properties": { + "virtualPath": { + "type": "string" + }, + "manifest": { + "$ref": "#/$defs/JavaManifest" + }, + "pomProperties": { + "$ref": "#/$defs/PomProperties" + }, + "pomProject": { + "$ref": "#/$defs/PomProject" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "virtualPath" + ] + }, + "KbPackageMetadata": { + "properties": { + "product_id": { + "type": "string" + }, + "kb": { + "type": "string" + } + }, + "type": "object", + "required": [ + "product_id", + "kb" + ] + }, + "License": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "urls": { + "items": { + "type": "string" + }, + "type": "array" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type", + "urls", + "locations" + ] + }, + "LinuxKernelMetadata": { + "properties": { + "name": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "version": { + "type": "string" + }, + "extendedVersion": { + "type": "string" + }, + "buildTime": { + "type": "string" + }, + "author": { + "type": "string" + }, + "format": { + "type": "string" + }, + "rwRootFS": { + "type": "boolean" + }, + "swapDevice": { + "type": "integer" + }, + "rootDevice": { + "type": "integer" + }, + "videoMode": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "architecture", + "version" + ] + }, + "LinuxKernelModuleMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "license": { + "type": "string" + }, + "kernelVersion": { + "type": "string" + }, + "versionMagic": { + "type": "string" + }, + "parameters": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/LinuxKernelModuleParameter" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "LinuxKernelModuleParameter": { + "properties": { + "type": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "type": "object" + }, + "LinuxRelease": { + "properties": { + "prettyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "idLike": { + "$ref": "#/$defs/IDLikes" + }, + "version": { + "type": "string" + }, + "versionID": { + "type": "string" + }, + "versionCodename": { + "type": "string" + }, + "buildID": { + "type": "string" + }, + "imageID": { + "type": "string" + }, + "imageVersion": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "variantID": { + "type": "string" + }, + "homeURL": { + "type": "string" + }, + "supportURL": { + "type": "string" + }, + "bugReportURL": { + "type": "string" + }, + "privacyPolicyURL": { + "type": "string" + }, + "cpeName": { + "type": "string" + }, + "supportEnd": { + "type": "string" + } + }, + "type": "object" + }, + "Location": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + }, + "annotations": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "MixLockMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "NixStoreMetadata": { + "properties": { + "outputHash": { + "type": "string" + }, + "output": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "outputHash", + "files" + ] + }, + "NpmPackageJSONMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "private": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "homepage", + "description", + "url", + "private" + ] + }, + "NpmPackageLockJSONMetadata": { + "properties": { + "resolved": { + "type": "string" + }, + "integrity": { + "type": "string" + } + }, + "type": "object", + "required": [ + "resolved", + "integrity" + ] + }, + "Package": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "foundBy": { + "type": "string" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + }, + "licenses": { + "$ref": "#/$defs/licenses" + }, + "language": { + "type": "string" + }, + "cpes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "purl": { + "type": "string" + }, + "metadataType": { + "type": "string" + }, + "metadata": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/AlpmMetadata" + }, + { + "$ref": "#/$defs/ApkMetadata" + }, + { + "$ref": "#/$defs/BinaryMetadata" + }, + { + "$ref": "#/$defs/CargoPackageMetadata" + }, + { + "$ref": "#/$defs/CocoapodsMetadata" + }, + { + "$ref": "#/$defs/ConanLockMetadata" + }, + { + "$ref": "#/$defs/ConanMetadata" + }, + { + "$ref": "#/$defs/DartPubMetadata" + }, + { + "$ref": "#/$defs/DotnetDepsMetadata" + }, + { + "$ref": "#/$defs/DotnetPortableExecutableMetadata" + }, + { + "$ref": "#/$defs/DpkgMetadata" + }, + { + "$ref": "#/$defs/GemMetadata" + }, + { + "$ref": "#/$defs/GolangBinMetadata" + }, + { + "$ref": "#/$defs/GolangModMetadata" + }, + { + "$ref": "#/$defs/HackageMetadata" + }, + { + "$ref": "#/$defs/JavaMetadata" + }, + { + "$ref": "#/$defs/KbPackageMetadata" + }, + { + "$ref": "#/$defs/LinuxKernelMetadata" + }, + { + "$ref": "#/$defs/LinuxKernelModuleMetadata" + }, + { + "$ref": "#/$defs/MixLockMetadata" + }, + { + "$ref": "#/$defs/NixStoreMetadata" + }, + { + "$ref": "#/$defs/NpmPackageJSONMetadata" + }, + { + "$ref": "#/$defs/NpmPackageLockJSONMetadata" + }, + { + "$ref": "#/$defs/PhpComposerJSONMetadata" + }, + { + "$ref": "#/$defs/PortageMetadata" + }, + { + "$ref": "#/$defs/PythonPackageMetadata" + }, + { + "$ref": "#/$defs/PythonPipfileLockMetadata" + }, + { + "$ref": "#/$defs/PythonRequirementsMetadata" + }, + { + "$ref": "#/$defs/RDescriptionFileMetadata" + }, + { + "$ref": "#/$defs/RebarLockMetadata" + }, + { + "$ref": "#/$defs/RpmMetadata" + }, + { + "$ref": "#/$defs/SwiftPackageManagerMetadata" + } + ] + } + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "foundBy", + "locations", + "licenses", + "language", + "cpes", + "purl" + ] + }, + "PhpComposerAuthors": { + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "PhpComposerExternalReference": { + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "shasum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "type", + "url", + "reference" + ] + }, + "PhpComposerJSONMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$ref": "#/$defs/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "dist" + ] + }, + "PomParent": { + "properties": { + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object", + "required": [ + "groupId", + "artifactId", + "version" + ] + }, + "PomProject": { + "properties": { + "path": { + "type": "string" + }, + "parent": { + "$ref": "#/$defs/PomParent" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "groupId", + "artifactId", + "version", + "name" + ] + }, + "PomProperties": { + "properties": { + "path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "extraFields": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path", + "name", + "groupId", + "artifactId", + "version" + ] + }, + "PortageFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PortageMetadata": { + "properties": { + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/PortageFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "installedSize", + "files" + ] + }, + "PythonDirectURLOriginInfo": { + "properties": { + "url": { + "type": "string" + }, + "commitId": { + "type": "string" + }, + "vcs": { + "type": "string" + } + }, + "type": "object", + "required": [ + "url" + ] + }, + "PythonFileDigest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "PythonFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/PythonFileDigest" + }, + "size": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PythonPackageMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/PythonFileRecord" + }, + "type": "array" + }, + "sitePackagesRootPath": { + "type": "string" + }, + "topLevelPackages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "directUrlOrigin": { + "$ref": "#/$defs/PythonDirectURLOriginInfo" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "platform", + "sitePackagesRootPath" + ] + }, + "PythonPipfileLockMetadata": { + "properties": { + "hashes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "index": { + "type": "string" + } + }, + "type": "object", + "required": [ + "hashes", + "index" + ] + }, + "PythonRequirementsMetadata": { + "properties": { + "name": { + "type": "string" + }, + "extras": { + "items": { + "type": "string" + }, + "type": "array" + }, + "versionConstraint": { + "type": "string" + }, + "url": { + "type": "string" + }, + "markers": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "versionConstraint" + ] + }, + "RDescriptionFileMetadata": { + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "url": { + "items": { + "type": "string" + }, + "type": "array" + }, + "repository": { + "type": "string" + }, + "built": { + "type": "string" + }, + "needsCompilation": { + "type": "boolean" + }, + "imports": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "suggests": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "RebarLockMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "Relationship": { + "properties": { + "parent": { + "type": "string" + }, + "child": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "parent", + "child", + "type" + ] + }, + "RpmMetadata": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/RpmdbFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "vendor", + "modularityLabel", + "files" + ] + }, + "RpmdbFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "mode": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "userName": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "flags": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "mode", + "size", + "digest", + "userName", + "groupName", + "flags" + ] + }, + "Schema": { + "properties": { + "version": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "version", + "url" + ] + }, + "SearchResult": { + "properties": { + "classification": { + "type": "string" + }, + "lineNumber": { + "type": "integer" + }, + "lineOffset": { + "type": "integer" + }, + "seekPosition": { + "type": "integer" + }, + "length": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "classification", + "lineNumber", + "lineOffset", + "seekPosition", + "length" + ] + }, + "Secrets": { + "properties": { + "location": { + "$ref": "#/$defs/Coordinates" + }, + "secrets": { + "items": { + "$ref": "#/$defs/SearchResult" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "location", + "secrets" + ] + }, + "Source": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "metadata" + ] + }, + "SwiftPackageManagerMetadata": { + "properties": { + "revision": { + "type": "string" + } + }, + "type": "object", + "required": [ + "revision" + ] + }, + "licenses": { + "items": { + "$ref": "#/$defs/License" + }, + "type": "array" + } + } +} From c570598e397d786cf5916dc5b1b8780461d6abae Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 10 Oct 2023 18:46:13 -0400 Subject: [PATCH 4/4] small refactor to remove duplicate code Signed-off-by: Alex Goodman --- syft/pkg/cataloger/deb/parse_dpkg_db.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/syft/pkg/cataloger/deb/parse_dpkg_db.go b/syft/pkg/cataloger/deb/parse_dpkg_db.go index 719cba1182f..03c66c5831d 100644 --- a/syft/pkg/cataloger/deb/parse_dpkg_db.go +++ b/syft/pkg/cataloger/deb/parse_dpkg_db.go @@ -266,20 +266,11 @@ func associateRelationships(pkgs []pkg.Package) (relationships []artifact.Relati continue } - for _, depSpecifier := range meta.PreDepends { - deps := splitPackageChoice(depSpecifier) - for _, dep := range deps { - for _, depPkg := range lookup[dep] { - relationships = append(relationships, artifact.Relationship{ - From: depPkg, - To: p, - Type: artifact.DependencyOfRelationship, - }) - } - } - } + var allDeps []string + allDeps = append(allDeps, meta.Depends...) + allDeps = append(allDeps, meta.PreDepends...) - for _, depSpecifier := range meta.Depends { + for _, depSpecifier := range allDeps { deps := splitPackageChoice(depSpecifier) for _, dep := range deps { for _, depPkg := range lookup[dep] {