diff --git a/postal/buildpack.go b/postal/buildpack.go index 02a91a17..82b168c3 100644 --- a/postal/buildpack.go +++ b/postal/buildpack.go @@ -10,15 +10,24 @@ import ( // Dependency is a representation of a buildpack dependency. type Dependency struct { + // CPE is the Common Platform Enumerator for the dependency. + CPE string `toml:"cpe"` + // DeprecationDate is the data upon which this dependency is considered deprecated. DeprecationDate time.Time `toml:"deprecation_date"` // ID is the identifier used to specify the dependency. ID string `toml:"id"` + // Licenses is a list of SPDX license identifiers of licenses in the dependency. + Licenses []string `toml:"licenses"` + // Name is the human-readable name of the dependency. Name string `toml:"name"` + // PURL is the package URL for the dependency. + PURL string `toml:"purl"` + // SHA256 is the hex-encoded SHA256 checksum of the built dependency. SHA256 string `toml:"sha256"` diff --git a/postal/service.go b/postal/service.go index 91aed8ba..b89561b2 100644 --- a/postal/service.go +++ b/postal/service.go @@ -196,10 +196,22 @@ func (s Service) GenerateBillOfMaterials(dependencies ...Dependency) []packit.BO }, } + if dependency.CPE != "" { + entry.Metadata["cpe"] = dependency.CPE + } + if (dependency.DeprecationDate != time.Time{}) { entry.Metadata["deprecation-date"] = dependency.DeprecationDate } + if dependency.Licenses != nil { + entry.Metadata["licenses"] = dependency.Licenses + } + + if dependency.PURL != "" { + entry.Metadata["purl"] = dependency.PURL + } + entries = append(entries, entry) } diff --git a/postal/service_test.go b/postal/service_test.go index 8dfaeebb..034c9658 100644 --- a/postal/service_test.go +++ b/postal/service_test.go @@ -957,25 +957,17 @@ version = "this is super not semver" }) context("GenerateBillOfMaterials", func() { - var deprecationDate time.Time - - it.Before(func() { - var err error - deprecationDate, err = time.Parse(time.RFC3339, "2022-04-01T00:00:00Z") - Expect(err).NotTo(HaveOccurred()) - }) it("returns a list of BOMEntry values", func() { entries := service.GenerateBillOfMaterials( postal.Dependency{ - DeprecationDate: deprecationDate, - ID: "some-entry", - Name: "Some Entry", - SHA256: "some-sha", - Source: "some-source", - Stacks: []string{"some-stack"}, - URI: "some-uri", - Version: "1.2.3", + ID: "some-entry", + Name: "Some Entry", + SHA256: "some-sha", + Source: "some-source", + Stacks: []string{"some-stack"}, + URI: "some-uri", + Version: "1.2.3", }, postal.Dependency{ ID: "other-entry", @@ -991,11 +983,10 @@ version = "this is super not semver" { Name: "Some Entry", Metadata: map[string]interface{}{ - "deprecation-date": deprecationDate, - "sha256": "some-sha", - "stacks": []string{"some-stack"}, - "uri": "some-uri", - "version": "1.2.3", + "sha256": "some-sha", + "stacks": []string{"some-stack"}, + "uri": "some-uri", + "version": "1.2.3", }, }, { @@ -1009,5 +1000,133 @@ version = "this is super not semver" }, })) }) + + context("when there is a CPE", func() { + it("generates a BOM with the CPE", func() { + entries := service.GenerateBillOfMaterials( + postal.Dependency{ + CPE: "some-cpe", + ID: "some-entry", + Name: "Some Entry", + SHA256: "some-sha", + Source: "some-source", + Stacks: []string{"some-stack"}, + URI: "some-uri", + Version: "1.2.3", + }, + ) + + Expect(entries).To(Equal([]packit.BOMEntry{ + { + Name: "Some Entry", + Metadata: map[string]interface{}{ + "cpe": "some-cpe", + "sha256": "some-sha", + "stacks": []string{"some-stack"}, + "uri": "some-uri", + "version": "1.2.3", + }, + }, + })) + }) + }) + + context("when there is a deprecation date", func() { + var deprecationDate time.Time + + it.Before(func() { + var err error + deprecationDate, err = time.Parse(time.RFC3339, "2022-04-01T00:00:00Z") + Expect(err).NotTo(HaveOccurred()) + }) + + it("generates a BOM with the deprecation date", func() { + entries := service.GenerateBillOfMaterials( + postal.Dependency{ + DeprecationDate: deprecationDate, + ID: "some-entry", + Name: "Some Entry", + SHA256: "some-sha", + Source: "some-source", + Stacks: []string{"some-stack"}, + URI: "some-uri", + Version: "1.2.3", + }, + ) + + Expect(entries).To(Equal([]packit.BOMEntry{ + { + Name: "Some Entry", + Metadata: map[string]interface{}{ + "deprecation-date": deprecationDate, + "sha256": "some-sha", + "stacks": []string{"some-stack"}, + "uri": "some-uri", + "version": "1.2.3", + }, + }, + })) + }) + }) + + context("when there is license information", func() { + it("generates a BOM with the license information", func() { + entries := service.GenerateBillOfMaterials( + postal.Dependency{ + ID: "some-entry", + Licenses: []string{"some-license"}, + Name: "Some Entry", + SHA256: "some-sha", + Source: "some-source", + Stacks: []string{"some-stack"}, + URI: "some-uri", + Version: "1.2.3", + }, + ) + + Expect(entries).To(Equal([]packit.BOMEntry{ + { + Name: "Some Entry", + Metadata: map[string]interface{}{ + "licenses": []string{"some-license"}, + "sha256": "some-sha", + "stacks": []string{"some-stack"}, + "uri": "some-uri", + "version": "1.2.3", + }, + }, + })) + }) + }) + + context("when there is a pURL", func() { + it("generates a BOM with the pURL", func() { + entries := service.GenerateBillOfMaterials( + postal.Dependency{ + ID: "some-entry", + Name: "Some Entry", + PURL: "some-purl", + SHA256: "some-sha", + Source: "some-source", + Stacks: []string{"some-stack"}, + URI: "some-uri", + Version: "1.2.3", + }, + ) + + Expect(entries).To(Equal([]packit.BOMEntry{ + { + Name: "Some Entry", + Metadata: map[string]interface{}{ + "purl": "some-purl", + "sha256": "some-sha", + "stacks": []string{"some-stack"}, + "uri": "some-uri", + "version": "1.2.3", + }, + }, + })) + }) + }) }) }