aboutsummaryrefslogtreecommitdiff
path: root/licensediff/licensediff.go
diff options
context:
space:
mode:
Diffstat (limited to 'licensediff/licensediff.go')
-rw-r--r--licensediff/licensediff.go139
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
+}