diff options
Diffstat (limited to 'licensediff/licensediff.go')
-rw-r--r-- | licensediff/licensediff.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/licensediff/licensediff.go b/licensediff/licensediff.go new file mode 100644 index 0000000..ba8cd84 --- /dev/null +++ b/licensediff/licensediff.go @@ -0,0 +1,139 @@ +// 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 +} |