150 lines
5.6 KiB
Go
150 lines
5.6 KiB
Go
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
|
|
|
// Example for: *idsearcher*, *tvsaver*
|
|
|
|
// This example demonstrates building an SPDX document for a directory's
|
|
// contents (implicitly using *builder*); searching through that directory for
|
|
// [SPDX short-form IDs](https://spdx.org/ids/); filling those IDs into the
|
|
// document's Package and File license fields; and saving the resulting document
|
|
// to disk.
|
|
// Run project: go run example_search.go project2 ../../testdata/project2/folder test.spdx
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spdx/tools-golang/idsearcher"
|
|
|
|
"github.com/spdx/tools-golang/tvsaver"
|
|
)
|
|
|
|
func main() {
|
|
|
|
// check that we've received the right number of arguments
|
|
args := os.Args
|
|
if len(args) != 4 {
|
|
fmt.Printf("Usage: %v <package-name> <package-root-dir> <spdx-file-out>\n", args[0])
|
|
fmt.Printf(" Build a SPDX 2.2 document with one package called <package-name>;\n")
|
|
fmt.Printf(" create files with hashes corresponding to the files in <package-root-dir>;\n")
|
|
fmt.Printf(" search for SPDX short-form IDs, and use them to fill in license data\n")
|
|
fmt.Printf(" where possible; and save it out as a tag-value file to <spdx-file-out>.\n")
|
|
return
|
|
}
|
|
|
|
// get the command-line arguments
|
|
packageName := args[1]
|
|
packageRootDir := args[2]
|
|
fileOut := args[3]
|
|
|
|
// to use the SPDX idsearcher package, the first step is to define a
|
|
// idsearcher.Config2_2 struct. this config data can be reused, in case you
|
|
// are building SPDX documents for several directories in sequence.
|
|
config := &idsearcher.Config2_2{
|
|
|
|
// NamespacePrefix is a prefix that will be used to populate the
|
|
// mandatory DocumentNamespace field in the Creation Info section.
|
|
// Because it needs to be unique, the value that will be filled in
|
|
// for the document will have the package name and verification code
|
|
// appended to this prefix.
|
|
NamespacePrefix: "https://example.com/whatever/testdata-",
|
|
|
|
// CreatorType and Creator, from builder.Config2_2, are not needed for
|
|
// idsearcher.Config2_2. Because it is automated and doesn't assume
|
|
// further review, the following two Creator fields are filled in:
|
|
// Creator: Tool: github.com/spdx/tools-golang/builder
|
|
// Creator: Tool: github.com/spdx/tools-golang/idsearcher
|
|
|
|
// You can define one or more paths that should be ignored
|
|
// when walking through the directory. This is intended to omit files
|
|
// that are located within the package's directory, but which should
|
|
// be omitted from the SPDX document.
|
|
// This is directly passed through to builder, and uses the same
|
|
// format as shown in examples/3-build/example_build.go.
|
|
BuilderPathsIgnored: []string{
|
|
|
|
// ignore all files in the .git/ directory at the package root
|
|
"/.git/",
|
|
|
|
// ignore all files in all __pycache__/ directories, anywhere
|
|
// within the package directory tree
|
|
"**/__pycache__/",
|
|
|
|
// ignore the file with this specific path relative to the
|
|
// package root
|
|
"/.ignorefile",
|
|
|
|
// or ignore all files with this filename, anywhere within the
|
|
// package directory tree
|
|
"**/.DS_Store",
|
|
},
|
|
|
|
// Finally, SearcherPathsIgnored lists certain paths that should not be
|
|
// searched by idsearcher, even if those paths have Files present (and
|
|
// had files filled in by builder). This is useful, for instance, if
|
|
// your project has some directories or files with
|
|
// "SPDX-License-Identifier:" tags, but for one reason or another you
|
|
// want to exclude those files' tags from being picked up by the
|
|
// searcher.
|
|
// SearcherPathsIgnored uses the same format as BuilderPathsIgnored.
|
|
SearcherPathsIgnored: []string{
|
|
|
|
// Example for the Linux kernel: ignore the documentation file
|
|
// which explains how to use SPDX short-form IDs (and therefore
|
|
// has a bunch of "SPDX-License-Identifier:" tags that we wouldn't
|
|
// want to pick up).
|
|
"/Documentation/process/license-rules.rst",
|
|
|
|
// Similar example for the Linux kernel: ignore all files in the
|
|
// /LICENSES/ directory.
|
|
"/LICENSES/",
|
|
},
|
|
}
|
|
|
|
// now, when we actually ask idsearcher to walk through a directory and
|
|
// build an SPDX document, we need to give it three things:
|
|
// - what to name the package; and
|
|
// - where the directory is located on disk; and
|
|
// - the config object we just defined.
|
|
// these are the same arguments needed for builder, and in fact they get
|
|
// passed through to builder (with the relevant data from the config
|
|
// object extracted behind the scenes).
|
|
doc, err := idsearcher.BuildIDsDocument2_2(packageName, packageRootDir, config)
|
|
if err != nil {
|
|
fmt.Printf("Error while building document: %v\n", err)
|
|
return
|
|
}
|
|
|
|
// if we got here, the document has been created.
|
|
// all file hashes and the package verification code have been filled in
|
|
// appropriately by builder.
|
|
// And, all files with "SPDX-License-Identifier:" tags have had their
|
|
// licenses extracted into LicenseInfoInFiles and LicenseConcluded for
|
|
// each file by idsearcher. The PackageLicenseInfoFromFiles field will
|
|
// also be filled in with all license identifiers.
|
|
fmt.Printf("Successfully created document and searched for IDs for package %s\n", packageName)
|
|
|
|
// NOTE that BuildIDsDocument does NOT do any validation of the license
|
|
// identifiers, to confirm that they are e.g. on the SPDX License List
|
|
// or in other appropriate format (e.g., LicenseRef-...)
|
|
|
|
// we can now save it to disk, using tvsaver.
|
|
|
|
// create a new file for writing
|
|
w, err := os.Create(fileOut)
|
|
if err != nil {
|
|
fmt.Printf("Error while opening %v for writing: %v\n", fileOut, err)
|
|
return
|
|
}
|
|
defer w.Close()
|
|
|
|
err = tvsaver.Save2_2(doc, w)
|
|
if err != nil {
|
|
fmt.Printf("Error while saving %v: %v", fileOut, err)
|
|
return
|
|
}
|
|
|
|
fmt.Printf("Successfully saved %v\n", fileOut)
|
|
}
|