@@ -17,10 +17,12 @@ limitations under the License.
1717package differs
1818
1919import (
20+ "errors"
2021 "strings"
2122
2223 pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util"
2324 "github.com/GoogleContainerTools/container-diff/util"
25+ "github.com/sirupsen/logrus"
2426)
2527
2628type MultiVersionPackageAnalyzer interface {
@@ -33,6 +35,11 @@ type SingleVersionPackageAnalyzer interface {
3335 Name () string
3436}
3537
38+ type SingleVersionPackageLayerAnalyzer interface {
39+ getPackages (image pkgutil.Image ) ([]map [string ]util.PackageInfo , error )
40+ Name () string
41+ }
42+
3643func multiVersionDiff (image1 , image2 pkgutil.Image , differ MultiVersionPackageAnalyzer ) (* util.MultiVersionPackageDiffResult , error ) {
3744 pack1 , err := differ .getPackages (image1 )
3845 if err != nil {
@@ -71,6 +78,13 @@ func singleVersionDiff(image1, image2 pkgutil.Image, differ SingleVersionPackage
7178 }, nil
7279}
7380
81+ // singleVersionLayerDiff returns an error as this diff is not supported as
82+ // it is far from obvious to define it in meaningful way
83+ func singleVersionLayerDiff (image1 , image2 pkgutil.Image , differ SingleVersionPackageLayerAnalyzer ) (* util.SingleVersionPackageLayerDiffResult , error ) {
84+ logrus .Warning ("'diff' command for packages on layers is not supported, consider using 'analyze' on each image instead" )
85+ return & util.SingleVersionPackageLayerDiffResult {}, errors .New ("Diff for packages on layers is not supported, only analysis is supported" )
86+ }
87+
7488func multiVersionAnalysis (image pkgutil.Image , analyzer MultiVersionPackageAnalyzer ) (* util.MultiVersionPackageAnalyzeResult , error ) {
7589 pack , err := analyzer .getPackages (image )
7690 if err != nil {
@@ -98,3 +112,39 @@ func singleVersionAnalysis(image pkgutil.Image, analyzer SingleVersionPackageAna
98112 }
99113 return & analysis , nil
100114}
115+
116+ // singleVersionLayerAnalysis returns the packages included, deleted or
117+ // updated in each layer
118+ func singleVersionLayerAnalysis (image pkgutil.Image , analyzer SingleVersionPackageLayerAnalyzer ) (* util.SingleVersionPackageLayerAnalyzeResult , error ) {
119+ pack , err := analyzer .getPackages (image )
120+ if err != nil {
121+ return & util.SingleVersionPackageLayerAnalyzeResult {}, err
122+ }
123+ var pkgDiffs []util.PackageDiff
124+
125+ // Each layer with modified packages includes a complete list of packages
126+ // in its package database. Thus we diff the current layer with the
127+ // previous one that contains a package database. Layers that do not
128+ // include a package database are omitted.
129+ preInd := - 1
130+ for i := range pack {
131+ var pkgDiff util.PackageDiff
132+ if preInd < 0 && len (pack [i ]) > 0 {
133+ pkgDiff = util .GetMapDiff (make (map [string ]util.PackageInfo ), pack [i ])
134+ preInd = i
135+ } else if preInd >= 0 && len (pack [i ]) > 0 {
136+ pkgDiff = util .GetMapDiff (pack [preInd ], pack [i ])
137+ preInd = i
138+ }
139+
140+ pkgDiffs = append (pkgDiffs , pkgDiff )
141+ }
142+
143+ return & util.SingleVersionPackageLayerAnalyzeResult {
144+ Image : image .Source ,
145+ AnalyzeType : strings .TrimSuffix (analyzer .Name (), "Analyzer" ),
146+ Analysis : util.PackageLayerDiff {
147+ PackageDiffs : pkgDiffs ,
148+ },
149+ }, nil
150+ }
0 commit comments