diff options
author | Ian Ling <ian@iancaling.com> | 2022-04-08 08:52:57 -0700 |
---|---|---|
committer | Ian Ling <ian@iancaling.com> | 2022-04-25 15:00:47 -0700 |
commit | 460cf54ece7eba418c50407ee35544c5d63588a7 (patch) | |
tree | 07ec7aaf51a92a1ae209e540f45241f990561919 /spdx | |
parent | fa24fac85dd550a3f815896241081a1246810d2c (diff) | |
download | spdx-tools-460cf54ece7eba418c50407ee35544c5d63588a7.tar.gz |
Overhaul structs, refactor JSON parser and saver
Signed-off-by: Ian Ling <ian@iancaling.com>
Diffstat (limited to 'spdx')
-rw-r--r-- | spdx/annotation.go | 69 | ||||
-rw-r--r-- | spdx/checksum.go | 26 | ||||
-rw-r--r-- | spdx/creation_info.go | 151 | ||||
-rw-r--r-- | spdx/document.go | 114 | ||||
-rw-r--r-- | spdx/file.go | 72 | ||||
-rw-r--r-- | spdx/identifier.go | 62 | ||||
-rw-r--r-- | spdx/other_license.go | 22 | ||||
-rw-r--r-- | spdx/package.go | 246 | ||||
-rw-r--r-- | spdx/relationship.go | 16 | ||||
-rw-r--r-- | spdx/snippet.go | 73 |
10 files changed, 528 insertions, 323 deletions
diff --git a/spdx/annotation.go b/spdx/annotation.go index ede9c8a..560b6f0 100644 --- a/spdx/annotation.go +++ b/spdx/annotation.go @@ -2,54 +2,91 @@ package spdx -// Annotation2_1 is an Annotation section of an SPDX Document for version 2.1 of the spec. -type Annotation2_1 struct { +import ( + "encoding/json" + "fmt" + "strings" +) - // 8.1: Annotator - // Cardinality: conditional (mandatory, one) if there is an Annotation +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 +} + +// Annotation2_1 is an Annotation section of an SPDX Document for version 2.1 of the spec. +type Annotation2_1 struct { + // 8.1: Annotator + // Cardinality: conditional (mandatory, one) if there is an Annotation + Annotator Annotator `json:"annotator"` // 8.2: Annotation Date: YYYY-MM-DDThh:mm:ssZ // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationDate string + AnnotationDate string `json:"annotationDate"` // 8.3: Annotation Type: "REVIEW" or "OTHER" // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationType string + AnnotationType string `json:"annotationType"` // 8.4: SPDX Identifier Reference // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationSPDXIdentifier DocElementID + // This field is not used in hierarchical data formats where the referenced element is clear, such as JSON or YAML. + AnnotationSPDXIdentifier DocElementID `json:"-"` // 8.5: Annotation Comment // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationComment string + AnnotationComment string `json:"comment"` } // Annotation2_2 is an Annotation section of an SPDX Document for version 2.2 of the spec. type Annotation2_2 struct { - // 8.1: Annotator // Cardinality: conditional (mandatory, one) if there is an Annotation - Annotator string - // including AnnotatorType: one of "Person", "Organization" or "Tool" - AnnotatorType string + Annotator Annotator `json:"annotator"` // 8.2: Annotation Date: YYYY-MM-DDThh:mm:ssZ // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationDate string + AnnotationDate string `json:"annotationDate"` // 8.3: Annotation Type: "REVIEW" or "OTHER" // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationType string + AnnotationType string `json:"annotationType"` // 8.4: SPDX Identifier Reference // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationSPDXIdentifier DocElementID + // This field is not used in hierarchical data formats where the referenced element is clear, such as JSON or YAML. + AnnotationSPDXIdentifier DocElementID `json:"-"` // 8.5: Annotation Comment // Cardinality: conditional (mandatory, one) if there is an Annotation - AnnotationComment string + AnnotationComment string `json:"comment"` } diff --git a/spdx/checksum.go b/spdx/checksum.go index 872aee2..3295969 100644 --- a/spdx/checksum.go +++ b/spdx/checksum.go @@ -2,25 +2,25 @@ package spdx -// ChecksumAlgorithm2_2 represents the algorithm used to generate the file checksum in the Checksum2_2 struct. +// 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 = "SHA1" - SHA256 = "SHA256" - SHA384 = "SHA384" - SHA512 = "SHA512" - MD2 = "MD2" - MD4 = "MD4" - MD5 = "MD5" - MD6 = "MD6" + SHA1 ChecksumAlgorithm = "SHA1" + SHA256 ChecksumAlgorithm = "SHA256" + SHA384 ChecksumAlgorithm = "SHA384" + SHA512 ChecksumAlgorithm = "SHA512" + MD2 ChecksumAlgorithm = "MD2" + MD4 ChecksumAlgorithm = "MD4" + MD5 ChecksumAlgorithm = "MD5" + MD6 ChecksumAlgorithm = "MD6" ) -//Checksum2_2 struct Provide a unique identifier to match analysis information on each specific file in a package. -// The Algorithm field describes the ChecksumAlgorithm2_2 used and the Value represents the file checksum +// 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 - Value string + Algorithm ChecksumAlgorithm `json:"algorithm"` + Value string `json:"checksumValue"` } diff --git a/spdx/creation_info.go b/spdx/creation_info.go index 1bdaaab..c0b6f63 100644 --- a/spdx/creation_info.go +++ b/spdx/creation_info.go @@ -2,146 +2,85 @@ package spdx -// CreationInfo2_1 is a Document Creation Information section of an -// SPDX Document for version 2.1 of the spec. -type CreationInfo2_1 struct { +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 +} - // 2.1: SPDX Version; should be in the format "SPDX-2.1" - // Cardinality: mandatory, one - SPDXVersion 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) - // 2.2: Data License; should be "CC0-1.0" - // Cardinality: mandatory, one - DataLicense string + if len(fields) != 2 { + return fmt.Errorf("failed to parse Creator '%s'", str) + } - // 2.3: SPDX Identifier; should be "DOCUMENT" to represent - // mandatory identifier of SPDXRef-DOCUMENT - // Cardinality: mandatory, one - SPDXIdentifier ElementID + c.CreatorType = fields[0] + c.Creator = fields[1] - // 2.4: Document Name - // Cardinality: mandatory, one - DocumentName string + return nil +} - // 2.5: Document Namespace - // Cardinality: mandatory, one - DocumentNamespace string +// 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)) + } - // 2.6: External Document References - // Cardinality: optional, one or many - ExternalDocumentReferences map[string]ExternalDocumentRef2_1 + return []byte{}, nil +} +// CreationInfo2_1 is a Document Creation Information section of an +// SPDX Document for version 2.1 of the spec. +type CreationInfo2_1 struct { // 2.7: License List Version // Cardinality: optional, one - LicenseListVersion string + LicenseListVersion string `json:"licenseListVersion"` // 2.8: Creators: may have multiple keys for Person, Organization // and/or Tool // Cardinality: mandatory, one or many - CreatorPersons []string - CreatorOrganizations []string - CreatorTools []string + Creators []Creator `json:"creators"` // 2.9: Created: data format YYYY-MM-DDThh:mm:ssZ // Cardinality: mandatory, one - Created string + Created string `json:"created"` // 2.10: Creator Comment // Cardinality: optional, one - CreatorComment string - - // 2.11: Document Comment - // Cardinality: optional, one - DocumentComment string -} - -// ExternalDocumentRef2_1 is a reference to an external SPDX document -// as defined in section 2.6 for version 2.1 of the spec. -type ExternalDocumentRef2_1 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 - - // URI is the URI defined for the external document - URI string - - // Alg is the type of hash algorithm used, e.g. "SHA1", "SHA256" - Alg string - - // Checksum is the actual hash data - Checksum string + CreatorComment string `json:"comment"` } // CreationInfo2_2 is a Document Creation Information section of an // SPDX Document for version 2.2 of the spec. type CreationInfo2_2 struct { - - // 2.1: SPDX Version; should be in the format "SPDX-2.2" - // Cardinality: mandatory, one - SPDXVersion string - - // 2.2: Data License; should be "CC0-1.0" - // Cardinality: mandatory, one - DataLicense string - - // 2.3: SPDX Identifier; should be "DOCUMENT" to represent - // mandatory identifier of SPDXRef-DOCUMENT - // Cardinality: mandatory, one - SPDXIdentifier ElementID - - // 2.4: Document Name - // Cardinality: mandatory, one - DocumentName string - - // 2.5: Document Namespace - // Cardinality: mandatory, one - DocumentNamespace string - - // 2.6: External Document References - // Cardinality: optional, one or many - ExternalDocumentReferences map[string]ExternalDocumentRef2_2 - // 2.7: License List Version // Cardinality: optional, one - LicenseListVersion string + LicenseListVersion string `json:"licenseListVersion"` // 2.8: Creators: may have multiple keys for Person, Organization // and/or Tool // Cardinality: mandatory, one or many - CreatorPersons []string - CreatorOrganizations []string - CreatorTools []string + Creators []Creator `json:"creators"` // 2.9: Created: data format YYYY-MM-DDThh:mm:ssZ // Cardinality: mandatory, one - Created string + Created string `json:"created"` // 2.10: Creator Comment // Cardinality: optional, one - CreatorComment string - - // 2.11: Document Comment - // Cardinality: optional, one - DocumentComment string -} - -// ExternalDocumentRef2_2 is a reference to an external SPDX document -// as defined in section 2.6 for version 2.2 of the spec. -type ExternalDocumentRef2_2 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 - - // URI is the URI defined for the external document - URI string - - // Alg is the type of hash algorithm used, e.g. "SHA1", "SHA256" - Alg string - - // Checksum is the actual hash data - Checksum string + CreatorComment string `json:"comment"` } diff --git a/spdx/document.go b/spdx/document.go index 6a7bc3d..a3117cb 100644 --- a/spdx/document.go +++ b/spdx/document.go @@ -3,15 +3,75 @@ // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later package spdx +// ExternalDocumentRef2_1 is a reference to an external SPDX document +// as defined in section 2.6 for version 2.1 of the spec. +type ExternalDocumentRef2_1 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 Checksum `json:"checksum"` +} + +// ExternalDocumentRef2_2 is a reference to an external SPDX document +// as defined in section 2.6 for version 2.2 of the spec. +type ExternalDocumentRef2_2 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 Checksum `json:"checksum"` +} + // Document2_1 is an SPDX Document for version 2.1 of the spec. // See https://spdx.org/sites/cpstandard/files/pages/files/spdxversion2.1.pdf type Document2_1 struct { - CreationInfo *CreationInfo2_1 - Packages map[ElementID]*Package2_1 - UnpackagedFiles map[ElementID]*File2_1 - OtherLicenses []*OtherLicense2_1 - Relationships []*Relationship2_1 - Annotations []*Annotation2_1 + // 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 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 []ExternalDocumentRef2_1 `json:"externalDocumentRefs,omitempty"` + + // 2.11: Document Comment + // Cardinality: optional, one + DocumentComment string `json:"comment,omitempty"` + + CreationInfo *CreationInfo2_1 `json:"creationInfo"` + Packages []*Package2_1 `json:"packages"` + Files []*File2_1 `json:"files"` + OtherLicenses []*OtherLicense2_1 `json:"hasExtractedLicensingInfos"` + Relationships []*Relationship2_1 `json:"relationships"` + Annotations []*Annotation2_1 `json:"annotations"` + Snippets []Snippet2_1 `json:"snippets"` // DEPRECATED in version 2.0 of spec Reviews []*Review2_1 @@ -20,12 +80,42 @@ type Document2_1 struct { // Document2_2 is an SPDX Document for version 2.2 of the spec. // See https://spdx.github.io/spdx-spec/v2-draft/ (DRAFT) type Document2_2 struct { - CreationInfo *CreationInfo2_2 - Packages map[ElementID]*Package2_2 - UnpackagedFiles map[ElementID]*File2_2 - OtherLicenses []*OtherLicense2_2 - Relationships []*Relationship2_2 - Annotations []*Annotation2_2 + // 2.1: SPDX Version; should be in the format "SPDX-2.2" + // 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 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 []ExternalDocumentRef2_2 `json:"externalDocumentRefs,omitempty"` + + // 2.11: Document Comment + // Cardinality: optional, one + DocumentComment string `json:"comment,omitempty"` + + CreationInfo *CreationInfo2_2 `json:"creationInfo"` + Packages []*Package2_2 `json:"packages"` + Files []*File2_2 `json:"files"` + OtherLicenses []*OtherLicense2_2 `json:"hasExtractedLicensingInfos"` + Relationships []*Relationship2_2 `json:"relationships"` + Annotations []*Annotation2_2 `json:"annotations"` + Snippets []Snippet2_2 `json:"snippets"` // DEPRECATED in version 2.0 of spec Reviews []*Review2_2 diff --git a/spdx/file.go b/spdx/file.go index a745dc3..01dbb36 100644 --- a/spdx/file.go +++ b/spdx/file.go @@ -4,68 +4,67 @@ package spdx // File2_1 is a File section of an SPDX Document for version 2.1 of the spec. type File2_1 struct { - // 4.1: File Name // Cardinality: mandatory, one - FileName string + FileName string `json:"fileName"` // 4.2: File SPDX Identifier: "SPDXRef-[idstring]" // Cardinality: mandatory, one - FileSPDXIdentifier ElementID + FileSPDXIdentifier ElementID `json:"SPDXID"` - // 4.3: File Type + // 4.3: File Types // Cardinality: optional, multiple - FileType []string + 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 - FileChecksumSHA1 string - FileChecksumSHA256 string - FileChecksumMD5 string + Checksums []Checksum `json:"checksums"` // 4.5: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - LicenseConcluded string + LicenseConcluded string `json:"licenseConcluded"` // 4.6: License Information in File: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one or many - LicenseInfoInFile []string + LicenseInfoInFiles []string `json:"licenseInfoInFiles"` // 4.7: Comments on License // Cardinality: optional, one - LicenseComments string + LicenseComments string `json:"licenseComments,omitempty"` // 4.8: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - FileCopyrightText string + 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 []*ArtifactOfProject2_1 + ArtifactOfProjects []*ArtifactOfProject2_1 `json:"-"` // 4.12: File Comment // Cardinality: optional, one - FileComment string + FileComment string `json:"comment,omitempty"` // 4.13: File Notice // Cardinality: optional, one - FileNotice string + FileNotice string `json:"noticeText,omitempty"` // 4.14: File Contributor // Cardinality: optional, one or many - FileContributor []string + FileContributors []string `json:"fileContributors,omitempty"` // DEPRECATED in version 2.0 of spec // 4.15: File Dependencies // Cardinality: optional, one or many - FileDependencies []string + 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 + // the only ones that _THIS_ document can contain are the ones that are // defined here -- so this should just be an ElementID. - Snippets map[ElementID]*Snippet2_1 + Snippets map[ElementID]*Snippet2_1 `json:"-"` + + Annotations []Annotation2_1 `json:"annotations"` } // ArtifactOfProject2_1 is a DEPRECATED collection of data regarding @@ -90,70 +89,71 @@ type ArtifactOfProject2_1 struct { // File2_2 is a File section of an SPDX Document for version 2.2 of the spec. type File2_2 struct { - // 4.1: File Name // Cardinality: mandatory, one - FileName string + FileName string `json:"fileName"` // 4.2: File SPDX Identifier: "SPDXRef-[idstring]" // Cardinality: mandatory, one - FileSPDXIdentifier ElementID + FileSPDXIdentifier ElementID `json:"SPDXID"` - // 4.3: File Type + // 4.3: File Types // Cardinality: optional, multiple - FileType []string + 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 - FileChecksums map[ChecksumAlgorithm]Checksum + Checksums []Checksum `json:"checksums"` // 4.5: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - LicenseConcluded string + LicenseConcluded string `json:"licenseConcluded"` // 4.6: License Information in File: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one or many - LicenseInfoInFile []string + LicenseInfoInFiles []string `json:"licenseInfoInFiles"` // 4.7: Comments on License // Cardinality: optional, one - LicenseComments string + LicenseComments string `json:"licenseComments,omitempty"` // 4.8: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - FileCopyrightText string + 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 []*ArtifactOfProject2_2 + ArtifactOfProjects []*ArtifactOfProject2_2 `json:"-"` // 4.12: File Comment // Cardinality: optional, one - FileComment string + FileComment string `json:"comment,omitempty"` // 4.13: File Notice // Cardinality: optional, one - FileNotice string + FileNotice string `json:"noticeText,omitempty"` // 4.14: File Contributor // Cardinality: optional, one or many - FileContributor []string + FileContributors []string `json:"fileContributors,omitempty"` // 4.15: File Attribution Text // Cardinality: optional, one or many - FileAttributionTexts []string + FileAttributionTexts []string `json:"attributionTexts,omitempty"` // DEPRECATED in version 2.0 of spec // 4.16: File Dependencies // Cardinality: optional, one or many - FileDependencies []string + 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[ElementID]*Snippet2_2 + Snippets map[ElementID]*Snippet2_2 `json:"-"` + + Annotations []Annotation2_2 `json:"annotations,omitempty"` } // ArtifactOfProject2_2 is a DEPRECATED collection of data regarding diff --git a/spdx/identifier.go b/spdx/identifier.go index baf44c1..56f8ffc 100644 --- a/spdx/identifier.go +++ b/spdx/identifier.go @@ -2,6 +2,12 @@ package spdx +import ( + "encoding/json" + "fmt" + "strings" +) + // 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. @@ -28,6 +34,62 @@ type DocElementID struct { SpecialID string } +// 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) 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, "DocumentRef-") { + // strip out the "DocumentRef-" so we can get the value + idFields = strings.SplitN(idStr, "DocumentRef-", 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 + } + } + + // handle SPDXRef- + idFields = strings.SplitN(idStr, "SPDXRef-", 2) + if len(idFields) != 2 { + return fmt.Errorf("failed to parse SPDX Identifier '%s'", idStr) + } + + d.ElementRefID = ElementID(idFields[1]) + + return nil +} + +// 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 != "" { + return json.Marshal(fmt.Sprintf("DocumentRef-%s:SPDXRef-%s", d.DocumentRefID, d.ElementRefID)) + } else if d.ElementRefID != "" { + return json.Marshal(fmt.Sprintf("SPDXRef-%s", d.ElementRefID)) + } else if d.SpecialID != "" { + return json.Marshal(d.SpecialID) + } + + return []byte{}, fmt.Errorf("failed to marshal empty DocElementID") +} + // TODO: add equivalents for LicenseRef- identifiers // MakeDocElementID takes strings (without prefixes) for the DocumentRef- diff --git a/spdx/other_license.go b/spdx/other_license.go index a509c47..6e43676 100644 --- a/spdx/other_license.go +++ b/spdx/other_license.go @@ -5,57 +5,55 @@ package spdx // OtherLicense2_1 is an Other License Information section of an // SPDX Document for version 2.1 of the spec. type OtherLicense2_1 struct { - // 6.1: License Identifier: "LicenseRef-[idstring]" // Cardinality: conditional (mandatory, one) if license is not // on SPDX License List - LicenseIdentifier string + LicenseIdentifier string `json:"licenseId"` // 6.2: Extracted Text // Cardinality: conditional (mandatory, one) if there is a // License Identifier assigned - ExtractedText string + 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 + 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 + LicenseCrossReferences []string `json:"seeAlsos,omitempty"` // 6.5: License Comment // Cardinality: optional, one - LicenseComment string + LicenseComment string `json:"comment,omitempty"` } // OtherLicense2_2 is an Other License Information section of an // SPDX Document for version 2.2 of the spec. type OtherLicense2_2 struct { - // 6.1: License Identifier: "LicenseRef-[idstring]" // Cardinality: conditional (mandatory, one) if license is not // on SPDX License List - LicenseIdentifier string + LicenseIdentifier string `json:"licenseId"` // 6.2: Extracted Text // Cardinality: conditional (mandatory, one) if there is a // License Identifier assigned - ExtractedText string + 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 + 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 + LicenseCrossReferences []string `json:"seeAlsos,omitempty"` // 6.5: License Comment // Cardinality: optional, one - LicenseComment string + LicenseComment string `json:"comment,omitempty"` } diff --git a/spdx/package.go b/spdx/package.go index 9aeb8a2..e6c4522 100644 --- a/spdx/package.go +++ b/spdx/package.go @@ -2,140 +2,225 @@ package spdx +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"` +} + // Package2_1 is a Package section of an SPDX Document for version 2.1 of the spec. type Package2_1 struct { - // 3.1: Package Name // Cardinality: mandatory, one - PackageName string + PackageName string `json:"name"` // 3.2: Package SPDX Identifier: "SPDXRef-[idstring]" // Cardinality: mandatory, one - PackageSPDXIdentifier ElementID + PackageSPDXIdentifier ElementID `json:"SPDXID"` // 3.3: Package Version // Cardinality: optional, one - PackageVersion string + PackageVersion string `json:"versionInfo,omitempty"` // 3.4: Package File Name // Cardinality: optional, one - PackageFileName string + PackageFileName string `json:"packageFileName,omitempty"` // 3.5: Package Supplier: may have single result for either Person or Organization, // or NOASSERTION // Cardinality: optional, one - PackageSupplierPerson string - PackageSupplierOrganization string - PackageSupplierNOASSERTION bool + PackageSupplier *Supplier `json:"supplier,omitempty"` // 3.6: Package Originator: may have single result for either Person or Organization, // or NOASSERTION // Cardinality: optional, one - PackageOriginatorPerson string - PackageOriginatorOrganization string - PackageOriginatorNOASSERTION bool + PackageOriginator *Originator `json:"originator,omitempty"` // 3.7: Package Download Location // Cardinality: mandatory, one - PackageDownloadLocation string + PackageDownloadLocation string `json:"downloadLocation"` // 3.8: FilesAnalyzed // Cardinality: optional, one; default value is "true" if omitted - FilesAnalyzed bool + FilesAnalyzed bool `json:"filesAnalyzed,omitempty"` // NOT PART OF SPEC: did FilesAnalyzed tag appear? - IsFilesAnalyzedTagPresent bool + IsFilesAnalyzedTagPresent bool `json:"-"` // 3.9: Package Verification Code - // Cardinality: mandatory, one if filesAnalyzed is true / omitted; - // zero (must be omitted) if filesAnalyzed is false - PackageVerificationCode string - // Spec also allows specifying a single file to exclude from the - // verification code algorithm; intended to enable exclusion of - // the SPDX document file itself. - PackageVerificationCodeExcludedFile string + PackageVerificationCode PackageVerificationCode `json:"packageVerificationCode"` // 3.10: Package Checksum: may have keys for SHA1, SHA256 and/or MD5 // Cardinality: optional, one or many - PackageChecksumSHA1 string - PackageChecksumSHA256 string - PackageChecksumMD5 string + PackageChecksums []Checksum `json:"checksums,omitempty"` // 3.11: Package Home Page // Cardinality: optional, one - PackageHomePage string + PackageHomePage string `json:"homepage,omitempty"` // 3.12: Source Information // Cardinality: optional, one - PackageSourceInfo string + PackageSourceInfo string `json:"sourceInfo,omitempty"` // 3.13: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - PackageLicenseConcluded string + 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 + PackageLicenseInfoFromFiles []string `json:"licenseInfoFromFiles"` // 3.15: Declared License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - PackageLicenseDeclared string + PackageLicenseDeclared string `json:"licenseDeclared"` // 3.16: Comments on License // Cardinality: optional, one - PackageLicenseComments string + PackageLicenseComments string `json:"licenseComments,omitempty"` // 3.17: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - PackageCopyrightText string + PackageCopyrightText string `json:"copyrightText"` // 3.18: Package Summary Description // Cardinality: optional, one - PackageSummary string + PackageSummary string `json:"summary,omitempty"` // 3.19: Package Detailed Description // Cardinality: optional, one - PackageDescription string + PackageDescription string `json:"description,omitempty"` // 3.20: Package Comment // Cardinality: optional, one - PackageComment string + PackageComment string `json:"comment,omitempty"` // 3.21: Package External Reference // Cardinality: optional, one or many - PackageExternalReferences []*PackageExternalReference2_1 - - // 3.22: Package External Reference Comment - // Cardinality: conditional (optional, one) for each External Reference - // contained within PackageExternalReference2_1 struct, if present + PackageExternalReferences []*PackageExternalReference2_1 `json:"externalRefs,omitempty"` // Files contained in this Package - Files map[ElementID]*File2_1 + Files []*File2_1 + + Annotations []Annotation2_1 `json:"annotations,omitempty"` } // PackageExternalReference2_1 is an External Reference to additional info // about a Package, as defined in section 3.21 in version 2.1 of the spec. type PackageExternalReference2_1 struct { - // category is "SECURITY", "PACKAGE-MANAGER" or "OTHER" - Category string + 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 + RefType string `json:"referenceType"` // locator is a unique string to access the package-specific // info, metadata or content within the target location - Locator string + Locator string `json:"referenceLocator"` // 3.22: Package External Reference Comment // Cardinality: conditional (optional, one) for each External Reference - ExternalRefComment string + ExternalRefComment string `json:"comment"` } // Package2_2 is a Package section of an SPDX Document for version 2.2 of the spec. type Package2_2 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? @@ -143,101 +228,91 @@ type Package2_2 struct { // 3.1: Package Name // Cardinality: mandatory, one - PackageName string + PackageName string `json:"name"` // 3.2: Package SPDX Identifier: "SPDXRef-[idstring]" // Cardinality: mandatory, one - PackageSPDXIdentifier ElementID + PackageSPDXIdentifier ElementID `json:"SPDXID"` // 3.3: Package Version // Cardinality: optional, one - PackageVersion string + PackageVersion string `json:"versionInfo,omitempty"` // 3.4: Package File Name // Cardinality: optional, one - PackageFileName string + PackageFileName string `json:"packageFileName,omitempty"` // 3.5: Package Supplier: may have single result for either Person or Organization, // or NOASSERTION // Cardinality: optional, one - PackageSupplierPerson string - PackageSupplierOrganization string - PackageSupplierNOASSERTION bool + PackageSupplier *Supplier `json:"supplier,omitempty"` // 3.6: Package Originator: may have single result for either Person or Organization, // or NOASSERTION // Cardinality: optional, one - PackageOriginatorPerson string - PackageOriginatorOrganization string - PackageOriginatorNOASSERTION bool + PackageOriginator *Originator `json:"originator,omitempty"` // 3.7: Package Download Location // Cardinality: mandatory, one - PackageDownloadLocation string + PackageDownloadLocation string `json:"downloadLocation"` // 3.8: FilesAnalyzed // Cardinality: optional, one; default value is "true" if omitted - FilesAnalyzed bool + FilesAnalyzed bool `json:"filesAnalyzed,omitempty"` // NOT PART OF SPEC: did FilesAnalyzed tag appear? IsFilesAnalyzedTagPresent bool // 3.9: Package Verification Code - // Cardinality: mandatory, one if filesAnalyzed is true / omitted; - // zero (must be omitted) if filesAnalyzed is false - PackageVerificationCode string - // Spec also allows specifying a single file to exclude from the - // verification code algorithm; intended to enable exclusion of - // the SPDX document file itself. - PackageVerificationCodeExcludedFile string + PackageVerificationCode PackageVerificationCode `json:"packageVerificationCode"` // 3.10: Package Checksum: may have keys for SHA1, SHA256 and/or MD5 // Cardinality: optional, one or many - PackageChecksums map[ChecksumAlgorithm]Checksum + PackageChecksums []Checksum `json:"checksums"` // 3.11: Package Home Page // Cardinality: optional, one - PackageHomePage string + PackageHomePage string `json:"homepage,omitempty"` // 3.12: Source Information // Cardinality: optional, one - PackageSourceInfo string + PackageSourceInfo string `json:"sourceInfo,omitempty"` // 3.13: Concluded License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - PackageLicenseConcluded string + 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 + PackageLicenseInfoFromFiles []string `json:"licenseInfoFromFiles"` // 3.15: Declared License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - PackageLicenseDeclared string + PackageLicenseDeclared string `json:"licenseDeclared"` // 3.16: Comments on License // Cardinality: optional, one - PackageLicenseComments string + PackageLicenseComments string `json:"licenseComments,omitempty"` // 3.17: Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - PackageCopyrightText string + PackageCopyrightText string `json:"copyrightText"` // 3.18: Package Summary Description // Cardinality: optional, one - PackageSummary string + PackageSummary string `json:"summary,omitempty"` // 3.19: Package Detailed Description // Cardinality: optional, one - PackageDescription string + PackageDescription string `json:"description,omitempty"` // 3.20: Package Comment // Cardinality: optional, one - PackageComment string + PackageComment string `json:"comment,omitempty"` // 3.21: Package External Reference // Cardinality: optional, one or many - PackageExternalReferences []*PackageExternalReference2_2 + PackageExternalReferences []*PackageExternalReference2_2 `json:"externalRefs,omitempty"` // 3.22: Package External Reference Comment // Cardinality: conditional (optional, one) for each External Reference @@ -245,28 +320,29 @@ type Package2_2 struct { // 3.23: Package Attribution Text // Cardinality: optional, one or many - PackageAttributionTexts []string + PackageAttributionTexts []string `json:"attributionTexts,omitempty"` // Files contained in this Package - Files map[ElementID]*File2_2 + Files []*File2_2 + + Annotations []Annotation2_2 `json:"annotations"` } // PackageExternalReference2_2 is an External Reference to additional info // about a Package, as defined in section 3.21 in version 2.2 of the spec. type PackageExternalReference2_2 struct { - - // category is "SECURITY", "PACKAGE-MANAGER", "PERSISTENT-ID" or "OTHER" - Category string + // 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 + RefType string `json:"referenceType"` // locator is a unique string to access the package-specific // info, metadata or content within the target location - Locator string + Locator string `json:"referenceLocator"` // 3.22: Package External Reference Comment // Cardinality: conditional (optional, one) for each External Reference - ExternalRefComment string + ExternalRefComment string `json:"comment"` } diff --git a/spdx/relationship.go b/spdx/relationship.go index 9e06838..9127727 100644 --- a/spdx/relationship.go +++ b/spdx/relationship.go @@ -11,13 +11,13 @@ type Relationship2_1 struct { // one mandatory for SPDX Document with multiple packages // RefA and RefB are first and second item // Relationship is type from 7.1.1 - RefA DocElementID - RefB DocElementID - Relationship string + RefA DocElementID `json:"spdxElementId"` + RefB DocElementID `json:"relatedSpdxElement"` + Relationship string `json:"relationshipType"` // 7.2: Relationship Comment // Cardinality: optional, one - RelationshipComment string + RelationshipComment string `json:"comment,omitempty"` } // Relationship2_2 is a Relationship section of an SPDX Document for @@ -29,11 +29,11 @@ type Relationship2_2 struct { // one mandatory for SPDX Document with multiple packages // RefA and RefB are first and second item // Relationship is type from 7.1.1 - RefA DocElementID - RefB DocElementID - Relationship string + RefA DocElementID `json:"spdxElementId"` + RefB DocElementID `json:"relatedSpdxElement"` + Relationship string `json:"relationshipType"` // 7.2: Relationship Comment // Cardinality: optional, one - RelationshipComment string + RelationshipComment string `json:"comment,omitempty"` } diff --git a/spdx/snippet.go b/spdx/snippet.go index 5fe37ca..6bffb8c 100644 --- a/spdx/snippet.go +++ b/spdx/snippet.go @@ -2,50 +2,60 @@ package spdx +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"` +} + // Snippet2_1 is a Snippet section of an SPDX Document for version 2.1 of the spec. type Snippet2_1 struct { // 5.1: Snippet SPDX Identifier: "SPDXRef-[idstring]" // Cardinality: mandatory, one - SnippetSPDXIdentifier ElementID + SnippetSPDXIdentifier ElementID `json:"SPDXID"` // 5.2: Snippet from File SPDX Identifier // Cardinality: mandatory, one - SnippetFromFileSPDXIdentifier DocElementID + SnippetFromFileSPDXIdentifier ElementID `json:"snippetFromFile"` - // 5.3: Snippet Byte Range: [start byte]:[end byte] - // Cardinality: mandatory, one - SnippetByteRangeStart int - SnippetByteRangeEnd int - - // 5.4: Snippet Line Range: [start line]:[end line] - // Cardinality: optional, one - SnippetLineRangeStart int - SnippetLineRangeEnd int + // Ranges denotes the start/end byte offsets or line numbers that the snippet is relevant to + Ranges []SnippetRange `json:"ranges"` // 5.5: Snippet Concluded License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - SnippetLicenseConcluded string + SnippetLicenseConcluded string `json:"licenseConcluded"` // 5.6: License Information in Snippet: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: optional, one or many - LicenseInfoInSnippet []string + LicenseInfoInSnippet []string `json:"licenseInfoInSnippets,omitempty"` // 5.7: Snippet Comments on License // Cardinality: optional, one - SnippetLicenseComments string + SnippetLicenseComments string `json:"licenseComments,omitempty"` // 5.8: Snippet Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - SnippetCopyrightText string + SnippetCopyrightText string `json:"copyrightText"` // 5.9: Snippet Comment // Cardinality: optional, one - SnippetComment string + SnippetComment string `json:"comment,omitempty"` // 5.10: Snippet Name // Cardinality: optional, one - SnippetName string + SnippetName string `json:"name,omitempty"` } // Snippet2_2 is a Snippet section of an SPDX Document for version 2.2 of the spec. @@ -53,47 +63,40 @@ type Snippet2_2 struct { // 5.1: Snippet SPDX Identifier: "SPDXRef-[idstring]" // Cardinality: mandatory, one - SnippetSPDXIdentifier ElementID + SnippetSPDXIdentifier ElementID `json:"SPDXID"` // 5.2: Snippet from File SPDX Identifier // Cardinality: mandatory, one - SnippetFromFileSPDXIdentifier DocElementID + SnippetFromFileSPDXIdentifier ElementID `json:"snippetFromFile"` - // 5.3: Snippet Byte Range: [start byte]:[end byte] - // Cardinality: mandatory, one - SnippetByteRangeStart int - SnippetByteRangeEnd int - - // 5.4: Snippet Line Range: [start line]:[end line] - // Cardinality: optional, one - SnippetLineRangeStart int - SnippetLineRangeEnd int + // Ranges denotes the start/end byte offsets or line numbers that the snippet is relevant to + Ranges []SnippetRange `json:"ranges"` // 5.5: Snippet Concluded License: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - SnippetLicenseConcluded string + SnippetLicenseConcluded string `json:"licenseConcluded"` // 5.6: License Information in Snippet: SPDX License Expression, "NONE" or "NOASSERTION" // Cardinality: optional, one or many - LicenseInfoInSnippet []string + LicenseInfoInSnippet []string `json:"licenseInfoInSnippets,omitempty"` // 5.7: Snippet Comments on License // Cardinality: optional, one - SnippetLicenseComments string + SnippetLicenseComments string `json:"licenseComments,omitempty"` // 5.8: Snippet Copyright Text: copyright notice(s) text, "NONE" or "NOASSERTION" // Cardinality: mandatory, one - SnippetCopyrightText string + SnippetCopyrightText string `json:"copyrightText"` // 5.9: Snippet Comment // Cardinality: optional, one - SnippetComment string + SnippetComment string `json:"comment,omitempty"` // 5.10: Snippet Name // Cardinality: optional, one - SnippetName string + SnippetName string `json:"name,omitempty"` // 5.11: Snippet Attribution Text // Cardinality: optional, one or many - SnippetAttributionTexts []string + SnippetAttributionTexts []string `json:"-"` } |