@@ -8,11 +8,13 @@ import (
88 "github.com/paketo-buildpacks/packit/v2"
99 "github.com/paketo-buildpacks/packit/v2/chronos"
1010 "github.com/paketo-buildpacks/packit/v2/fs"
11+ "github.com/paketo-buildpacks/packit/v2/sbom"
1112 "github.com/paketo-buildpacks/packit/v2/scribe"
1213)
1314
1415//go:generate faux --interface InstallProcess --output fakes/install_process.go
1516//go:generate faux --interface EntryResolver --output fakes/entry_resolver.go
17+ //go:generate faux --interface SBOMGenerator --output fakes/sbom_generator.go
1618
1719// InstallProcess defines the interface for executing the "bundle install"
1820// build process.
@@ -27,6 +29,10 @@ type EntryResolver interface {
2729 MergeLayerTypes (string , []packit.BuildpackPlanEntry ) (launch , build bool )
2830}
2931
32+ type SBOMGenerator interface {
33+ Generate (dir string ) (sbom.SBOM , error )
34+ }
35+
3036// Build will return a packit.BuildFunc that will be invoked during the build
3137// phase of the buildpack lifecycle.
3238//
@@ -63,7 +69,13 @@ type EntryResolver interface {
6369// configuration from the global location, which will be configured to point to
6470// a file that is maintained in each of the build and launch layers
6571// respectively.
66- func Build (installProcess InstallProcess , logger scribe.Emitter , clock chronos.Clock , entries EntryResolver ) packit.BuildFunc {
72+ func Build (
73+ entries EntryResolver ,
74+ installProcess InstallProcess ,
75+ sbomGenerator SBOMGenerator ,
76+ logger scribe.Emitter ,
77+ clock chronos.Clock ,
78+ ) packit.BuildFunc {
6779 return func (context packit.BuildContext ) (packit.BuildResult , error ) {
6880 logger .Title ("%s %s" , context .BuildpackInfo .Name , context .BuildpackInfo .Version )
6981
@@ -111,6 +123,26 @@ func Build(installProcess InstallProcess, logger scribe.Emitter, clock chronos.C
111123 "cache_sha" : checksum ,
112124 "ruby_version" : rubyVersion ,
113125 }
126+
127+ logger .GeneratingSBOM (layer .Path )
128+
129+ var sbomContent sbom.SBOM
130+ duration , err = clock .Measure (func () error {
131+ sbomContent , err = sbomGenerator .Generate (context .WorkingDir )
132+ return err
133+ })
134+ if err != nil {
135+ return packit.BuildResult {}, err
136+ }
137+ logger .Action ("Completed in %s" , duration .Round (time .Millisecond ))
138+ logger .Break ()
139+
140+ logger .FormattingSBOM (context .BuildpackInfo .SBOMFormats ... )
141+
142+ layer .SBOM , err = sbomContent .InFormats (context .BuildpackInfo .SBOMFormats ... )
143+ if err != nil {
144+ return packit.BuildResult {}, err
145+ }
114146 } else {
115147 logger .Process ("Reusing cached layer %s" , layer .Path )
116148 logger .Break ()
@@ -171,6 +203,26 @@ func Build(installProcess InstallProcess, logger scribe.Emitter, clock chronos.C
171203 "cache_sha" : checksum ,
172204 "ruby_version" : rubyVersion ,
173205 }
206+
207+ logger .GeneratingSBOM (layer .Path )
208+
209+ var sbomContent sbom.SBOM
210+ duration , err = clock .Measure (func () error {
211+ sbomContent , err = sbomGenerator .Generate (context .WorkingDir )
212+ return err
213+ })
214+ if err != nil {
215+ return packit.BuildResult {}, err
216+ }
217+ logger .Action ("Completed in %s" , duration .Round (time .Millisecond ))
218+ logger .Break ()
219+
220+ logger .FormattingSBOM (context .BuildpackInfo .SBOMFormats ... )
221+
222+ layer .SBOM , err = sbomContent .InFormats (context .BuildpackInfo .SBOMFormats ... )
223+ if err != nil {
224+ return packit.BuildResult {}, err
225+ }
174226 } else {
175227 logger .Process ("Reusing cached layer %s" , layer .Path )
176228 logger .Break ()
0 commit comments