aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorSteve Winslow <swinslow@gmail.com>2018-10-24 17:46:56 -0400
committerGitHub <noreply@github.com>2018-10-24 17:46:56 -0400
commit941fa33ea499c1f9092818a264a38600efe1acce (patch)
tree27f7bbf471ef74dbde5a01003862d80aa198bcc9 /examples
parentd4c19259c711d59d26040295112d6d2fd618faa1 (diff)
downloadspdx-tools-941fa33ea499c1f9092818a264a38600efe1acce.tar.gz
Added examples (#29)
Closes #27 Signed-off-by: Steve Winslow <swinslow@gmail.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/1-load/example_load.go92
-rw-r--r--examples/2-load-save/example_load_save.go68
-rw-r--r--examples/3-build/example_build.go117
-rw-r--r--examples/4-search/example_search.go148
-rw-r--r--examples/5-report/example_report.go77
-rw-r--r--examples/README.md44
6 files changed, 546 insertions, 0 deletions
diff --git a/examples/1-load/example_load.go b/examples/1-load/example_load.go
new file mode 100644
index 0000000..994f7f7
--- /dev/null
+++ b/examples/1-load/example_load.go
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+// Example for: *tvloader*, *spdx*
+
+// This example demonstrates loading an SPDX tag-value file from disk into
+// memory, and printing some of its contents to standard output.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/swinslow/spdx-go/v0/tvloader"
+)
+
+func main() {
+
+ // check that we've received the right number of arguments
+ args := os.Args
+ if len(args) != 2 {
+ fmt.Printf("Usage: %v <spdx-file-in>\n", args[0])
+ fmt.Printf(" Load SPDX 2.1 tag-value file <spdx-file-in>, and\n")
+ fmt.Printf(" print a portion of its contents.\n")
+ return
+ }
+
+ // open the SPDX file
+ filename := args[1]
+ r, err := os.Open(filename)
+ if err != nil {
+ fmt.Printf("Error while opening %v for reading: %v", filename, err)
+ return
+ }
+ defer r.Close()
+
+ // try to load the SPDX file's contents as a tag-value file, version 2.1
+ doc, err := tvloader.Load2_1(r)
+ if err != nil {
+ fmt.Printf("Error while parsing %v: %v", filename, err)
+ return
+ }
+
+ // if we got here, the file is now loaded into memory.
+ fmt.Printf("Successfully loaded %s\n\n", filename)
+
+ // we can now take a look at its contents via the various data
+ // structures representing the SPDX document's sections.
+
+ // print the struct containing the SPDX file's Creation Info section data
+ fmt.Printf("==============\n")
+ fmt.Printf("Creation info:\n")
+ fmt.Printf("==============\n")
+ fmt.Printf("%#v\n\n", doc.CreationInfo)
+
+ // check whether the SPDX file has at least one package
+ if doc.Packages == nil || len(doc.Packages) < 1 {
+ fmt.Printf("No packages found in SPDX document\n")
+ return
+ }
+
+ // it does, so we'll choose the first one
+ pkg := doc.Packages[0]
+
+ // check whether the package had its files analyzed
+ if !pkg.FilesAnalyzed {
+ fmt.Printf("First Package (%s) had FilesAnalyzed: false\n", pkg.PackageName)
+ return
+ }
+
+ // also check whether the package has any files present
+ if pkg.Files == nil || len(pkg.Files) < 1 {
+ fmt.Printf("No Files found in first Package (%s)\n", pkg.PackageName)
+ return
+ }
+
+ // if we got here, there's at least one file
+ // print the filename and license info for the first 50
+ fmt.Printf("============================\n")
+ fmt.Printf("Files info (up to first 50):\n")
+ fmt.Printf("============================\n")
+ i := 1
+ for _, f := range pkg.Files {
+ fmt.Printf("File %d: %s\n", i, f.FileName)
+ fmt.Printf(" License from file: %v\n", f.LicenseInfoInFile)
+ fmt.Printf(" License concluded: %v\n", f.LicenseConcluded)
+ i++
+ if i > 50 {
+ break
+ }
+ }
+}
diff --git a/examples/2-load-save/example_load_save.go b/examples/2-load-save/example_load_save.go
new file mode 100644
index 0000000..4a5cfc6
--- /dev/null
+++ b/examples/2-load-save/example_load_save.go
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+// Example for: *tvloader*, *tvsaver*
+
+// This example demonstrates loading an SPDX tag-value file from disk into memory,
+// and re-saving it to a different file on disk.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/swinslow/spdx-go/v0/tvloader"
+ "github.com/swinslow/spdx-go/v0/tvsaver"
+)
+
+func main() {
+
+ // check that we've received the right number of arguments
+ args := os.Args
+ if len(args) != 3 {
+ fmt.Printf("Usage: %v <spdx-file-in> <spdx-file-out>\n", args[0])
+ fmt.Printf(" Load SPDX 2.1 tag-value file <spdx-file-in>, and\n")
+ fmt.Printf(" save it out to <spdx-file-out>.\n")
+ return
+ }
+
+ // open the SPDX file
+ fileIn := args[1]
+ r, err := os.Open(fileIn)
+ if err != nil {
+ fmt.Printf("Error while opening %v for reading: %v", fileIn, err)
+ return
+ }
+ defer r.Close()
+
+ // try to load the SPDX file's contents as a tag-value file, version 2.1
+ doc, err := tvloader.Load2_1(r)
+ if err != nil {
+ fmt.Printf("Error while parsing %v: %v", fileIn, err)
+ return
+ }
+
+ // if we got here, the file is now loaded into memory.
+ fmt.Printf("Successfully loaded %s\n", fileIn)
+
+ // we can now save it back to disk, using tvsaver.
+
+ // create a new file for writing
+ fileOut := args[2]
+ w, err := os.Create(fileOut)
+ if err != nil {
+ fmt.Printf("Error while opening %v for writing: %v", fileOut, err)
+ return
+ }
+ defer w.Close()
+
+ // try to save the document to disk as an SPDX tag-value file, version 2.1
+ err = tvsaver.Save2_1(doc, w)
+ if err != nil {
+ fmt.Printf("Error while saving %v: %v", fileOut, err)
+ return
+ }
+
+ // it worked
+ fmt.Printf("Successfully saved %s\n", fileOut)
+}
diff --git a/examples/3-build/example_build.go b/examples/3-build/example_build.go
new file mode 100644
index 0000000..5ddafdd
--- /dev/null
+++ b/examples/3-build/example_build.go
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+// Example for: *builder*, *tvsaver*
+
+// This example demonstrates building an 'empty' SPDX document in memory that
+// corresponds to a given directory's contents, including all files with their
+// hashes and the package's verification code, and saving the document to disk.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/swinslow/spdx-go/v0/builder"
+ "github.com/swinslow/spdx-go/v0/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.1 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(" 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 builder package, the first step is to define a
+ // builder.Config2_1 struct. this config data can be reused, in case you
+ // are building SPDX documents for several directories in sequence.
+ config := &builder.Config2_1{
+
+ // 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 will be used for the first part of the Creator field
+ // in the Creation Info section. Per the SPDX spec, it can be
+ // "Person", "Organization" or "Tool".
+ CreatorType: "Person",
+
+ // Creator will be used for the second part of the Creator field in
+ // the Creation Info section.
+ Creator: "Jane Doe",
+
+ // note that builder will also add the following, in addition to the
+ // Creator defined above:
+ // Creator: Tool: github.com/swinslow/spdx-go/v0/builder
+
+ // Finally, 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.
+ PathsIgnored: []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",
+ },
+ }
+
+ // now, when we actually ask builder 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.
+ doc, err := builder.Build2_1(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 license info is marked as NOASSERTION, but file hashes and
+ // the package verification code have been filled in appropriately.
+ fmt.Printf("Successfully created document for package %s\n", packageName)
+
+ // 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_1(doc, w)
+ if err != nil {
+ fmt.Printf("Error while saving %v: %v", fileOut, err)
+ return
+ }
+
+ fmt.Printf("Successfully saved %v\n", fileOut)
+}
diff --git a/examples/4-search/example_search.go b/examples/4-search/example_search.go
new file mode 100644
index 0000000..0abbf7e
--- /dev/null
+++ b/examples/4-search/example_search.go
@@ -0,0 +1,148 @@
+// 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.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/swinslow/spdx-go/v0/idsearcher"
+
+ "github.com/swinslow/spdx-go/v0/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.1 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_1 struct. this config data can be reused, in case you
+ // are building SPDX documents for several directories in sequence.
+ config := &idsearcher.Config{
+
+ // 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_1, are not needed for
+ // idsearcher.Config. Because it is automated and doesn't assume
+ // further review, the following two Creator fields are filled in:
+ // Creator: Tool: github.com/swinslow/spdx-go/v0/builder
+ // Creator: Tool: github.com/swinslow/spdx-go/v0/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.BuildIDsDocument(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 LicenseInfoInFile 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_1(doc, w)
+ if err != nil {
+ fmt.Printf("Error while saving %v: %v", fileOut, err)
+ return
+ }
+
+ fmt.Printf("Successfully saved %v\n", fileOut)
+}
diff --git a/examples/5-report/example_report.go b/examples/5-report/example_report.go
new file mode 100644
index 0000000..5506a68
--- /dev/null
+++ b/examples/5-report/example_report.go
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+// Example for: *reporter*, *tvloader*
+
+// This example demonstrates loading an SPDX tag-value file from disk into memory,
+// generating a basic report listing counts of the concluded licenses for its
+// files, and printing the report to standard output.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/swinslow/spdx-go/v0/reporter"
+ "github.com/swinslow/spdx-go/v0/tvloader"
+)
+
+func main() {
+
+ // check that we've received the right number of arguments
+ args := os.Args
+ if len(args) != 2 {
+ fmt.Printf("Usage: %v <spdx-file-in>\n", args[0])
+ fmt.Printf(" Load SPDX 2.1 tag-value file <spdx-file-in>, and\n")
+ fmt.Printf(" generate and print a report of its concluded licenses.\n")
+ return
+ }
+
+ // open the SPDX file
+ filename := args[1]
+ r, err := os.Open(filename)
+ if err != nil {
+ fmt.Printf("Error while opening %v for reading: %v", filename, err)
+ return
+ }
+ defer r.Close()
+
+ // try to load the SPDX file's contents as a tag-value file, version 2.1
+ doc, err := tvloader.Load2_1(r)
+ if err != nil {
+ fmt.Printf("Error while parsing %v: %v", filename, err)
+ return
+ }
+
+ // if we got here, the file is now loaded into memory.
+ fmt.Printf("Successfully loaded %s\n\n", filename)
+
+ // check whether the SPDX file has at least one package
+ if doc.Packages == nil || len(doc.Packages) < 1 {
+ fmt.Printf("No packages found in SPDX document\n")
+ return
+ }
+
+ // it does, so we'll choose the first one
+ pkg := doc.Packages[0]
+
+ // check whether the package had its files analyzed
+ if !pkg.FilesAnalyzed {
+ fmt.Printf("First Package (%s) had FilesAnalyzed: false\n", pkg.PackageName)
+ return
+ }
+
+ // also check whether the package has any files present
+ if pkg.Files == nil || len(pkg.Files) < 1 {
+ fmt.Printf("No Files found in first Package (%s)\n", pkg.PackageName)
+ return
+ }
+
+ // if we got here, there's at least one file
+ // generate and print a report of the Package's Files' LicenseConcluded
+ // values, sorted by # of occurrences
+ err = reporter.Generate(pkg, os.Stdout)
+ if err != nil {
+ fmt.Printf("Error while generating report: %v\n", err)
+ }
+}
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..64e41f2
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,44 @@
+SPDX-License-Identifier: CC-BY-4.0
+
+# spdx-go Examples
+
+The `examples/` directory contains examples for how to use the various spdx-go sub-packages.
+
+## 1-load/
+
+*tvloader*, *spdx*
+
+This example demonstrates loading an SPDX tag-value file from disk into memory,
+and printing some of its contents to standard output.
+
+## 2-load-save/
+
+*tvloader*, *tvsaver*
+
+This example demonstrates loading an SPDX tag-value file from disk into memory,
+and re-saving it to a different file on disk.
+
+## 3-build/
+
+*builder*, *tvsaver*
+
+This example demonstrates building an 'empty' SPDX document in memory that
+corresponds to a given directory's contents, including all files with their
+hashes and the package's verification code, and saving the document to disk.
+
+## 4-search/
+
+*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.
+
+## 5-report/
+
+*reporter*, *tvloader*
+
+This example demonstrates loading an SPDX tag-value file from disk into memory,
+generating a basic report listing counts of the concluded licenses for its
+files, and printing the report to standard output.