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