aboutsummaryrefslogtreecommitdiff
path: root/licensediff/licensediff.go
blob: 98da0e56aa09b2b14ceaab0546d19ec9f1222521 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// 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"
)

// 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
}

// 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
}