diff options
Diffstat (limited to 'spdx/package.go')
-rw-r--r-- | spdx/package.go | 246 |
1 files changed, 161 insertions, 85 deletions
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"` } |