xref: /aosp_15_r20/external/spdx-tools/examples/1-load/example_load.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1*ba677afaSXin Li// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2*ba677afaSXin Li
3*ba677afaSXin Li// Example for: *tvloader*, *spdx*
4*ba677afaSXin Li
5*ba677afaSXin Li// This example demonstrates loading an SPDX tag-value file from disk into
6*ba677afaSXin Li// memory, and printing some of its contents to standard output.
7*ba677afaSXin Li// Run project:  go run example_load.go ../sample-docs/tv/hello.spdx
8*ba677afaSXin Li
9*ba677afaSXin Lipackage main
10*ba677afaSXin Li
11*ba677afaSXin Liimport (
12*ba677afaSXin Li	"fmt"
13*ba677afaSXin Li	"os"
14*ba677afaSXin Li
15*ba677afaSXin Li	"github.com/spdx/tools-golang/spdxlib"
16*ba677afaSXin Li	"github.com/spdx/tools-golang/tvloader"
17*ba677afaSXin Li)
18*ba677afaSXin Li
19*ba677afaSXin Lifunc main() {
20*ba677afaSXin Li
21*ba677afaSXin Li	// check that we've received the right number of arguments
22*ba677afaSXin Li	args := os.Args
23*ba677afaSXin Li	if len(args) != 2 {
24*ba677afaSXin Li		fmt.Printf("Usage: %v <spdx-file-in>\n", args[0])
25*ba677afaSXin Li		fmt.Printf("  Load SPDX 2.2 tag-value file <spdx-file-in>, and\n")
26*ba677afaSXin Li		fmt.Printf("  print a portion of its contents.\n")
27*ba677afaSXin Li		return
28*ba677afaSXin Li	}
29*ba677afaSXin Li
30*ba677afaSXin Li	// open the SPDX file
31*ba677afaSXin Li	filename := args[1]
32*ba677afaSXin Li	r, err := os.Open(filename)
33*ba677afaSXin Li	if err != nil {
34*ba677afaSXin Li		fmt.Printf("Error while opening %v for reading: %v", filename, err)
35*ba677afaSXin Li		return
36*ba677afaSXin Li	}
37*ba677afaSXin Li	defer r.Close()
38*ba677afaSXin Li
39*ba677afaSXin Li	// try to load the SPDX file's contents as a tag-value file, version 2.2
40*ba677afaSXin Li	doc, err := tvloader.Load2_2(r)
41*ba677afaSXin Li	if err != nil {
42*ba677afaSXin Li		fmt.Printf("Error while parsing %v: %v", filename, err)
43*ba677afaSXin Li		return
44*ba677afaSXin Li	}
45*ba677afaSXin Li
46*ba677afaSXin Li	// if we got here, the file is now loaded into memory.
47*ba677afaSXin Li	fmt.Printf("Successfully loaded %s\n\n", filename)
48*ba677afaSXin Li
49*ba677afaSXin Li	// we can now take a look at its contents via the various data
50*ba677afaSXin Li	// structures representing the SPDX document's sections.
51*ba677afaSXin Li
52*ba677afaSXin Li	// print the struct containing the SPDX file's Creation Info section data
53*ba677afaSXin Li	fmt.Printf("==============\n")
54*ba677afaSXin Li	fmt.Printf("Creation info:\n")
55*ba677afaSXin Li	fmt.Printf("==============\n")
56*ba677afaSXin Li	fmt.Printf("%#v\n\n", doc.CreationInfo)
57*ba677afaSXin Li
58*ba677afaSXin Li	// check whether the SPDX file has at least one package that it describes
59*ba677afaSXin Li	pkgIDs, err := spdxlib.GetDescribedPackageIDs2_2(doc)
60*ba677afaSXin Li	if err != nil {
61*ba677afaSXin Li		fmt.Printf("Unable to get describe packages from SPDX document: %v\n", err)
62*ba677afaSXin Li		return
63*ba677afaSXin Li	}
64*ba677afaSXin Li
65*ba677afaSXin Li	if len(pkgIDs) == 0 {
66*ba677afaSXin Li		return
67*ba677afaSXin Li	}
68*ba677afaSXin Li
69*ba677afaSXin Li	// it does, so we'll go through each one
70*ba677afaSXin Li	for _, pkg := range doc.Packages {
71*ba677afaSXin Li		var documentDescribesPackage bool
72*ba677afaSXin Li		for _, describedPackageID := range pkgIDs {
73*ba677afaSXin Li			if pkg.PackageSPDXIdentifier == describedPackageID {
74*ba677afaSXin Li				documentDescribesPackage = true
75*ba677afaSXin Li				break
76*ba677afaSXin Li			}
77*ba677afaSXin Li		}
78*ba677afaSXin Li
79*ba677afaSXin Li		if !documentDescribesPackage {
80*ba677afaSXin Li			continue
81*ba677afaSXin Li		}
82*ba677afaSXin Li
83*ba677afaSXin Li		pkgID := pkg.PackageSPDXIdentifier
84*ba677afaSXin Li
85*ba677afaSXin Li		// check whether the package had its files analyzed
86*ba677afaSXin Li		if !pkg.FilesAnalyzed {
87*ba677afaSXin Li			fmt.Printf("Package %s (%s) had FilesAnalyzed: false\n", string(pkgID), pkg.PackageName)
88*ba677afaSXin Li			continue
89*ba677afaSXin Li		}
90*ba677afaSXin Li
91*ba677afaSXin Li		// also check whether the package has any files present
92*ba677afaSXin Li		if pkg.Files == nil || len(pkg.Files) < 1 {
93*ba677afaSXin Li			fmt.Printf("Package %s (%s) has no Files\n", string(pkgID), pkg.PackageName)
94*ba677afaSXin Li			continue
95*ba677afaSXin Li		}
96*ba677afaSXin Li
97*ba677afaSXin Li		// if we got here, there's at least one file
98*ba677afaSXin Li		// print the filename and license info for the first 50
99*ba677afaSXin Li		fmt.Printf("============================\n")
100*ba677afaSXin Li		fmt.Printf("Package %s (%s)\n", string(pkgID), pkg.PackageName)
101*ba677afaSXin Li		fmt.Printf("File info (up to first 50):\n")
102*ba677afaSXin Li		i := 1
103*ba677afaSXin Li		for _, f := range pkg.Files {
104*ba677afaSXin Li			// note that these will be in random order, since we're pulling
105*ba677afaSXin Li			// from a map. if we care about order, we should first pull the
106*ba677afaSXin Li			// IDs into a slice, sort it, and then print the ordered files.
107*ba677afaSXin Li			fmt.Printf("- File %d: %s\n", i, f.FileName)
108*ba677afaSXin Li			fmt.Printf("    License from file: %v\n", f.LicenseInfoInFiles)
109*ba677afaSXin Li			fmt.Printf("    License concluded: %v\n", f.LicenseConcluded)
110*ba677afaSXin Li			i++
111*ba677afaSXin Li			if i > 50 {
112*ba677afaSXin Li				break
113*ba677afaSXin Li			}
114*ba677afaSXin Li		}
115*ba677afaSXin Li	}
116*ba677afaSXin Li}
117