// Package licensediff is used to generate a "diff" between the concluded // licenses in two SPDX Packages, using the filename as the match point. // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later package licensediff import ( "github.com/spdx/tools-golang/spdx/v2_1" "github.com/spdx/tools-golang/spdx/v2_2" "github.com/spdx/tools-golang/spdx/v2_3" ) // LicensePair is a result set where we are talking about two license strings, // potentially differing, for a single filename between two SPDX Packages. type LicensePair struct { First string Second string } // MakePairs2_1 essentially just consolidates all files and LicenseConcluded // strings into a single data structure. func MakePairs2_1(p1 *v2_1.Package, p2 *v2_1.Package) (map[string]LicensePair, error) { pairs := map[string]LicensePair{} // first, go through and add all files/licenses from p1 for _, f := range p1.Files { pair := LicensePair{First: f.LicenseConcluded, Second: ""} pairs[f.FileName] = pair } // now, go through all files/licenses from p2. If already // present, add as .second; if not, create new pair for _, f := range p2.Files { firstLic := "" existingPair, ok := pairs[f.FileName] if ok { // already present; update it firstLic = existingPair.First } // now, update what's there, either way pair := LicensePair{First: firstLic, Second: f.LicenseConcluded} pairs[f.FileName] = pair } return pairs, nil } // MakePairs2_2 essentially just consolidates all files and LicenseConcluded // strings into a single data structure. func MakePairs2_2(p1 *v2_2.Package, p2 *v2_2.Package) (map[string]LicensePair, error) { pairs := map[string]LicensePair{} // first, go through and add all files/licenses from p1 for _, f := range p1.Files { pair := LicensePair{First: f.LicenseConcluded, Second: ""} pairs[f.FileName] = pair } // now, go through all files/licenses from p2. If already // present, add as .second; if not, create new pair for _, f := range p2.Files { firstLic := "" existingPair, ok := pairs[f.FileName] if ok { // already present; update it firstLic = existingPair.First } // now, update what's there, either way pair := LicensePair{First: firstLic, Second: f.LicenseConcluded} pairs[f.FileName] = pair } return pairs, nil } // MakePairs2_3 essentially just consolidates all files and LicenseConcluded // strings into a single data structure. func MakePairs2_3(p1 *v2_3.Package, p2 *v2_3.Package) (map[string]LicensePair, error) { pairs := map[string]LicensePair{} // first, go through and add all files/licenses from p1 for _, f := range p1.Files { pair := LicensePair{First: f.LicenseConcluded, Second: ""} pairs[f.FileName] = pair } // now, go through all files/licenses from p2. If already // present, add as .second; if not, create new pair for _, f := range p2.Files { firstLic := "" existingPair, ok := pairs[f.FileName] if ok { // already present; update it firstLic = existingPair.First } // now, update what's there, either way pair := LicensePair{First: firstLic, Second: f.LicenseConcluded} pairs[f.FileName] = pair } return pairs, nil } // LicenseDiff is a structured version of the output of MakePairs. It is // meant to make it easier to find and report on, e.g., just the files that // have different licenses, or those that are in just one scan. type LicenseDiff struct { InBothChanged map[string]LicensePair InBothSame map[string]string InFirstOnly map[string]string InSecondOnly map[string]string } // MakeResults creates a more structured set of results from the output // of MakePairs. func MakeResults(pairs map[string]LicensePair) (*LicenseDiff, error) { diff := &LicenseDiff{ InBothChanged: map[string]LicensePair{}, InBothSame: map[string]string{}, InFirstOnly: map[string]string{}, InSecondOnly: map[string]string{}, } // walk through pairs and allocate them where they belong for filename, pair := range pairs { if pair.First == pair.Second { diff.InBothSame[filename] = pair.First } else { if pair.First == "" { diff.InSecondOnly[filename] = pair.Second } else if pair.Second == "" { diff.InFirstOnly[filename] = pair.First } else { diff.InBothChanged[filename] = pair } } } return diff, nil }