aboutsummaryrefslogtreecommitdiff
path: root/spdx
diff options
context:
space:
mode:
authorSadaf Ebrahimi <sadafebrahimi@google.com>2023-01-26 16:53:11 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-01-26 16:53:11 +0000
commitf12cf925825a59c2bed27a69b67fd67aedc40736 (patch)
tree6ea4841a079772cb06df5ec2cf99637f8d53805b /spdx
parent5f73058e15df15ab2a35ca0c9d506b4fd0a83de7 (diff)
parent75f88b4895c444b4dfa2566595a7bf2774cdd389 (diff)
downloadspdx-tools-f12cf925825a59c2bed27a69b67fd67aedc40736.tar.gz
Upgrade spdx-tools to v0.4.0 am: 75f88b4895
Original change: https://android-review.googlesource.com/c/platform/external/spdx-tools/+/2401868 Change-Id: Ic8874ba0a8ce9c14050c2de8f652de86415dacbe Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'spdx')
-rw-r--r--spdx/common/annotation.go44
-rw-r--r--spdx/common/checksum.go34
-rw-r--r--spdx/common/creation_info.go44
-rw-r--r--spdx/common/external.go67
-rw-r--r--spdx/common/identifier.go173
-rw-r--r--spdx/common/identifier_test.go314
-rw-r--r--spdx/common/package.go105
-rw-r--r--spdx/common/snippet.go20
-rw-r--r--spdx/v2_1/annotation.go29
-rw-r--r--spdx/v2_1/creation_info.go26
-rw-r--r--spdx/v2_1/document.go65
-rw-r--r--spdx/v2_1/file.go90
-rw-r--r--spdx/v2_1/other_license.go31
-rw-r--r--spdx/v2_1/package.go120
-rw-r--r--spdx/v2_1/relationship.go23
-rw-r--r--spdx/v2_1/review.go25
-rw-r--r--spdx/v2_1/snippet.go44
-rw-r--r--spdx/v2_2/annotation.go29
-rw-r--r--spdx/v2_2/creation_info.go26
-rw-r--r--spdx/v2_2/document.go65
-rw-r--r--spdx/v2_2/file.go94
-rw-r--r--spdx/v2_2/other_license.go31
-rw-r--r--spdx/v2_2/package.go133
-rw-r--r--spdx/v2_2/relationship.go23
-rw-r--r--spdx/v2_2/review.go25
-rw-r--r--spdx/v2_2/snippet.go48
-rw-r--r--spdx/v2_3/annotation.go29
-rw-r--r--spdx/v2_3/creation_info.go26
-rw-r--r--spdx/v2_3/document.go65
-rw-r--r--spdx/v2_3/file.go96
-rw-r--r--spdx/v2_3/other_license.go31
-rw-r--r--spdx/v2_3/package.go151
-rw-r--r--spdx/v2_3/relationship.go23
-rw-r--r--spdx/v2_3/review.go25
-rw-r--r--spdx/v2_3/snippet.go48
35 files changed, 2222 insertions, 0 deletions
diff --git a/spdx/common/annotation.go b/spdx/common/annotation.go
new file mode 100644
index 0000000..e77d7b7
--- /dev/null
+++ b/spdx/common/annotation.go
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+type Annotator struct {
+ Annotator string
+ // including AnnotatorType: one of "Person", "Organization" or "Tool"
+ AnnotatorType string
+}
+
+// UnmarshalJSON takes an annotator in the typical one-line format and parses it into an Annotator struct.
+// This function is also used when unmarshalling YAML
+func (a *Annotator) UnmarshalJSON(data []byte) error {
+ // annotator will simply be a string
+ annotatorStr := string(data)
+ annotatorStr = strings.Trim(annotatorStr, "\"")
+
+ annotatorFields := strings.SplitN(annotatorStr, ": ", 2)
+
+ if len(annotatorFields) != 2 {
+ return fmt.Errorf("failed to parse Annotator '%s'", annotatorStr)
+ }
+
+ a.AnnotatorType = annotatorFields[0]
+ a.Annotator = annotatorFields[1]
+
+ return nil
+}
+
+// MarshalJSON converts the receiver into a slice of bytes representing an Annotator in string form.
+// This function is also used when marshalling to YAML
+func (a Annotator) MarshalJSON() ([]byte, error) {
+ if a.Annotator != "" {
+ return json.Marshal(fmt.Sprintf("%s: %s", a.AnnotatorType, a.Annotator))
+ }
+
+ return []byte{}, nil
+}
diff --git a/spdx/common/checksum.go b/spdx/common/checksum.go
new file mode 100644
index 0000000..aa2ae52
--- /dev/null
+++ b/spdx/common/checksum.go
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+// ChecksumAlgorithm represents the algorithm used to generate the file checksum in the Checksum struct.
+type ChecksumAlgorithm string
+
+// The checksum algorithms mentioned in the spdxv2.2.0 https://spdx.github.io/spdx-spec/4-file-information/#44-file-checksum
+const (
+ SHA224 ChecksumAlgorithm = "SHA224"
+ SHA1 ChecksumAlgorithm = "SHA1"
+ SHA256 ChecksumAlgorithm = "SHA256"
+ SHA384 ChecksumAlgorithm = "SHA384"
+ SHA512 ChecksumAlgorithm = "SHA512"
+ MD2 ChecksumAlgorithm = "MD2"
+ MD4 ChecksumAlgorithm = "MD4"
+ MD5 ChecksumAlgorithm = "MD5"
+ MD6 ChecksumAlgorithm = "MD6"
+ SHA3_256 ChecksumAlgorithm = "SHA3-256"
+ SHA3_384 ChecksumAlgorithm = "SHA3-384"
+ SHA3_512 ChecksumAlgorithm = "SHA3-512"
+ BLAKE2b_256 ChecksumAlgorithm = "BLAKE2b-256"
+ BLAKE2b_384 ChecksumAlgorithm = "BLAKE2b-384"
+ BLAKE2b_512 ChecksumAlgorithm = "BLAKE2b-512"
+ BLAKE3 ChecksumAlgorithm = "BLAKE3"
+ ADLER32 ChecksumAlgorithm = "ADLER32"
+)
+
+// Checksum provides a unique identifier to match analysis information on each specific file in a package.
+// The Algorithm field describes the ChecksumAlgorithm used and the Value represents the file checksum
+type Checksum struct {
+ Algorithm ChecksumAlgorithm `json:"algorithm"`
+ Value string `json:"checksumValue"`
+}
diff --git a/spdx/common/creation_info.go b/spdx/common/creation_info.go
new file mode 100644
index 0000000..c87ae7b
--- /dev/null
+++ b/spdx/common/creation_info.go
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+// Creator is a wrapper around the Creator SPDX field. The SPDX field contains two values, which requires special
+// handling in order to marshal/unmarshal it to/from Go data types.
+type Creator struct {
+ Creator string
+ // CreatorType should be one of "Person", "Organization", or "Tool"
+ CreatorType string
+}
+
+// UnmarshalJSON takes an annotator in the typical one-line format and parses it into a Creator struct.
+// This function is also used when unmarshalling YAML
+func (c *Creator) UnmarshalJSON(data []byte) error {
+ str := string(data)
+ str = strings.Trim(str, "\"")
+ fields := strings.SplitN(str, ": ", 2)
+
+ if len(fields) != 2 {
+ return fmt.Errorf("failed to parse Creator '%s'", str)
+ }
+
+ c.CreatorType = fields[0]
+ c.Creator = fields[1]
+
+ return nil
+}
+
+// MarshalJSON converts the receiver into a slice of bytes representing a Creator in string form.
+// This function is also used with marshalling to YAML
+func (c Creator) MarshalJSON() ([]byte, error) {
+ if c.Creator != "" {
+ return json.Marshal(fmt.Sprintf("%s: %s", c.CreatorType, c.Creator))
+ }
+
+ return []byte{}, nil
+}
diff --git a/spdx/common/external.go b/spdx/common/external.go
new file mode 100644
index 0000000..59c3f0f
--- /dev/null
+++ b/spdx/common/external.go
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+// Constants for various string types
+const (
+ // F.2 Security types
+ TypeSecurityCPE23Type string = "cpe23Type"
+ TypeSecurityCPE22Type string = "cpe22Type"
+ TypeSecurityAdvisory string = "advisory"
+ TypeSecurityFix string = "fix"
+ TypeSecurityUrl string = "url"
+ TypeSecuritySwid string = "swid"
+
+ // F.3 Package-Manager types
+ TypePackageManagerMavenCentral string = "maven-central"
+ TypePackageManagerNpm string = "npm"
+ TypePackageManagerNuGet string = "nuget"
+ TypePackageManagerBower string = "bower"
+ TypePackageManagerPURL string = "purl"
+
+ // 11.1 Relationship field types
+ TypeRelationshipDescribe string = "DESCRIBES"
+ TypeRelationshipDescribeBy string = "DESCRIBED_BY"
+ TypeRelationshipContains string = "CONTAINS"
+ TypeRelationshipContainedBy string = "CONTAINED_BY"
+ TypeRelationshipDependsOn string = "DEPENDS_ON"
+ TypeRelationshipDependencyOf string = "DEPENDENCY_OF"
+ TypeRelationshipBuildDependencyOf string = "BUILD_DEPENDENCY_OF"
+ TypeRelationshipDevDependencyOf string = "DEV_DEPENDENCY_OF"
+ TypeRelationshipOptionalDependencyOf string = "OPTIONAL_DEPENDENCY_OF"
+ TypeRelationshipProvidedDependencyOf string = "PROVIDED_DEPENDENCY_OF"
+ TypeRelationshipTestDependencyOf string = "TEST_DEPENDENCY_OF"
+ TypeRelationshipRuntimeDependencyOf string = "RUNTIME_DEPENDENCY_OF"
+ TypeRelationshipExampleOf string = "EXAMPLE_OF"
+ TypeRelationshipGenerates string = "GENERATES"
+ TypeRelationshipGeneratedFrom string = "GENERATED_FROM"
+ TypeRelationshipAncestorOf string = "ANCESTOR_OF"
+ TypeRelationshipDescendantOf string = "DESCENDANT_OF"
+ TypeRelationshipVariantOf string = "VARIANT_OF"
+ TypeRelationshipDistributionArtifact string = "DISTRIBUTION_ARTIFACT"
+ TypeRelationshipPatchFor string = "PATCH_FOR"
+ TypeRelationshipPatchApplied string = "PATCH_APPLIED"
+ TypeRelationshipCopyOf string = "COPY_OF"
+ TypeRelationshipFileAdded string = "FILE_ADDED"
+ TypeRelationshipFileDeleted string = "FILE_DELETED"
+ TypeRelationshipFileModified string = "FILE_MODIFIED"
+ TypeRelationshipExpandedFromArchive string = "EXPANDED_FROM_ARCHIVE"
+ TypeRelationshipDynamicLink string = "DYNAMIC_LINK"
+ TypeRelationshipStaticLink string = "STATIC_LINK"
+ TypeRelationshipDataFileOf string = "DATA_FILE_OF"
+ TypeRelationshipTestCaseOf string = "TEST_CASE_OF"
+ TypeRelationshipBuildToolOf string = "BUILD_TOOL_OF"
+ TypeRelationshipDevToolOf string = "DEV_TOOL_OF"
+ TypeRelationshipTestOf string = "TEST_OF"
+ TypeRelationshipTestToolOf string = "TEST_TOOL_OF"
+ TypeRelationshipDocumentationOf string = "DOCUMENTATION_OF"
+ TypeRelationshipOptionalComponentOf string = "OPTIONAL_COMPONENT_OF"
+ TypeRelationshipMetafileOf string = "METAFILE_OF"
+ TypeRelationshipPackageOf string = "PACKAGE_OF"
+ TypeRelationshipAmends string = "AMENDS"
+ TypeRelationshipPrerequisiteFor string = "PREREQUISITE_FOR"
+ TypeRelationshipHasPrerequisite string = "HAS_PREREQUISITE"
+ TypeRelationshipRequirementDescriptionFor string = "REQUIREMENT_DESCRIPTION_FOR"
+ TypeRelationshipSpecificationFor string = "SPECIFICATION_FOR"
+ TypeRelationshipOther string = "OTHER"
+)
diff --git a/spdx/common/identifier.go b/spdx/common/identifier.go
new file mode 100644
index 0000000..806a815
--- /dev/null
+++ b/spdx/common/identifier.go
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+const (
+ spdxRefPrefix = "SPDXRef-"
+ documentRefPrefix = "DocumentRef-"
+)
+
+// ElementID represents the identifier string portion of an SPDX element
+// identifier. DocElementID should be used for any attributes which can
+// contain identifiers defined in a different SPDX document.
+// ElementIDs should NOT contain the mandatory 'SPDXRef-' portion.
+type ElementID string
+
+// MarshalJSON returns an SPDXRef- prefixed JSON string
+func (d ElementID) MarshalJSON() ([]byte, error) {
+ return json.Marshal(prefixElementId(d))
+}
+
+// UnmarshalJSON validates SPDXRef- prefixes and removes them when processing ElementIDs
+func (d *ElementID) UnmarshalJSON(data []byte) error {
+ // SPDX identifier will simply be a string
+ idStr := string(data)
+ idStr = strings.Trim(idStr, "\"")
+
+ e, err := trimElementIdPrefix(idStr)
+ if err != nil {
+ return err
+ }
+ *d = e
+ return nil
+}
+
+// prefixElementId adds the SPDXRef- prefix to an element ID if it does not have one
+func prefixElementId(id ElementID) string {
+ val := string(id)
+ if !strings.HasPrefix(val, spdxRefPrefix) {
+ return spdxRefPrefix + val
+ }
+ return val
+}
+
+// trimElementIdPrefix removes the SPDXRef- prefix from an element ID string or returns an error if it
+// does not start with SPDXRef-
+func trimElementIdPrefix(id string) (ElementID, error) {
+ // handle SPDXRef-
+ idFields := strings.SplitN(id, spdxRefPrefix, 2)
+ if len(idFields) != 2 {
+ return "", fmt.Errorf("failed to parse SPDX identifier '%s'", id)
+ }
+
+ e := ElementID(idFields[1])
+ return e, nil
+}
+
+// DocElementID represents an SPDX element identifier that could be defined
+// in a different SPDX document, and therefore could have a "DocumentRef-"
+// portion, such as Relationships and Annotations.
+// ElementID is used for attributes in which a "DocumentRef-" portion cannot
+// appear, such as a Package or File definition (since it is necessarily
+// being defined in the present document).
+// DocumentRefID will be the empty string for elements defined in the
+// present document.
+// DocElementIDs should NOT contain the mandatory 'DocumentRef-' or
+// 'SPDXRef-' portions.
+// SpecialID is used ONLY if the DocElementID matches a defined set of
+// permitted special values for a particular field, e.g. "NONE" or
+// "NOASSERTION" for the right-hand side of Relationships. If SpecialID
+// is set, DocumentRefID and ElementRefID should be empty (and vice versa).
+type DocElementID struct {
+ DocumentRefID string
+ ElementRefID ElementID
+ SpecialID string
+}
+
+// MarshalJSON converts the receiver into a slice of bytes representing a DocElementID in string form.
+// This function is also used when marshalling to YAML
+func (d DocElementID) MarshalJSON() ([]byte, error) {
+ if d.DocumentRefID != "" && d.ElementRefID != "" {
+ idStr := prefixElementId(d.ElementRefID)
+ return json.Marshal(fmt.Sprintf("%s%s:%s", documentRefPrefix, d.DocumentRefID, idStr))
+ } else if d.ElementRefID != "" {
+ return json.Marshal(prefixElementId(d.ElementRefID))
+ } else if d.SpecialID != "" {
+ return json.Marshal(d.SpecialID)
+ }
+
+ return []byte{}, fmt.Errorf("failed to marshal empty DocElementID")
+}
+
+// UnmarshalJSON takes a SPDX Identifier string parses it into a DocElementID struct.
+// This function is also used when unmarshalling YAML
+func (d *DocElementID) UnmarshalJSON(data []byte) (err error) {
+ // SPDX identifier will simply be a string
+ idStr := string(data)
+ idStr = strings.Trim(idStr, "\"")
+
+ // handle special cases
+ if idStr == "NONE" || idStr == "NOASSERTION" {
+ d.SpecialID = idStr
+ return nil
+ }
+
+ var idFields []string
+ // handle DocumentRef- if present
+ if strings.HasPrefix(idStr, documentRefPrefix) {
+ // strip out the "DocumentRef-" so we can get the value
+ idFields = strings.SplitN(idStr, documentRefPrefix, 2)
+ idStr = idFields[1]
+
+ // an SPDXRef can appear after a DocumentRef, separated by a colon
+ idFields = strings.SplitN(idStr, ":", 2)
+ d.DocumentRefID = idFields[0]
+
+ if len(idFields) == 2 {
+ idStr = idFields[1]
+ } else {
+ return nil
+ }
+ }
+
+ d.ElementRefID, err = trimElementIdPrefix(idStr)
+ return err
+}
+
+// TODO: add equivalents for LicenseRef- identifiers
+
+// MakeDocElementID takes strings (without prefixes) for the DocumentRef-
+// and SPDXRef- identifiers, and returns a DocElementID. An empty string
+// should be used for the DocumentRef- portion if it is referring to the
+// present document.
+func MakeDocElementID(docRef string, eltRef string) DocElementID {
+ return DocElementID{
+ DocumentRefID: docRef,
+ ElementRefID: ElementID(eltRef),
+ }
+}
+
+// MakeDocElementSpecial takes a "special" string (e.g. "NONE" or
+// "NOASSERTION" for the right side of a Relationship), nd returns
+// a DocElementID with it in the SpecialID field. Other fields will
+// be empty.
+func MakeDocElementSpecial(specialID string) DocElementID {
+ return DocElementID{SpecialID: specialID}
+}
+
+// RenderElementID takes an ElementID and returns the string equivalent,
+// with the SPDXRef- prefix reinserted.
+func RenderElementID(eID ElementID) string {
+ return spdxRefPrefix + string(eID)
+}
+
+// RenderDocElementID takes a DocElementID and returns the string equivalent,
+// with the SPDXRef- prefix (and, if applicable, the DocumentRef- prefix)
+// reinserted. If a SpecialID is present, it will be rendered verbatim and
+// DocumentRefID and ElementRefID will be ignored.
+func RenderDocElementID(deID DocElementID) string {
+ if deID.SpecialID != "" {
+ return deID.SpecialID
+ }
+ prefix := ""
+ if deID.DocumentRefID != "" {
+ prefix = documentRefPrefix + deID.DocumentRefID + ":"
+ }
+ return prefix + spdxRefPrefix + string(deID.ElementRefID)
+}
diff --git a/spdx/common/identifier_test.go b/spdx/common/identifier_test.go
new file mode 100644
index 0000000..8df2ea3
--- /dev/null
+++ b/spdx/common/identifier_test.go
@@ -0,0 +1,314 @@
+package common
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "strings"
+ "testing"
+)
+
+func Test_DocElementIDEncoding(t *testing.T) {
+ tests := []struct {
+ name string
+ value DocElementID
+ expected string
+ err bool
+ }{
+ {
+ name: "ElementRefID",
+ value: DocElementID{
+ ElementRefID: "some-id",
+ },
+ expected: "SPDXRef-some-id",
+ },
+ {
+ name: "DocumentRefID:ElementRefID",
+ value: DocElementID{
+ DocumentRefID: "a-doc",
+ ElementRefID: "some-id",
+ },
+ expected: "DocumentRef-a-doc:SPDXRef-some-id",
+ },
+ {
+ name: "DocumentRefID no ElementRefID",
+ value: DocElementID{
+ DocumentRefID: "a-doc",
+ },
+ err: true,
+ },
+ {
+ name: "SpecialID",
+ value: DocElementID{
+ SpecialID: "special-id",
+ },
+ expected: "special-id",
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ result, err := json.Marshal(test.value)
+ switch {
+ case !test.err && err != nil:
+ t.Fatalf("unexpected error: %v", err)
+ case test.err && err == nil:
+ t.Fatalf("expected error but got none")
+ case test.err:
+ return
+ }
+ s := string(result)
+ if !strings.HasPrefix(s, `"`) || !strings.HasSuffix(s, `"`) {
+ t.Fatalf("string was not returned: %s", s)
+ }
+ s = strings.Trim(s, `"`)
+ if test.expected != s {
+ t.Fatalf("%s != %s", test.expected, s)
+ }
+ })
+ }
+}
+
+func Test_DocElementIDDecoding(t *testing.T) {
+ tests := []struct {
+ name string
+ value string
+ expected DocElementID
+ err bool
+ }{
+ {
+ name: "ElementRefID",
+ value: "SPDXRef-some-id",
+ expected: DocElementID{
+ ElementRefID: "some-id",
+ },
+ },
+ {
+ name: "DocumentRefID:ElementRefID",
+ value: "DocumentRef-a-doc:SPDXRef-some-id",
+ expected: DocElementID{
+ DocumentRefID: "a-doc",
+ ElementRefID: "some-id",
+ },
+ },
+ {
+ name: "DocumentRefID no ElementRefID",
+ value: "DocumentRef-a-doc",
+ expected: DocElementID{
+ DocumentRefID: "a-doc",
+ },
+ },
+ {
+ name: "DocumentRefID invalid ElementRefID",
+ value: "DocumentRef-a-doc:invalid",
+ err: true,
+ },
+ {
+ name: "invalid format",
+ value: "some-id-without-spdxref",
+ err: true,
+ },
+ {
+ name: "SpecialID NONE",
+ value: "NONE",
+ expected: DocElementID{
+ SpecialID: "NONE",
+ },
+ },
+ {
+ name: "SpecialID NOASSERTION",
+ value: "NOASSERTION",
+ expected: DocElementID{
+ SpecialID: "NOASSERTION",
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ out := DocElementID{}
+ s := fmt.Sprintf(`"%s"`, test.value)
+ err := json.Unmarshal([]byte(s), &out)
+ switch {
+ case !test.err && err != nil:
+ t.Fatalf("unexpected error: %v", err)
+ case test.err && err == nil:
+ t.Fatalf("expected error but got none")
+ case test.err:
+ return
+ }
+ if !reflect.DeepEqual(test.expected, out) {
+ t.Fatalf("unexpected value: %v != %v", test.expected, out)
+ }
+ })
+ }
+}
+
+func Test_ElementIDEncoding(t *testing.T) {
+ tests := []struct {
+ name string
+ value ElementID
+ expected string
+ err bool
+ }{
+ {
+ name: "appends spdxref",
+ value: ElementID("some-id"),
+ expected: "SPDXRef-some-id",
+ },
+ {
+ name: "appends spdxref",
+ value: ElementID("SPDXRef-some-id"),
+ expected: "SPDXRef-some-id",
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ result, err := json.Marshal(test.value)
+ switch {
+ case !test.err && err != nil:
+ t.Fatalf("unexpected error: %v", err)
+ case test.err && err == nil:
+ t.Fatalf("expected error but got none")
+ case test.err:
+ return
+ }
+ s := string(result)
+ if !strings.HasPrefix(s, `"`) || !strings.HasSuffix(s, `"`) {
+ t.Fatalf("string was not returned: %s", s)
+ }
+ s = strings.Trim(s, `"`)
+ if test.expected != s {
+ t.Fatalf("%s != %s", test.expected, s)
+ }
+ })
+ }
+}
+
+func Test_ElementIDDecoding(t *testing.T) {
+ tests := []struct {
+ name string
+ value string
+ expected ElementID
+ err bool
+ }{
+ {
+ name: "valid id",
+ value: "SPDXRef-some-id",
+ expected: ElementID("some-id"),
+ },
+ {
+ name: "invalid format",
+ value: "some-id-without-spdxref",
+ err: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ var out ElementID
+ s := fmt.Sprintf(`"%s"`, test.value)
+ err := json.Unmarshal([]byte(s), &out)
+ switch {
+ case !test.err && err != nil:
+ t.Fatalf("unexpected error: %v", err)
+ case test.err && err == nil:
+ t.Fatalf("expected error but got none")
+ case test.err:
+ return
+ }
+ if !reflect.DeepEqual(test.expected, out) {
+ t.Fatalf("unexpected value: %v != %v", test.expected, out)
+ }
+ })
+ }
+}
+
+func Test_ElementIDStructEncoding(t *testing.T) {
+ type typ struct {
+ Id ElementID `json:"id"`
+ }
+ tests := []struct {
+ name string
+ value typ
+ expected string
+ err bool
+ }{
+ {
+ name: "appends spdxref",
+ value: typ{
+ Id: ElementID("some-id"),
+ },
+ expected: `{"id":"SPDXRef-some-id"}`,
+ },
+ {
+ name: "appends spdxref",
+ value: typ{
+ Id: ElementID("SPDXRef-some-id"),
+ },
+ expected: `{"id":"SPDXRef-some-id"}`,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ result, err := json.Marshal(test.value)
+ switch {
+ case !test.err && err != nil:
+ t.Fatalf("unexpected error: %v", err)
+ case test.err && err == nil:
+ t.Fatalf("expected error but got none")
+ case test.err:
+ return
+ }
+ s := string(result)
+ if test.expected != s {
+ t.Fatalf("%s != %s", test.expected, s)
+ }
+ })
+ }
+}
+
+func Test_ElementIDStructDecoding(t *testing.T) {
+ type typ struct {
+ Id ElementID `json:"id"`
+ }
+ tests := []struct {
+ name string
+ value string
+ expected typ
+ err bool
+ }{
+ {
+ name: "valid id",
+ expected: typ{
+ Id: ElementID("some-id"),
+ },
+ value: `{"id":"SPDXRef-some-id"}`,
+ },
+ {
+ name: "invalid format",
+ value: `{"id":"some-id"}`,
+ err: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ out := typ{}
+ err := json.Unmarshal([]byte(test.value), &out)
+ switch {
+ case !test.err && err != nil:
+ t.Fatalf("unexpected error: %v", err)
+ case test.err && err == nil:
+ t.Fatalf("expected error but got none")
+ case test.err:
+ return
+ }
+ if !reflect.DeepEqual(test.expected, out) {
+ t.Fatalf("unexpected value: %v != %v", test.expected, out)
+ }
+ })
+ }
+}
diff --git a/spdx/common/package.go b/spdx/common/package.go
new file mode 100644
index 0000000..de5a075
--- /dev/null
+++ b/spdx/common/package.go
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+type Supplier struct {
+ // can be "NOASSERTION"
+ Supplier string
+ // SupplierType can be one of "Person", "Organization", or empty if Supplier is "NOASSERTION"
+ SupplierType string
+}
+
+// UnmarshalJSON takes a supplier in the typical one-line format and parses it into a Supplier struct.
+// This function is also used when unmarshalling YAML
+func (s *Supplier) UnmarshalJSON(data []byte) error {
+ // the value is just a string presented as a slice of bytes
+ supplierStr := string(data)
+ supplierStr = strings.Trim(supplierStr, "\"")
+
+ if supplierStr == "NOASSERTION" {
+ s.Supplier = supplierStr
+ return nil
+ }
+
+ supplierFields := strings.SplitN(supplierStr, ": ", 2)
+
+ if len(supplierFields) != 2 {
+ return fmt.Errorf("failed to parse Supplier '%s'", supplierStr)
+ }
+
+ s.SupplierType = supplierFields[0]
+ s.Supplier = supplierFields[1]
+
+ return nil
+}
+
+// MarshalJSON converts the receiver into a slice of bytes representing a Supplier in string form.
+// This function is also used when marshalling to YAML
+func (s Supplier) MarshalJSON() ([]byte, error) {
+ if s.Supplier == "NOASSERTION" {
+ return json.Marshal(s.Supplier)
+ } else if s.SupplierType != "" && s.Supplier != "" {
+ return json.Marshal(fmt.Sprintf("%s: %s", s.SupplierType, s.Supplier))
+ }
+
+ return []byte{}, fmt.Errorf("failed to marshal invalid Supplier: %+v", s)
+}
+
+type Originator struct {
+ // can be "NOASSERTION"
+ Originator string
+ // OriginatorType can be one of "Person", "Organization", or empty if Originator is "NOASSERTION"
+ OriginatorType string
+}
+
+// UnmarshalJSON takes an originator in the typical one-line format and parses it into an Originator struct.
+// This function is also used when unmarshalling YAML
+func (o *Originator) UnmarshalJSON(data []byte) error {
+ // the value is just a string presented as a slice of bytes
+ originatorStr := string(data)
+ originatorStr = strings.Trim(originatorStr, "\"")
+
+ if originatorStr == "NOASSERTION" {
+ o.Originator = originatorStr
+ return nil
+ }
+
+ originatorFields := strings.SplitN(originatorStr, ": ", 2)
+
+ if len(originatorFields) != 2 {
+ return fmt.Errorf("failed to parse Originator '%s'", originatorStr)
+ }
+
+ o.OriginatorType = originatorFields[0]
+ o.Originator = originatorFields[1]
+
+ return nil
+}
+
+// MarshalJSON converts the receiver into a slice of bytes representing an Originator in string form.
+// This function is also used when marshalling to YAML
+func (o Originator) MarshalJSON() ([]byte, error) {
+ if o.Originator == "NOASSERTION" {
+ return json.Marshal(o.Originator)
+ } else if o.Originator != "" {
+ return json.Marshal(fmt.Sprintf("%s: %s", o.OriginatorType, o.Originator))
+ }
+
+ return []byte{}, nil
+}
+
+type PackageVerificationCode struct {
+ // Cardinality: mandatory, one if filesAnalyzed is true / omitted;
+ // zero (must be omitted) if filesAnalyzed is false
+ Value string `json:"packageVerificationCodeValue"`
+ // Spec also allows specifying files to exclude from the
+ // verification code algorithm; intended to enable exclusion of
+ // the SPDX document file itself.
+ ExcludedFiles []string `json:"packageVerificationCodeExcludedFiles,omitempty"`
+}
diff --git a/spdx/common/snippet.go b/spdx/common/snippet.go
new file mode 100644
index 0000000..63afac3
--- /dev/null
+++ b/spdx/common/snippet.go
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package common
+
+type SnippetRangePointer struct {
+ // 5.3: Snippet Byte Range: [start byte]:[end byte]
+ // Cardinality: mandatory, one
+ Offset int `json:"offset,omitempty"`
+
+ // 5.4: Snippet Line Range: [start line]:[end line]
+ // Cardinality: optional, one
+ LineNumber int `json:"lineNumber,omitempty"`
+
+ FileSPDXIdentifier ElementID `json:"reference"`
+}
+
+type SnippetRange struct {
+ StartPointer SnippetRangePointer `json:"startPointer"`
+ EndPointer SnippetRangePointer `json:"endPointer"`
+}
diff --git a/spdx/v2_1/annotation.go b/spdx/v2_1/annotation.go
new file mode 100644
index 0000000..45fcd13
--- /dev/null
+++ b/spdx/v2_1/annotation.go
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Annotation is an Annotation section of an SPDX Document for version 2.1 of the spec.
+type Annotation struct {
+ // 8.1: Annotator
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ Annotator common.Annotator `json:"annotator"`
+
+ // 8.2: Annotation Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationDate string `json:"annotationDate"`
+
+ // 8.3: Annotation Type: "REVIEW" or "OTHER"
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationType string `json:"annotationType"`
+
+ // 8.4: SPDX Identifier Reference
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ // This field is not used in hierarchical data formats where the referenced element is clear, such as JSON or YAML.
+ AnnotationSPDXIdentifier common.DocElementID `json:"-"`
+
+ // 8.5: Annotation Comment
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationComment string `json:"comment"`
+}
diff --git a/spdx/v2_1/creation_info.go b/spdx/v2_1/creation_info.go
new file mode 100644
index 0000000..0e1bd87
--- /dev/null
+++ b/spdx/v2_1/creation_info.go
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// CreationInfo is a Document Creation Information section of an
+// SPDX Document for version 2.1 of the spec.
+type CreationInfo struct {
+ // 2.7: License List Version
+ // Cardinality: optional, one
+ LicenseListVersion string `json:"licenseListVersion"`
+
+ // 2.8: Creators: may have multiple keys for Person, Organization
+ // and/or Tool
+ // Cardinality: mandatory, one or many
+ Creators []common.Creator `json:"creators"`
+
+ // 2.9: Created: data format YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: mandatory, one
+ Created string `json:"created"`
+
+ // 2.10: Creator Comment
+ // Cardinality: optional, one
+ CreatorComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_1/document.go b/spdx/v2_1/document.go
new file mode 100644
index 0000000..81738ff
--- /dev/null
+++ b/spdx/v2_1/document.go
@@ -0,0 +1,65 @@
+// Package spdx contains the struct definition for an SPDX Document
+// and its constituent parts.
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// ExternalDocumentRef is a reference to an external SPDX document
+// as defined in section 2.6 for version 2.1 of the spec.
+type ExternalDocumentRef struct {
+ // DocumentRefID is the ID string defined in the start of the
+ // reference. It should _not_ contain the "DocumentRef-" part
+ // of the mandatory ID string.
+ DocumentRefID string `json:"externalDocumentId"`
+
+ // URI is the URI defined for the external document
+ URI string `json:"spdxDocument"`
+
+ // Checksum is the actual hash data
+ Checksum common.Checksum `json:"checksum"`
+}
+
+// Document is an SPDX Document for version 2.1 of the spec.
+// See https://spdx.org/sites/cpstandard/files/pages/files/spdxversion2.1.pdf
+type Document struct {
+ // 2.1: SPDX Version; should be in the format "SPDX-2.1"
+ // Cardinality: mandatory, one
+ SPDXVersion string `json:"spdxVersion"`
+
+ // 2.2: Data License; should be "CC0-1.0"
+ // Cardinality: mandatory, one
+ DataLicense string `json:"dataLicense"`
+
+ // 2.3: SPDX Identifier; should be "DOCUMENT" to represent
+ // mandatory identifier of SPDXRef-DOCUMENT
+ // Cardinality: mandatory, one
+ SPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 2.4: Document Name
+ // Cardinality: mandatory, one
+ DocumentName string `json:"name"`
+
+ // 2.5: Document Namespace
+ // Cardinality: mandatory, one
+ DocumentNamespace string `json:"documentNamespace"`
+
+ // 2.6: External Document References
+ // Cardinality: optional, one or many
+ ExternalDocumentReferences []ExternalDocumentRef `json:"externalDocumentRefs,omitempty"`
+
+ // 2.11: Document Comment
+ // Cardinality: optional, one
+ DocumentComment string `json:"comment,omitempty"`
+
+ CreationInfo *CreationInfo `json:"creationInfo"`
+ Packages []*Package `json:"packages,omitempty"`
+ Files []*File `json:"files,omitempty"`
+ OtherLicenses []*OtherLicense `json:"hasExtractedLicensingInfos,omitempty"`
+ Relationships []*Relationship `json:"relationships,omitempty"`
+ Annotations []*Annotation `json:"annotations,omitempty"`
+ Snippets []Snippet `json:"snippets,omitempty"`
+
+ // DEPRECATED in version 2.0 of spec
+ Reviews []*Review `json:"-"`
+}
diff --git a/spdx/v2_1/file.go b/spdx/v2_1/file.go
new file mode 100644
index 0000000..2373887
--- /dev/null
+++ b/spdx/v2_1/file.go
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// File is a File section of an SPDX Document for version 2.1 of the spec.
+type File struct {
+ // 4.1: File Name
+ // Cardinality: mandatory, one
+ FileName string `json:"fileName"`
+
+ // 4.2: File SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ FileSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 4.3: File Types
+ // Cardinality: optional, multiple
+ FileTypes []string `json:"fileTypes,omitempty"`
+
+ // 4.4: File Checksum: may have keys for SHA1, SHA256 and/or MD5
+ // Cardinality: mandatory, one SHA1, others may be optionally provided
+ Checksums []common.Checksum `json:"checksums"`
+
+ // 4.5: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ LicenseConcluded string `json:"licenseConcluded"`
+
+ // 4.6: License Information in File: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one or many
+ LicenseInfoInFiles []string `json:"licenseInfoInFiles"`
+
+ // 4.7: Comments on License
+ // Cardinality: optional, one
+ LicenseComments string `json:"licenseComments,omitempty"`
+
+ // 4.8: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ FileCopyrightText string `json:"copyrightText"`
+
+ // DEPRECATED in version 2.1 of spec
+ // 4.9-4.11: Artifact of Project variables (defined below)
+ // Cardinality: optional, one or many
+ ArtifactOfProjects []*ArtifactOfProject `json:"-"`
+
+ // 4.12: File Comment
+ // Cardinality: optional, one
+ FileComment string `json:"comment,omitempty"`
+
+ // 4.13: File Notice
+ // Cardinality: optional, one
+ FileNotice string `json:"noticeText,omitempty"`
+
+ // 4.14: File Contributor
+ // Cardinality: optional, one or many
+ FileContributors []string `json:"fileContributors,omitempty"`
+
+ // DEPRECATED in version 2.0 of spec
+ // 4.15: File Dependencies
+ // Cardinality: optional, one or many
+ FileDependencies []string `json:"-"`
+
+ // Snippets contained in this File
+ // Note that Snippets could be defined in a different Document! However,
+ // the only ones that _THIS_ document can contain are the ones that are
+ // defined here -- so this should just be an ElementID.
+ Snippets map[common.ElementID]*Snippet `json:"-"`
+
+ Annotations []Annotation `json:"annotations,omitempty"`
+}
+
+// ArtifactOfProject is a DEPRECATED collection of data regarding
+// a Package, as defined in sections 4.9-4.11 in version 2.1 of the spec.
+type ArtifactOfProject struct {
+
+ // DEPRECATED in version 2.1 of spec
+ // 4.9: Artifact of Project Name
+ // Cardinality: conditional, required if present, one per AOP
+ Name string
+
+ // DEPRECATED in version 2.1 of spec
+ // 4.10: Artifact of Project Homepage: URL or "UNKNOWN"
+ // Cardinality: optional, one per AOP
+ HomePage string
+
+ // DEPRECATED in version 2.1 of spec
+ // 4.11: Artifact of Project Uniform Resource Identifier
+ // Cardinality: optional, one per AOP
+ URI string
+}
diff --git a/spdx/v2_1/other_license.go b/spdx/v2_1/other_license.go
new file mode 100644
index 0000000..6ae09fe
--- /dev/null
+++ b/spdx/v2_1/other_license.go
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+// OtherLicense is an Other License Information section of an
+// SPDX Document for version 2.1 of the spec.
+type OtherLicense struct {
+ // 6.1: License Identifier: "LicenseRef-[idstring]"
+ // Cardinality: conditional (mandatory, one) if license is not
+ // on SPDX License List
+ LicenseIdentifier string `json:"licenseId"`
+
+ // 6.2: Extracted Text
+ // Cardinality: conditional (mandatory, one) if there is a
+ // License Identifier assigned
+ ExtractedText string `json:"extractedText"`
+
+ // 6.3: License Name: single line of text or "NOASSERTION"
+ // Cardinality: conditional (mandatory, one) if license is not
+ // on SPDX License List
+ LicenseName string `json:"name,omitempty"`
+
+ // 6.4: License Cross Reference
+ // Cardinality: conditional (optional, one or many) if license
+ // is not on SPDX License List
+ LicenseCrossReferences []string `json:"seeAlsos,omitempty"`
+
+ // 6.5: License Comment
+ // Cardinality: optional, one
+ LicenseComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_1/package.go b/spdx/v2_1/package.go
new file mode 100644
index 0000000..6b0d7a5
--- /dev/null
+++ b/spdx/v2_1/package.go
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Package is a Package section of an SPDX Document for version 2.1 of the spec.
+type Package struct {
+ // 3.1: Package Name
+ // Cardinality: mandatory, one
+ PackageName string `json:"name"`
+
+ // 3.2: Package SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ PackageSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 3.3: Package Version
+ // Cardinality: optional, one
+ PackageVersion string `json:"versionInfo,omitempty"`
+
+ // 3.4: Package File Name
+ // Cardinality: optional, one
+ PackageFileName string `json:"packageFileName,omitempty"`
+
+ // 3.5: Package Supplier: may have single result for either Person or Organization,
+ // or NOASSERTION
+ // Cardinality: optional, one
+ PackageSupplier *common.Supplier `json:"supplier,omitempty"`
+
+ // 3.6: Package Originator: may have single result for either Person or Organization,
+ // or NOASSERTION
+ // Cardinality: optional, one
+ PackageOriginator *common.Originator `json:"originator,omitempty"`
+
+ // 3.7: Package Download Location
+ // Cardinality: mandatory, one
+ PackageDownloadLocation string `json:"downloadLocation"`
+
+ // 3.8: FilesAnalyzed
+ // Cardinality: optional, one; default value is "true" if omitted
+ FilesAnalyzed bool `json:"filesAnalyzed,omitempty"`
+ // NOT PART OF SPEC: did FilesAnalyzed tag appear?
+ IsFilesAnalyzedTagPresent bool `json:"-"`
+
+ // 3.9: Package Verification Code
+ PackageVerificationCode common.PackageVerificationCode `json:"packageVerificationCode"`
+
+ // 3.10: Package Checksum: may have keys for SHA1, SHA256 and/or MD5
+ // Cardinality: optional, one or many
+ PackageChecksums []common.Checksum `json:"checksums,omitempty"`
+
+ // 3.11: Package Home Page
+ // Cardinality: optional, one
+ PackageHomePage string `json:"homepage,omitempty"`
+
+ // 3.12: Source Information
+ // Cardinality: optional, one
+ PackageSourceInfo string `json:"sourceInfo,omitempty"`
+
+ // 3.13: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageLicenseConcluded string `json:"licenseConcluded"`
+
+ // 3.14: All Licenses Info from Files: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one or many if filesAnalyzed is true / omitted;
+ // zero (must be omitted) if filesAnalyzed is false
+ PackageLicenseInfoFromFiles []string `json:"licenseInfoFromFiles"`
+
+ // 3.15: Declared License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageLicenseDeclared string `json:"licenseDeclared"`
+
+ // 3.16: Comments on License
+ // Cardinality: optional, one
+ PackageLicenseComments string `json:"licenseComments,omitempty"`
+
+ // 3.17: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageCopyrightText string `json:"copyrightText"`
+
+ // 3.18: Package Summary Description
+ // Cardinality: optional, one
+ PackageSummary string `json:"summary,omitempty"`
+
+ // 3.19: Package Detailed Description
+ // Cardinality: optional, one
+ PackageDescription string `json:"description,omitempty"`
+
+ // 3.20: Package Comment
+ // Cardinality: optional, one
+ PackageComment string `json:"comment,omitempty"`
+
+ // 3.21: Package External Reference
+ // Cardinality: optional, one or many
+ PackageExternalReferences []*PackageExternalReference `json:"externalRefs,omitempty"`
+
+ // Files contained in this Package
+ Files []*File `json:"files,omitempty"`
+
+ Annotations []Annotation `json:"annotations,omitempty"`
+}
+
+// PackageExternalReference is an External Reference to additional info
+// about a Package, as defined in section 3.21 in version 2.1 of the spec.
+type PackageExternalReference struct {
+ // category is "SECURITY", "PACKAGE-MANAGER" or "OTHER"
+ Category string `json:"referenceCategory"`
+
+ // type is an [idstring] as defined in Appendix VI;
+ // called RefType here due to "type" being a Golang keyword
+ RefType string `json:"referenceType"`
+
+ // locator is a unique string to access the package-specific
+ // info, metadata or content within the target location
+ Locator string `json:"referenceLocator"`
+
+ // 3.22: Package External Reference Comment
+ // Cardinality: conditional (optional, one) for each External Reference
+ ExternalRefComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_1/relationship.go b/spdx/v2_1/relationship.go
new file mode 100644
index 0000000..006e23f
--- /dev/null
+++ b/spdx/v2_1/relationship.go
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Relationship is a Relationship section of an SPDX Document for
+// version 2.1 of the spec.
+type Relationship struct {
+
+ // 7.1: Relationship
+ // Cardinality: optional, one or more; one per Relationship
+ // one mandatory for SPDX Document with multiple packages
+ // RefA and RefB are first and second item
+ // Relationship is type from 7.1.1
+ RefA common.DocElementID `json:"spdxElementId"`
+ RefB common.DocElementID `json:"relatedSpdxElement"`
+ Relationship string `json:"relationshipType"`
+
+ // 7.2: Relationship Comment
+ // Cardinality: optional, one
+ RelationshipComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_1/review.go b/spdx/v2_1/review.go
new file mode 100644
index 0000000..8d70d00
--- /dev/null
+++ b/spdx/v2_1/review.go
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+// Review is a Review section of an SPDX Document for version 2.1 of the spec.
+// DEPRECATED in version 2.0 of spec; retained here for compatibility.
+type Review struct {
+
+ // DEPRECATED in version 2.0 of spec
+ // 9.1: Reviewer
+ // Cardinality: optional, one
+ Reviewer string
+ // including AnnotatorType: one of "Person", "Organization" or "Tool"
+ ReviewerType string
+
+ // DEPRECATED in version 2.0 of spec
+ // 9.2: Review Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: conditional (mandatory, one) if there is a Reviewer
+ ReviewDate string
+
+ // DEPRECATED in version 2.0 of spec
+ // 9.3: Review Comment
+ // Cardinality: optional, one
+ ReviewComment string
+}
diff --git a/spdx/v2_1/snippet.go b/spdx/v2_1/snippet.go
new file mode 100644
index 0000000..e4d2f59
--- /dev/null
+++ b/spdx/v2_1/snippet.go
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_1
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Snippet is a Snippet section of an SPDX Document for version 2.1 of the spec.
+type Snippet struct {
+
+ // 5.1: Snippet SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ SnippetSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 5.2: Snippet from File SPDX Identifier
+ // Cardinality: mandatory, one
+ SnippetFromFileSPDXIdentifier common.ElementID `json:"snippetFromFile"`
+
+ // Ranges denotes the start/end byte offsets or line numbers that the snippet is relevant to
+ Ranges []common.SnippetRange `json:"ranges"`
+
+ // 5.5: Snippet Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ SnippetLicenseConcluded string `json:"licenseConcluded"`
+
+ // 5.6: License Information in Snippet: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one or many
+ LicenseInfoInSnippet []string `json:"licenseInfoInSnippets,omitempty"`
+
+ // 5.7: Snippet Comments on License
+ // Cardinality: optional, one
+ SnippetLicenseComments string `json:"licenseComments,omitempty"`
+
+ // 5.8: Snippet Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ SnippetCopyrightText string `json:"copyrightText"`
+
+ // 5.9: Snippet Comment
+ // Cardinality: optional, one
+ SnippetComment string `json:"comment,omitempty"`
+
+ // 5.10: Snippet Name
+ // Cardinality: optional, one
+ SnippetName string `json:"name,omitempty"`
+}
diff --git a/spdx/v2_2/annotation.go b/spdx/v2_2/annotation.go
new file mode 100644
index 0000000..35eddc6
--- /dev/null
+++ b/spdx/v2_2/annotation.go
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Annotation is an Annotation section of an SPDX Document for version 2.2 of the spec.
+type Annotation struct {
+ // 12.1: Annotator
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ Annotator common.Annotator `json:"annotator"`
+
+ // 12.2: Annotation Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationDate string `json:"annotationDate"`
+
+ // 12.3: Annotation Type: "REVIEW" or "OTHER"
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationType string `json:"annotationType"`
+
+ // 12.4: SPDX Identifier Reference
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ // This field is not used in hierarchical data formats where the referenced element is clear, such as JSON or YAML.
+ AnnotationSPDXIdentifier common.DocElementID `json:"-"`
+
+ // 12.5: Annotation Comment
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationComment string `json:"comment"`
+}
diff --git a/spdx/v2_2/creation_info.go b/spdx/v2_2/creation_info.go
new file mode 100644
index 0000000..70e611f
--- /dev/null
+++ b/spdx/v2_2/creation_info.go
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// CreationInfo is a Document Creation Information section of an
+// SPDX Document for version 2.2 of the spec.
+type CreationInfo struct {
+ // 6.7: License List Version
+ // Cardinality: optional, one
+ LicenseListVersion string `json:"licenseListVersion"`
+
+ // 6.8: Creators: may have multiple keys for Person, Organization
+ // and/or Tool
+ // Cardinality: mandatory, one or many
+ Creators []common.Creator `json:"creators"`
+
+ // 6.9: Created: data format YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: mandatory, one
+ Created string `json:"created"`
+
+ // 6.10: Creator Comment
+ // Cardinality: optional, one
+ CreatorComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_2/document.go b/spdx/v2_2/document.go
new file mode 100644
index 0000000..31ac08b
--- /dev/null
+++ b/spdx/v2_2/document.go
@@ -0,0 +1,65 @@
+// Package spdx contains the struct definition for an SPDX Document
+// and its constituent parts.
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// ExternalDocumentRef is a reference to an external SPDX document
+// as defined in section 6.6 for version 2.2 of the spec.
+type ExternalDocumentRef struct {
+ // DocumentRefID is the ID string defined in the start of the
+ // reference. It should _not_ contain the "DocumentRef-" part
+ // of the mandatory ID string.
+ DocumentRefID string `json:"externalDocumentId"`
+
+ // URI is the URI defined for the external document
+ URI string `json:"spdxDocument"`
+
+ // Checksum is the actual hash data
+ Checksum common.Checksum `json:"checksum"`
+}
+
+// Document is an SPDX Document for version 2.2 of the spec.
+// See https://spdx.github.io/spdx-spec/v2-draft/ (DRAFT)
+type Document struct {
+ // 6.1: SPDX Version; should be in the format "SPDX-2.2"
+ // Cardinality: mandatory, one
+ SPDXVersion string `json:"spdxVersion"`
+
+ // 6.2: Data License; should be "CC0-1.0"
+ // Cardinality: mandatory, one
+ DataLicense string `json:"dataLicense"`
+
+ // 6.3: SPDX Identifier; should be "DOCUMENT" to represent
+ // mandatory identifier of SPDXRef-DOCUMENT
+ // Cardinality: mandatory, one
+ SPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 6.4: Document Name
+ // Cardinality: mandatory, one
+ DocumentName string `json:"name"`
+
+ // 6.5: Document Namespace
+ // Cardinality: mandatory, one
+ DocumentNamespace string `json:"documentNamespace"`
+
+ // 6.6: External Document References
+ // Cardinality: optional, one or many
+ ExternalDocumentReferences []ExternalDocumentRef `json:"externalDocumentRefs,omitempty"`
+
+ // 6.11: Document Comment
+ // Cardinality: optional, one
+ DocumentComment string `json:"comment,omitempty"`
+
+ CreationInfo *CreationInfo `json:"creationInfo"`
+ Packages []*Package `json:"packages,omitempty"`
+ Files []*File `json:"files,omitempty"`
+ OtherLicenses []*OtherLicense `json:"hasExtractedLicensingInfos,omitempty"`
+ Relationships []*Relationship `json:"relationships,omitempty"`
+ Annotations []*Annotation `json:"annotations,omitempty"`
+ Snippets []Snippet `json:"snippets,omitempty"`
+
+ // DEPRECATED in version 2.0 of spec
+ Reviews []*Review `json:"-"`
+}
diff --git a/spdx/v2_2/file.go b/spdx/v2_2/file.go
new file mode 100644
index 0000000..150e79f
--- /dev/null
+++ b/spdx/v2_2/file.go
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// File is a File section of an SPDX Document for version 2.2 of the spec.
+type File struct {
+ // 8.1: File Name
+ // Cardinality: mandatory, one
+ FileName string `json:"fileName"`
+
+ // 8.2: File SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ FileSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 8.3: File Types
+ // Cardinality: optional, multiple
+ FileTypes []string `json:"fileTypes,omitempty"`
+
+ // 8.4: File Checksum: may have keys for SHA1, SHA256 and/or MD5
+ // Cardinality: mandatory, one SHA1, others may be optionally provided
+ Checksums []common.Checksum `json:"checksums"`
+
+ // 8.5: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ LicenseConcluded string `json:"licenseConcluded"`
+
+ // 8.6: License Information in File: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one or many
+ LicenseInfoInFiles []string `json:"licenseInfoInFiles"`
+
+ // 8.7: Comments on License
+ // Cardinality: optional, one
+ LicenseComments string `json:"licenseComments,omitempty"`
+
+ // 8.8: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ FileCopyrightText string `json:"copyrightText"`
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.9-8.11: Artifact of Project variables (defined below)
+ // Cardinality: optional, one or many
+ ArtifactOfProjects []*ArtifactOfProject `json:"-"`
+
+ // 8.12: File Comment
+ // Cardinality: optional, one
+ FileComment string `json:"comment,omitempty"`
+
+ // 8.13: File Notice
+ // Cardinality: optional, one
+ FileNotice string `json:"noticeText,omitempty"`
+
+ // 8.14: File Contributor
+ // Cardinality: optional, one or many
+ FileContributors []string `json:"fileContributors,omitempty"`
+
+ // 8.15: File Attribution Text
+ // Cardinality: optional, one or many
+ FileAttributionTexts []string `json:"attributionTexts,omitempty"`
+
+ // DEPRECATED in version 2.0 of spec
+ // 8.16: File Dependencies
+ // Cardinality: optional, one or many
+ FileDependencies []string `json:"-"`
+
+ // Snippets contained in this File
+ // Note that Snippets could be defined in a different Document! However,
+ // the only ones that _THIS_ document can contain are this ones that are
+ // defined here -- so this should just be an ElementID.
+ Snippets map[common.ElementID]*Snippet `json:"-"`
+
+ Annotations []Annotation `json:"annotations,omitempty"`
+}
+
+// ArtifactOfProject is a DEPRECATED collection of data regarding
+// a Package, as defined in sections 8.9-8.11 in version 2.2 of the spec.
+type ArtifactOfProject struct {
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.9: Artifact of Project Name
+ // Cardinality: conditional, required if present, one per AOP
+ Name string
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.10: Artifact of Project Homepage: URL or "UNKNOWN"
+ // Cardinality: optional, one per AOP
+ HomePage string
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.11: Artifact of Project Uniform Resource Identifier
+ // Cardinality: optional, one per AOP
+ URI string
+}
diff --git a/spdx/v2_2/other_license.go b/spdx/v2_2/other_license.go
new file mode 100644
index 0000000..1eaf048
--- /dev/null
+++ b/spdx/v2_2/other_license.go
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+// OtherLicense is an Other License Information section of an
+// SPDX Document for version 2.2 of the spec.
+type OtherLicense struct {
+ // 10.1: License Identifier: "LicenseRef-[idstring]"
+ // Cardinality: conditional (mandatory, one) if license is not
+ // on SPDX License List
+ LicenseIdentifier string `json:"licenseId"`
+
+ // 10.2: Extracted Text
+ // Cardinality: conditional (mandatory, one) if there is a
+ // License Identifier assigned
+ ExtractedText string `json:"extractedText"`
+
+ // 10.3: License Name: single line of text or "NOASSERTION"
+ // Cardinality: conditional (mandatory, one) if license is not
+ // on SPDX License List
+ LicenseName string `json:"name,omitempty"`
+
+ // 10.4: License Cross Reference
+ // Cardinality: conditional (optional, one or many) if license
+ // is not on SPDX License List
+ LicenseCrossReferences []string `json:"seeAlsos,omitempty"`
+
+ // 10.5: License Comment
+ // Cardinality: optional, one
+ LicenseComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_2/package.go b/spdx/v2_2/package.go
new file mode 100644
index 0000000..2d99e04
--- /dev/null
+++ b/spdx/v2_2/package.go
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Package is a Package section of an SPDX Document for version 2.2 of the spec.
+type Package struct {
+ // NOT PART OF SPEC
+ // flag: does this "package" contain files that were in fact "unpackaged",
+ // e.g. included directly in the Document without being in a Package?
+ IsUnpackaged bool `json:"-"`
+
+ // 7.1: Package Name
+ // Cardinality: mandatory, one
+ PackageName string `json:"name"`
+
+ // 7.2: Package SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ PackageSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 7.3: Package Version
+ // Cardinality: optional, one
+ PackageVersion string `json:"versionInfo,omitempty"`
+
+ // 7.4: Package File Name
+ // Cardinality: optional, one
+ PackageFileName string `json:"packageFileName,omitempty"`
+
+ // 7.5: Package Supplier: may have single result for either Person or Organization,
+ // or NOASSERTION
+ // Cardinality: optional, one
+ PackageSupplier *common.Supplier `json:"supplier,omitempty"`
+
+ // 7.6: Package Originator: may have single result for either Person or Organization,
+ // or NOASSERTION
+ // Cardinality: optional, one
+ PackageOriginator *common.Originator `json:"originator,omitempty"`
+
+ // 7.7: Package Download Location
+ // Cardinality: mandatory, one
+ PackageDownloadLocation string `json:"downloadLocation"`
+
+ // 7.8: FilesAnalyzed
+ // Cardinality: optional, one; default value is "true" if omitted
+ FilesAnalyzed bool `json:"filesAnalyzed,omitempty"`
+ // NOT PART OF SPEC: did FilesAnalyzed tag appear?
+ IsFilesAnalyzedTagPresent bool `json:"-"`
+
+ // 7.9: Package Verification Code
+ PackageVerificationCode common.PackageVerificationCode `json:"packageVerificationCode"`
+
+ // 7.10: Package Checksum: may have keys for SHA1, SHA256, SHA512 and/or MD5
+ // Cardinality: optional, one or many
+ PackageChecksums []common.Checksum `json:"checksums,omitempty"`
+
+ // 7.11: Package Home Page
+ // Cardinality: optional, one
+ PackageHomePage string `json:"homepage,omitempty"`
+
+ // 7.12: Source Information
+ // Cardinality: optional, one
+ PackageSourceInfo string `json:"sourceInfo,omitempty"`
+
+ // 7.13: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageLicenseConcluded string `json:"licenseConcluded"`
+
+ // 7.14: All Licenses Info from Files: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one or many if filesAnalyzed is true / omitted;
+ // zero (must be omitted) if filesAnalyzed is false
+ PackageLicenseInfoFromFiles []string `json:"licenseInfoFromFiles"`
+
+ // 7.15: Declared License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageLicenseDeclared string `json:"licenseDeclared"`
+
+ // 7.16: Comments on License
+ // Cardinality: optional, one
+ PackageLicenseComments string `json:"licenseComments,omitempty"`
+
+ // 7.17: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageCopyrightText string `json:"copyrightText"`
+
+ // 7.18: Package Summary Description
+ // Cardinality: optional, one
+ PackageSummary string `json:"summary,omitempty"`
+
+ // 7.19: Package Detailed Description
+ // Cardinality: optional, one
+ PackageDescription string `json:"description,omitempty"`
+
+ // 7.20: Package Comment
+ // Cardinality: optional, one
+ PackageComment string `json:"comment,omitempty"`
+
+ // 7.21: Package External Reference
+ // Cardinality: optional, one or many
+ PackageExternalReferences []*PackageExternalReference `json:"externalRefs,omitempty"`
+
+ // 7.22: Package External Reference Comment
+ // Cardinality: conditional (optional, one) for each External Reference
+ // contained within PackageExternalReference2_1 struct, if present
+
+ // 7.23: Package Attribution Text
+ // Cardinality: optional, one or many
+ PackageAttributionTexts []string `json:"attributionTexts,omitempty"`
+
+ // Files contained in this Package
+ Files []*File `json:"files,omitempty"`
+
+ Annotations []Annotation `json:"annotations,omitempty"`
+}
+
+// PackageExternalReference is an External Reference to additional info
+// about a Package, as defined in section 7.21 in version 2.2 of the spec.
+type PackageExternalReference struct {
+ // category is "SECURITY", "PACKAGE-MANAGER" or "OTHER"
+ Category string `json:"referenceCategory"`
+
+ // type is an [idstring] as defined in Appendix VI;
+ // called RefType here due to "type" being a Golang keyword
+ RefType string `json:"referenceType"`
+
+ // locator is a unique string to access the package-specific
+ // info, metadata or content within the target location
+ Locator string `json:"referenceLocator"`
+
+ // 7.22: Package External Reference Comment
+ // Cardinality: conditional (optional, one) for each External Reference
+ ExternalRefComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_2/relationship.go b/spdx/v2_2/relationship.go
new file mode 100644
index 0000000..a93baa7
--- /dev/null
+++ b/spdx/v2_2/relationship.go
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Relationship is a Relationship section of an SPDX Document for
+// version 2.2 of the spec.
+type Relationship struct {
+
+ // 11.1: Relationship
+ // Cardinality: optional, one or more; one per Relationship
+ // one mandatory for SPDX Document with multiple packages
+ // RefA and RefB are first and second item
+ // Relationship is type from 11.1.1
+ RefA common.DocElementID `json:"spdxElementId"`
+ RefB common.DocElementID `json:"relatedSpdxElement"`
+ Relationship string `json:"relationshipType"`
+
+ // 11.2: Relationship Comment
+ // Cardinality: optional, one
+ RelationshipComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_2/review.go b/spdx/v2_2/review.go
new file mode 100644
index 0000000..22b3b8a
--- /dev/null
+++ b/spdx/v2_2/review.go
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+// Review is a Review section of an SPDX Document for version 2.2 of the spec.
+// DEPRECATED in version 2.0 of spec; retained here for compatibility.
+type Review struct {
+
+ // DEPRECATED in version 2.0 of spec
+ // 13.1: Reviewer
+ // Cardinality: optional, one
+ Reviewer string
+ // including AnnotatorType: one of "Person", "Organization" or "Tool"
+ ReviewerType string
+
+ // DEPRECATED in version 2.0 of spec
+ // 13.2: Review Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: conditional (mandatory, one) if there is a Reviewer
+ ReviewDate string
+
+ // DEPRECATED in version 2.0 of spec
+ // 13.3: Review Comment
+ // Cardinality: optional, one
+ ReviewComment string
+}
diff --git a/spdx/v2_2/snippet.go b/spdx/v2_2/snippet.go
new file mode 100644
index 0000000..61045f1
--- /dev/null
+++ b/spdx/v2_2/snippet.go
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_2
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Snippet is a Snippet section of an SPDX Document for version 2.2 of the spec.
+type Snippet struct {
+
+ // 9.1: Snippet SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ SnippetSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 9.2: Snippet from File SPDX Identifier
+ // Cardinality: mandatory, one
+ SnippetFromFileSPDXIdentifier common.ElementID `json:"snippetFromFile"`
+
+ // Ranges denotes the start/end byte offsets or line numbers that the snippet is relevant to
+ Ranges []common.SnippetRange `json:"ranges"`
+
+ // 9.5: Snippet Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ SnippetLicenseConcluded string `json:"licenseConcluded"`
+
+ // 9.6: License Information in Snippet: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one or many
+ LicenseInfoInSnippet []string `json:"licenseInfoInSnippets,omitempty"`
+
+ // 9.7: Snippet Comments on License
+ // Cardinality: optional, one
+ SnippetLicenseComments string `json:"licenseComments,omitempty"`
+
+ // 9.8: Snippet Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ SnippetCopyrightText string `json:"copyrightText"`
+
+ // 9.9: Snippet Comment
+ // Cardinality: optional, one
+ SnippetComment string `json:"comment,omitempty"`
+
+ // 9.10: Snippet Name
+ // Cardinality: optional, one
+ SnippetName string `json:"name,omitempty"`
+
+ // 9.11: Snippet Attribution Text
+ // Cardinality: optional, one or many
+ SnippetAttributionTexts []string `json:"-"`
+}
diff --git a/spdx/v2_3/annotation.go b/spdx/v2_3/annotation.go
new file mode 100644
index 0000000..121e995
--- /dev/null
+++ b/spdx/v2_3/annotation.go
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Annotation is an Annotation section of an SPDX Document for version 2.3 of the spec.
+type Annotation struct {
+ // 12.1: Annotator
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ Annotator common.Annotator `json:"annotator"`
+
+ // 12.2: Annotation Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationDate string `json:"annotationDate"`
+
+ // 12.3: Annotation Type: "REVIEW" or "OTHER"
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationType string `json:"annotationType"`
+
+ // 12.4: SPDX Identifier Reference
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ // This field is not used in hierarchical data formats where the referenced element is clear, such as JSON or YAML.
+ AnnotationSPDXIdentifier common.DocElementID `json:"-" yaml:"-"`
+
+ // 12.5: Annotation Comment
+ // Cardinality: conditional (mandatory, one) if there is an Annotation
+ AnnotationComment string `json:"comment"`
+}
diff --git a/spdx/v2_3/creation_info.go b/spdx/v2_3/creation_info.go
new file mode 100644
index 0000000..33b2caf
--- /dev/null
+++ b/spdx/v2_3/creation_info.go
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// CreationInfo is a Document Creation Information section of an
+// SPDX Document for version 2.3 of the spec.
+type CreationInfo struct {
+ // 6.7: License List Version
+ // Cardinality: optional, one
+ LicenseListVersion string `json:"licenseListVersion"`
+
+ // 6.8: Creators: may have multiple keys for Person, Organization
+ // and/or Tool
+ // Cardinality: mandatory, one or many
+ Creators []common.Creator `json:"creators"`
+
+ // 6.9: Created: data format YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: mandatory, one
+ Created string `json:"created"`
+
+ // 6.10: Creator Comment
+ // Cardinality: optional, one
+ CreatorComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_3/document.go b/spdx/v2_3/document.go
new file mode 100644
index 0000000..32fdb8d
--- /dev/null
+++ b/spdx/v2_3/document.go
@@ -0,0 +1,65 @@
+// Package spdx contains the struct definition for an SPDX Document
+// and its constituent parts.
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// ExternalDocumentRef is a reference to an external SPDX document
+// as defined in section 6.6 for version 2.3 of the spec.
+type ExternalDocumentRef struct {
+ // DocumentRefID is the ID string defined in the start of the
+ // reference. It should _not_ contain the "DocumentRef-" part
+ // of the mandatory ID string.
+ DocumentRefID string `json:"externalDocumentId"`
+
+ // URI is the URI defined for the external document
+ URI string `json:"spdxDocument"`
+
+ // Checksum is the actual hash data
+ Checksum common.Checksum `json:"checksum"`
+}
+
+// Document is an SPDX Document for version 2.3 of the spec.
+// See https://spdx.github.io/spdx-spec/v2.3/document-creation-information
+type Document struct {
+ // 6.1: SPDX Version; should be in the format "SPDX-2.3"
+ // Cardinality: mandatory, one
+ SPDXVersion string `json:"spdxVersion"`
+
+ // 6.2: Data License; should be "CC0-1.0"
+ // Cardinality: mandatory, one
+ DataLicense string `json:"dataLicense"`
+
+ // 6.3: SPDX Identifier; should be "DOCUMENT" to represent
+ // mandatory identifier of SPDXRef-DOCUMENT
+ // Cardinality: mandatory, one
+ SPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 6.4: Document Name
+ // Cardinality: mandatory, one
+ DocumentName string `json:"name"`
+
+ // 6.5: Document Namespace
+ // Cardinality: mandatory, one
+ DocumentNamespace string `json:"documentNamespace"`
+
+ // 6.6: External Document References
+ // Cardinality: optional, one or many
+ ExternalDocumentReferences []ExternalDocumentRef `json:"externalDocumentRefs,omitempty"`
+
+ // 6.11: Document Comment
+ // Cardinality: optional, one
+ DocumentComment string `json:"comment,omitempty"`
+
+ CreationInfo *CreationInfo `json:"creationInfo"`
+ Packages []*Package `json:"packages,omitempty"`
+ Files []*File `json:"files,omitempty"`
+ OtherLicenses []*OtherLicense `json:"hasExtractedLicensingInfos,omitempty"`
+ Relationships []*Relationship `json:"relationships,omitempty"`
+ Annotations []*Annotation `json:"annotations,omitempty"`
+ Snippets []Snippet `json:"snippets,omitempty"`
+
+ // DEPRECATED in version 2.0 of spec
+ Reviews []*Review `json:"-" yaml:"-"`
+}
diff --git a/spdx/v2_3/file.go b/spdx/v2_3/file.go
new file mode 100644
index 0000000..c472fdb
--- /dev/null
+++ b/spdx/v2_3/file.go
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// File is a File section of an SPDX Document for version 2.3 of the spec.
+type File struct {
+ // 8.1: File Name
+ // Cardinality: mandatory, one
+ FileName string `json:"fileName"`
+
+ // 8.2: File SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ FileSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 8.3: File Types
+ // Cardinality: optional, multiple
+ FileTypes []string `json:"fileTypes,omitempty"`
+
+ // 8.4: File Checksum: may have keys for SHA1, SHA256, MD5, SHA3-256, SHA3-384, SHA3-512, BLAKE2b-256, BLAKE2b-384, BLAKE2b-512, BLAKE3, ADLER32
+ // Cardinality: mandatory, one SHA1, others may be optionally provided
+ Checksums []common.Checksum `json:"checksums"`
+
+ // 8.5: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one
+ LicenseConcluded string `json:"licenseConcluded,omitempty"`
+
+ // 8.6: License Information in File: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one or many
+ LicenseInfoInFiles []string `json:"licenseInfoInFiles,omitempty"`
+
+ // 8.7: Comments on License
+ // Cardinality: optional, one
+ LicenseComments string `json:"licenseComments,omitempty"`
+
+ // 8.8: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ FileCopyrightText string `json:"copyrightText"`
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.9-8.11: Artifact of Project variables (defined below)
+ // Cardinality: optional, one or many
+ ArtifactOfProjects []*ArtifactOfProject `json:"artifactOfs,omitempty"`
+
+ // 8.12: File Comment
+ // Cardinality: optional, one
+ FileComment string `json:"comment,omitempty"`
+
+ // 8.13: File Notice
+ // Cardinality: optional, one
+ FileNotice string `json:"noticeText,omitempty"`
+
+ // 8.14: File Contributor
+ // Cardinality: optional, one or many
+ FileContributors []string `json:"fileContributors,omitempty"`
+
+ // 8.15: File Attribution Text
+ // Cardinality: optional, one or many
+ FileAttributionTexts []string `json:"attributionTexts,omitempty"`
+
+ // DEPRECATED in version 2.0 of spec
+ // 8.16: File Dependencies
+ // Cardinality: optional, one or many
+ FileDependencies []string `json:"fileDependencies,omitempty"`
+
+ // Snippets contained in this File
+ // Note that Snippets could be defined in a different Document! However,
+ // the only ones that _THIS_ document can contain are this ones that are
+ // defined here -- so this should just be an ElementID.
+ Snippets map[common.ElementID]*Snippet `json:"-" yaml:"-"`
+
+ Annotations []Annotation `json:"annotations,omitempty"`
+}
+
+// ArtifactOfProject is a DEPRECATED collection of data regarding
+// a Package, as defined in sections 8.9-8.11 in version 2.3 of the spec.
+// NOTE: the JSON schema does not define the structure of this object:
+// https://github.com/spdx/spdx-spec/blob/development/v2.3.1/schemas/spdx-schema.json#L480
+type ArtifactOfProject struct {
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.9: Artifact of Project Name
+ // Cardinality: conditional, required if present, one per AOP
+ Name string `json:"name"`
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.10: Artifact of Project Homepage: URL or "UNKNOWN"
+ // Cardinality: optional, one per AOP
+ HomePage string `json:"homePage"`
+
+ // DEPRECATED in version 2.1 of spec
+ // 8.11: Artifact of Project Uniform Resource Identifier
+ // Cardinality: optional, one per AOP
+ URI string `json:"URI"`
+}
diff --git a/spdx/v2_3/other_license.go b/spdx/v2_3/other_license.go
new file mode 100644
index 0000000..363bb41
--- /dev/null
+++ b/spdx/v2_3/other_license.go
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+// OtherLicense is an Other License Information section of an
+// SPDX Document for version 2.3 of the spec.
+type OtherLicense struct {
+ // 10.1: License Identifier: "LicenseRef-[idstring]"
+ // Cardinality: conditional (mandatory, one) if license is not
+ // on SPDX License List
+ LicenseIdentifier string `json:"licenseId"`
+
+ // 10.2: Extracted Text
+ // Cardinality: conditional (mandatory, one) if there is a
+ // License Identifier assigned
+ ExtractedText string `json:"extractedText"`
+
+ // 10.3: License Name: single line of text or "NOASSERTION"
+ // Cardinality: conditional (mandatory, one) if license is not
+ // on SPDX License List
+ LicenseName string `json:"name,omitempty"`
+
+ // 10.4: License Cross Reference
+ // Cardinality: conditional (optional, one or many) if license
+ // is not on SPDX License List
+ LicenseCrossReferences []string `json:"seeAlsos,omitempty"`
+
+ // 10.5: License Comment
+ // Cardinality: optional, one
+ LicenseComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_3/package.go b/spdx/v2_3/package.go
new file mode 100644
index 0000000..b9d5b95
--- /dev/null
+++ b/spdx/v2_3/package.go
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Package is a Package section of an SPDX Document for version 2.3 of the spec.
+type Package struct {
+ // NOT PART OF SPEC
+ // flag: does this "package" contain files that were in fact "unpackaged",
+ // e.g. included directly in the Document without being in a Package?
+ IsUnpackaged bool `json:"-" yaml:"-"`
+
+ // 7.1: Package Name
+ // Cardinality: mandatory, one
+ PackageName string `json:"name"`
+
+ // 7.2: Package SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ PackageSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 7.3: Package Version
+ // Cardinality: optional, one
+ PackageVersion string `json:"versionInfo,omitempty"`
+
+ // 7.4: Package File Name
+ // Cardinality: optional, one
+ PackageFileName string `json:"packageFileName,omitempty"`
+
+ // 7.5: Package Supplier: may have single result for either Person or Organization,
+ // or NOASSERTION
+ // Cardinality: optional, one
+ PackageSupplier *common.Supplier `json:"supplier,omitempty"`
+
+ // 7.6: Package Originator: may have single result for either Person or Organization,
+ // or NOASSERTION
+ // Cardinality: optional, one
+ PackageOriginator *common.Originator `json:"originator,omitempty"`
+
+ // 7.7: Package Download Location
+ // Cardinality: mandatory, one
+ PackageDownloadLocation string `json:"downloadLocation"`
+
+ // 7.8: FilesAnalyzed
+ // Cardinality: optional, one; default value is "true" if omitted
+ FilesAnalyzed bool `json:"filesAnalyzed,omitempty"`
+ // NOT PART OF SPEC: did FilesAnalyzed tag appear?
+ IsFilesAnalyzedTagPresent bool `json:"-" yaml:"-"`
+
+ // 7.9: Package Verification Code
+ // Cardinality: if FilesAnalyzed == true must be present, if FilesAnalyzed == false must be omitted
+ PackageVerificationCode *common.PackageVerificationCode `json:"packageVerificationCode,omitempty"`
+
+ // 7.10: Package Checksum: may have keys for SHA1, SHA256, SHA512, MD5, SHA3-256, SHA3-384, SHA3-512, BLAKE2b-256, BLAKE2b-384, BLAKE2b-512, BLAKE3, ADLER32
+ // Cardinality: optional, one or many
+ PackageChecksums []common.Checksum `json:"checksums,omitempty"`
+
+ // 7.11: Package Home Page
+ // Cardinality: optional, one
+ PackageHomePage string `json:"homepage,omitempty"`
+
+ // 7.12: Source Information
+ // Cardinality: optional, one
+ PackageSourceInfo string `json:"sourceInfo,omitempty"`
+
+ // 7.13: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one
+ PackageLicenseConcluded string `json:"licenseConcluded,omitempty"`
+
+ // 7.14: All Licenses Info from Files: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one or many if filesAnalyzed is true / omitted;
+ // zero (must be omitted) if filesAnalyzed is false
+ PackageLicenseInfoFromFiles []string `json:"licenseInfoFromFiles,omitempty"`
+
+ // 7.15: Declared License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one
+ PackageLicenseDeclared string `json:"licenseDeclared,omitempty"`
+
+ // 7.16: Comments on License
+ // Cardinality: optional, one
+ PackageLicenseComments string `json:"licenseComments,omitempty"`
+
+ // 7.17: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ PackageCopyrightText string `json:"copyrightText"`
+
+ // 7.18: Package Summary Description
+ // Cardinality: optional, one
+ PackageSummary string `json:"summary,omitempty"`
+
+ // 7.19: Package Detailed Description
+ // Cardinality: optional, one
+ PackageDescription string `json:"description,omitempty"`
+
+ // 7.20: Package Comment
+ // Cardinality: optional, one
+ PackageComment string `json:"comment,omitempty"`
+
+ // 7.21: Package External Reference
+ // Cardinality: optional, one or many
+ PackageExternalReferences []*PackageExternalReference `json:"externalRefs,omitempty"`
+
+ // 7.22: Package External Reference Comment
+ // Cardinality: conditional (optional, one) for each External Reference
+ // contained within PackageExternalReference2_1 struct, if present
+
+ // 7.23: Package Attribution Text
+ // Cardinality: optional, one or many
+ PackageAttributionTexts []string `json:"attributionTexts,omitempty"`
+
+ // 7.24: Primary Package Purpose
+ // Cardinality: optional, one or many
+ // Allowed values: APPLICATION, FRAMEWORK, LIBRARY, CONTAINER, OPERATING-SYSTEM, DEVICE, FIRMWARE, SOURCE, ARCHIVE, FILE, INSTALL, OTHER
+ PrimaryPackagePurpose string `json:"primaryPackagePurpose,omitempty"`
+
+ // 7.25: Release Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: optional, one
+ ReleaseDate string `json:"releaseDate,omitempty"`
+
+ // 7.26: Build Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: optional, one
+ BuiltDate string `json:"builtDate,omitempty"`
+
+ // 7.27: Valid Until Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: optional, one
+ ValidUntilDate string `json:"validUntilDate,omitempty"`
+
+ // Files contained in this Package
+ Files []*File `json:"files,omitempty"`
+
+ Annotations []Annotation `json:"annotations,omitempty"`
+}
+
+// PackageExternalReference is an External Reference to additional info
+// about a Package, as defined in section 7.21 in version 2.3 of the spec.
+type PackageExternalReference struct {
+ // category is "SECURITY", "PACKAGE-MANAGER" or "OTHER"
+ Category string `json:"referenceCategory"`
+
+ // type is an [idstring] as defined in Appendix VI;
+ // called RefType here due to "type" being a Golang keyword
+ RefType string `json:"referenceType"`
+
+ // locator is a unique string to access the package-specific
+ // info, metadata or content within the target location
+ Locator string `json:"referenceLocator"`
+
+ // 7.22: Package External Reference Comment
+ // Cardinality: conditional (optional, one) for each External Reference
+ ExternalRefComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_3/relationship.go b/spdx/v2_3/relationship.go
new file mode 100644
index 0000000..af4c07d
--- /dev/null
+++ b/spdx/v2_3/relationship.go
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Relationship is a Relationship section of an SPDX Document for
+// version 2.3 of the spec.
+type Relationship struct {
+
+ // 11.1: Relationship
+ // Cardinality: optional, one or more; one per Relationship
+ // one mandatory for SPDX Document with multiple packages
+ // RefA and RefB are first and second item
+ // Relationship is type from 11.1.1
+ RefA common.DocElementID `json:"spdxElementId"`
+ RefB common.DocElementID `json:"relatedSpdxElement"`
+ Relationship string `json:"relationshipType"`
+
+ // 11.2: Relationship Comment
+ // Cardinality: optional, one
+ RelationshipComment string `json:"comment,omitempty"`
+}
diff --git a/spdx/v2_3/review.go b/spdx/v2_3/review.go
new file mode 100644
index 0000000..0463807
--- /dev/null
+++ b/spdx/v2_3/review.go
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+// Review is a Review section of an SPDX Document for version 2.3 of the spec.
+// DEPRECATED in version 2.0 of spec; retained here for compatibility.
+type Review struct {
+
+ // DEPRECATED in version 2.0 of spec
+ // 13.1: Reviewer
+ // Cardinality: optional, one
+ Reviewer string
+ // including AnnotatorType: one of "Person", "Organization" or "Tool"
+ ReviewerType string
+
+ // DEPRECATED in version 2.0 of spec
+ // 13.2: Review Date: YYYY-MM-DDThh:mm:ssZ
+ // Cardinality: conditional (mandatory, one) if there is a Reviewer
+ ReviewDate string
+
+ // DEPRECATED in version 2.0 of spec
+ // 13.3: Review Comment
+ // Cardinality: optional, one
+ ReviewComment string
+}
diff --git a/spdx/v2_3/snippet.go b/spdx/v2_3/snippet.go
new file mode 100644
index 0000000..d55a1a9
--- /dev/null
+++ b/spdx/v2_3/snippet.go
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+
+package v2_3
+
+import "github.com/spdx/tools-golang/spdx/common"
+
+// Snippet is a Snippet section of an SPDX Document for version 2.3 of the spec.
+type Snippet struct {
+
+ // 9.1: Snippet SPDX Identifier: "SPDXRef-[idstring]"
+ // Cardinality: mandatory, one
+ SnippetSPDXIdentifier common.ElementID `json:"SPDXID"`
+
+ // 9.2: Snippet from File SPDX Identifier
+ // Cardinality: mandatory, one
+ SnippetFromFileSPDXIdentifier common.ElementID `json:"snippetFromFile"`
+
+ // Ranges denotes the start/end byte offsets or line numbers that the snippet is relevant to
+ Ranges []common.SnippetRange `json:"ranges"`
+
+ // 9.5: Snippet Concluded License: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one
+ SnippetLicenseConcluded string `json:"licenseConcluded,omitempty"`
+
+ // 9.6: License Information in Snippet: SPDX License Expression, "NONE" or "NOASSERTION"
+ // Cardinality: optional, one or many
+ LicenseInfoInSnippet []string `json:"licenseInfoInSnippets,omitempty"`
+
+ // 9.7: Snippet Comments on License
+ // Cardinality: optional, one
+ SnippetLicenseComments string `json:"licenseComments,omitempty"`
+
+ // 9.8: Snippet Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION"
+ // Cardinality: mandatory, one
+ SnippetCopyrightText string `json:"copyrightText"`
+
+ // 9.9: Snippet Comment
+ // Cardinality: optional, one
+ SnippetComment string `json:"comment,omitempty"`
+
+ // 9.10: Snippet Name
+ // Cardinality: optional, one
+ SnippetName string `json:"name,omitempty"`
+
+ // 9.11: Snippet Attribution Text
+ // Cardinality: optional, one or many
+ SnippetAttributionTexts []string `json:"-" yaml:"-"`
+}