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