• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Package reporter contains functions to generate a basic license count
2// report from an in-memory SPDX Package section whose Files have been
3// analyzed.
4// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
5package reporter
6
7import (
8	"fmt"
9	"io"
10	"sort"
11	"text/tabwriter"
12
13	"github.com/spdx/tools-golang/spdx/v2_1"
14	"github.com/spdx/tools-golang/spdx/v2_2"
15	"github.com/spdx/tools-golang/spdx/v2_3"
16)
17
18// ===== 2.1 Reporter functions =====
19
20// Generate2_1 takes a Package whose Files have been analyzed and an
21// io.Writer, and outputs to the io.Writer a tabulated count of
22// the number of Files for each unique LicenseConcluded in the set.
23func Generate2_1(pkg *v2_1.Package, w io.Writer) error {
24	if pkg.FilesAnalyzed == false {
25		return fmt.Errorf("Package FilesAnalyzed is false")
26	}
27	totalFound, totalNotFound, foundCounts := countLicenses2_1(pkg)
28
29	wr := tabwriter.NewWriter(w, 0, 0, 2, ' ', tabwriter.AlignRight)
30
31	fmt.Fprintf(wr, "%d\t  License found\n", totalFound)
32	fmt.Fprintf(wr, "%d\t  License not found\n", totalNotFound)
33	fmt.Fprintf(wr, "%d\t  TOTAL\n", totalFound+totalNotFound)
34	fmt.Fprintf(wr, "\n")
35
36	counts := []struct {
37		lic   string
38		count int
39	}{}
40	for k, v := range foundCounts {
41		var entry struct {
42			lic   string
43			count int
44		}
45		entry.lic = k
46		entry.count = v
47		counts = append(counts, entry)
48	}
49
50	sort.Slice(counts, func(i, j int) bool { return counts[i].count > counts[j].count })
51
52	for _, c := range counts {
53		fmt.Fprintf(wr, "%d\t  %s\n", c.count, c.lic)
54	}
55	fmt.Fprintf(wr, "%d\t  TOTAL FOUND\n", totalFound)
56
57	wr.Flush()
58	return nil
59}
60
61func countLicenses2_1(pkg *v2_1.Package) (int, int, map[string]int) {
62	if pkg == nil || pkg.Files == nil {
63		return 0, 0, nil
64	}
65
66	totalFound := 0
67	totalNotFound := 0
68	foundCounts := map[string]int{}
69	for _, f := range pkg.Files {
70		if f.LicenseConcluded == "" || f.LicenseConcluded == "NOASSERTION" {
71			totalNotFound++
72		} else {
73			totalFound++
74			foundCounts[f.LicenseConcluded]++
75		}
76	}
77
78	return totalFound, totalNotFound, foundCounts
79}
80
81// ===== 2.2 Reporter functions =====
82
83// Generate2_2 takes a Package whose Files have been analyzed and an
84// io.Writer, and outputs to the io.Writer a tabulated count of
85// the number of Files for each unique LicenseConcluded in the set.
86func Generate2_2(pkg *v2_2.Package, w io.Writer) error {
87	if pkg.FilesAnalyzed == false {
88		return fmt.Errorf("Package FilesAnalyzed is false")
89	}
90	totalFound, totalNotFound, foundCounts := countLicenses2_2(pkg)
91
92	wr := tabwriter.NewWriter(w, 0, 0, 2, ' ', tabwriter.AlignRight)
93
94	fmt.Fprintf(wr, "%d\t  License found\n", totalFound)
95	fmt.Fprintf(wr, "%d\t  License not found\n", totalNotFound)
96	fmt.Fprintf(wr, "%d\t  TOTAL\n", totalFound+totalNotFound)
97	fmt.Fprintf(wr, "\n")
98
99	counts := []struct {
100		lic   string
101		count int
102	}{}
103	for k, v := range foundCounts {
104		var entry struct {
105			lic   string
106			count int
107		}
108		entry.lic = k
109		entry.count = v
110		counts = append(counts, entry)
111	}
112
113	sort.Slice(counts, func(i, j int) bool { return counts[i].count > counts[j].count })
114
115	for _, c := range counts {
116		fmt.Fprintf(wr, "%d\t  %s\n", c.count, c.lic)
117	}
118	fmt.Fprintf(wr, "%d\t  TOTAL FOUND\n", totalFound)
119
120	wr.Flush()
121	return nil
122}
123
124func countLicenses2_2(pkg *v2_2.Package) (int, int, map[string]int) {
125	if pkg == nil || pkg.Files == nil {
126		return 0, 0, nil
127	}
128
129	totalFound := 0
130	totalNotFound := 0
131	foundCounts := map[string]int{}
132	for _, f := range pkg.Files {
133		if f.LicenseConcluded == "" || f.LicenseConcluded == "NOASSERTION" {
134			totalNotFound++
135		} else {
136			totalFound++
137			foundCounts[f.LicenseConcluded]++
138		}
139	}
140
141	return totalFound, totalNotFound, foundCounts
142}
143
144// ===== 2.3 Reporter functions =====
145
146// Generate2_3 takes a Package whose Files have been analyzed and an
147// io.Writer, and outputs to the io.Writer a tabulated count of
148// the number of Files for each unique LicenseConcluded in the set.
149func Generate2_3(pkg *v2_3.Package, w io.Writer) error {
150	if pkg.FilesAnalyzed == false {
151		return fmt.Errorf("Package FilesAnalyzed is false")
152	}
153	totalFound, totalNotFound, foundCounts := countLicenses2_3(pkg)
154
155	wr := tabwriter.NewWriter(w, 0, 0, 2, ' ', tabwriter.AlignRight)
156
157	fmt.Fprintf(wr, "%d\t  License found\n", totalFound)
158	fmt.Fprintf(wr, "%d\t  License not found\n", totalNotFound)
159	fmt.Fprintf(wr, "%d\t  TOTAL\n", totalFound+totalNotFound)
160	fmt.Fprintf(wr, "\n")
161
162	counts := []struct {
163		lic   string
164		count int
165	}{}
166	for k, v := range foundCounts {
167		var entry struct {
168			lic   string
169			count int
170		}
171		entry.lic = k
172		entry.count = v
173		counts = append(counts, entry)
174	}
175
176	sort.Slice(counts, func(i, j int) bool { return counts[i].count > counts[j].count })
177
178	for _, c := range counts {
179		fmt.Fprintf(wr, "%d\t  %s\n", c.count, c.lic)
180	}
181	fmt.Fprintf(wr, "%d\t  TOTAL FOUND\n", totalFound)
182
183	wr.Flush()
184	return nil
185}
186
187func countLicenses2_3(pkg *v2_3.Package) (int, int, map[string]int) {
188	if pkg == nil || pkg.Files == nil {
189		return 0, 0, nil
190	}
191
192	totalFound := 0
193	totalNotFound := 0
194	foundCounts := map[string]int{}
195	for _, f := range pkg.Files {
196		if f.LicenseConcluded == "" || f.LicenseConcluded == "NOASSERTION" {
197			totalNotFound++
198		} else {
199			totalFound++
200			foundCounts[f.LicenseConcluded]++
201		}
202	}
203
204	return totalFound, totalNotFound, foundCounts
205}
206