xref: /aosp_15_r20/external/spdx-tools/examples/3-build/example_build.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: *builder*, *tvsaver*
4*ba677afaSXin Li
5*ba677afaSXin Li// This example demonstrates building an 'empty' SPDX document in memory that
6*ba677afaSXin Li// corresponds to a given directory's contents, including all files with their
7*ba677afaSXin Li// hashes and the package's verification code, and saving the document to disk.
8*ba677afaSXin Li// Run project: go run example_build.go project2 ../../testdata/project2 test.spdx
9*ba677afaSXin Li
10*ba677afaSXin Lipackage main
11*ba677afaSXin Li
12*ba677afaSXin Liimport (
13*ba677afaSXin Li	"fmt"
14*ba677afaSXin Li	"os"
15*ba677afaSXin Li
16*ba677afaSXin Li	"github.com/spdx/tools-golang/builder"
17*ba677afaSXin Li	"github.com/spdx/tools-golang/tvsaver"
18*ba677afaSXin Li)
19*ba677afaSXin Li
20*ba677afaSXin Lifunc main() {
21*ba677afaSXin Li
22*ba677afaSXin Li	// check that we've received the right number of arguments
23*ba677afaSXin Li	args := os.Args
24*ba677afaSXin Li	if len(args) != 4 {
25*ba677afaSXin Li		fmt.Printf("Usage: %v <package-name> <package-root-dir> <spdx-file-out>\n", args[0])
26*ba677afaSXin Li		fmt.Printf("  Build a SPDX 2.2 document with one package called <package-name>;\n")
27*ba677afaSXin Li		fmt.Printf("  create files with hashes corresponding to the files in <package-root-dir>;\n")
28*ba677afaSXin Li		fmt.Printf("  and save it out as a tag-value file to <spdx-file-out>.\n")
29*ba677afaSXin Li		return
30*ba677afaSXin Li	}
31*ba677afaSXin Li
32*ba677afaSXin Li	// get the command-line arguments
33*ba677afaSXin Li	packageName := args[1]
34*ba677afaSXin Li	packageRootDir := args[2]
35*ba677afaSXin Li	fileOut := args[3]
36*ba677afaSXin Li
37*ba677afaSXin Li	// to use the SPDX builder package, the first step is to define a
38*ba677afaSXin Li	// builder.Config2_2 struct. this config data can be reused, in case you
39*ba677afaSXin Li	// are building SPDX documents for several directories in sequence.
40*ba677afaSXin Li	config := &builder.Config2_2{
41*ba677afaSXin Li
42*ba677afaSXin Li		// NamespacePrefix is a prefix that will be used to populate the
43*ba677afaSXin Li		// mandatory DocumentNamespace field in the Creation Info section.
44*ba677afaSXin Li		// Because it needs to be unique, the value that will be filled in
45*ba677afaSXin Li		// for the document will have the package name and verification code
46*ba677afaSXin Li		// appended to this prefix.
47*ba677afaSXin Li		NamespacePrefix: "https://example.com/whatever/testdata-",
48*ba677afaSXin Li
49*ba677afaSXin Li		// CreatorType will be used for the first part of the Creator field
50*ba677afaSXin Li		// in the Creation Info section. Per the SPDX spec, it can be
51*ba677afaSXin Li		// "Person", "Organization" or "Tool".
52*ba677afaSXin Li		CreatorType: "Person",
53*ba677afaSXin Li
54*ba677afaSXin Li		// Creator will be used for the second part of the Creator field in
55*ba677afaSXin Li		// the Creation Info section.
56*ba677afaSXin Li		Creator: "Jane Doe",
57*ba677afaSXin Li
58*ba677afaSXin Li		// note that builder will also add the following, in addition to the
59*ba677afaSXin Li		// Creator defined above:
60*ba677afaSXin Li		// Creator: Tool: github.com/spdx/tools-golang/builder
61*ba677afaSXin Li
62*ba677afaSXin Li		// Finally, you can define one or more paths that should be ignored
63*ba677afaSXin Li		// when walking through the directory. This is intended to omit files
64*ba677afaSXin Li		// that are located within the package's directory, but which should
65*ba677afaSXin Li		// be omitted from the SPDX document.
66*ba677afaSXin Li		PathsIgnored: []string{
67*ba677afaSXin Li
68*ba677afaSXin Li			// ignore all files in the .git/ directory at the package root
69*ba677afaSXin Li			"/.git/",
70*ba677afaSXin Li
71*ba677afaSXin Li			// ignore all files in all __pycache__/ directories, anywhere
72*ba677afaSXin Li			// within the package directory tree
73*ba677afaSXin Li			"**/__pycache__/",
74*ba677afaSXin Li
75*ba677afaSXin Li			// ignore the file with this specific path relative to the
76*ba677afaSXin Li			// package root
77*ba677afaSXin Li			"/.ignorefile",
78*ba677afaSXin Li
79*ba677afaSXin Li			// or ignore all files with this filename, anywhere within the
80*ba677afaSXin Li			// package directory tree
81*ba677afaSXin Li			"**/.DS_Store",
82*ba677afaSXin Li		},
83*ba677afaSXin Li	}
84*ba677afaSXin Li
85*ba677afaSXin Li	// now, when we actually ask builder to walk through a directory and
86*ba677afaSXin Li	// build an SPDX document, we need to give it three things:
87*ba677afaSXin Li	//   - what to name the package; and
88*ba677afaSXin Li	//   - where the directory is located on disk; and
89*ba677afaSXin Li	//   - the config object we just defined.
90*ba677afaSXin Li	doc, err := builder.Build2_2(packageName, packageRootDir, config)
91*ba677afaSXin Li	if err != nil {
92*ba677afaSXin Li		fmt.Printf("Error while building document: %v\n", err)
93*ba677afaSXin Li		return
94*ba677afaSXin Li	}
95*ba677afaSXin Li
96*ba677afaSXin Li	// if we got here, the document has been created.
97*ba677afaSXin Li	// all license info is marked as NOASSERTION, but file hashes and
98*ba677afaSXin Li	// the package verification code have been filled in appropriately.
99*ba677afaSXin Li	fmt.Printf("Successfully created document for package %s\n", packageName)
100*ba677afaSXin Li
101*ba677afaSXin Li	// we can now save it to disk, using tvsaver.
102*ba677afaSXin Li
103*ba677afaSXin Li	// create a new file for writing
104*ba677afaSXin Li	w, err := os.Create(fileOut)
105*ba677afaSXin Li	if err != nil {
106*ba677afaSXin Li		fmt.Printf("Error while opening %v for writing: %v\n", fileOut, err)
107*ba677afaSXin Li		return
108*ba677afaSXin Li	}
109*ba677afaSXin Li	defer w.Close()
110*ba677afaSXin Li
111*ba677afaSXin Li	err = tvsaver.Save2_2(doc, w)
112*ba677afaSXin Li	if err != nil {
113*ba677afaSXin Li		fmt.Printf("Error while saving %v: %v", fileOut, err)
114*ba677afaSXin Li		return
115*ba677afaSXin Li	}
116*ba677afaSXin Li
117*ba677afaSXin Li	fmt.Printf("Successfully saved %v\n", fileOut)
118*ba677afaSXin Li}
119