mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
remove spdx json presenter + model
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
8d522efcf6
commit
0c0890ef44
@ -1,21 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type AnnotationType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ReviewerAnnotationType AnnotationType = "REVIEWER"
|
|
||||||
OtherAnnotationType AnnotationType = "OTHER"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Annotation struct {
|
|
||||||
// Identify when the comment was made. This is to be specified according to the combined date and time in the
|
|
||||||
// UTC format, as specified in the ISO 8601 standard.
|
|
||||||
AnnotationDate time.Time `json:"annotationDate"`
|
|
||||||
// Type of the annotation
|
|
||||||
AnnotationType AnnotationType `json:"annotationType"`
|
|
||||||
// This field identifies the person, organization or tool that has commented on a file, package, or the entire document.
|
|
||||||
Annotator string `json:"annotator"`
|
|
||||||
Comment string `json:"comment"`
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type Checksum struct {
|
|
||||||
// Identifies the algorithm used to produce the subject Checksum. One of: "SHA256", "SHA1", "SHA384", "MD2", "MD4", "SHA512", "MD6", "MD5", "SHA224"
|
|
||||||
Algorithm string `json:"algorithm"`
|
|
||||||
ChecksumValue string `json:"checksumValue"`
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type CreationInfo struct {
|
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
// Identify when the SPDX file was originally created. The date is to be specified according to combined date and
|
|
||||||
// time in UTC format as specified in ISO 8601 standard. This field is distinct from the fields in section 8,
|
|
||||||
// which involves the addition of information during a subsequent review.
|
|
||||||
Created time.Time `json:"created"`
|
|
||||||
// Identify who (or what, in the case of a tool) created the SPDX file. If the SPDX file was created by an
|
|
||||||
// individual, indicate the person's name. If the SPDX file was created on behalf of a company or organization,
|
|
||||||
//indicate the entity name. If the SPDX file was created using a software tool, indicate the name and version
|
|
||||||
// for that tool. If multiple participants or tools were involved, use multiple instances of this field. Person
|
|
||||||
// name or organization name may be designated as “anonymous” if appropriate.
|
|
||||||
Creators []string `json:"creators"`
|
|
||||||
// An optional field for creators of the SPDX file to provide the version of the SPDX License List used when the SPDX file was created.
|
|
||||||
LicenseListVersion string `json:"licenseListVersion"`
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
// derived from:
|
|
||||||
// - https://spdx.github.io/spdx-spec/appendix-III-RDF-data-model-implementation-and-identifier-syntax/
|
|
||||||
// - https://github.com/spdx/spdx-spec/blob/v2.2/schemas/spdx-schema.json
|
|
||||||
// - https://github.com/spdx/spdx-spec/tree/v2.2/ontology
|
|
||||||
|
|
||||||
type Document struct {
|
|
||||||
Element
|
|
||||||
SPDXVersion string `json:"spdxVersion"`
|
|
||||||
// One instance is required for each SPDX file produced. It provides the necessary information for forward
|
|
||||||
// and backward compatibility for processing tools.
|
|
||||||
CreationInfo CreationInfo `json:"creationInfo"`
|
|
||||||
// 2.2: Data License; should be "CC0-1.0"
|
|
||||||
// Cardinality: mandatory, one
|
|
||||||
// License expression for dataLicense. Compliance with the SPDX specification includes populating the SPDX
|
|
||||||
// fields therein with data related to such fields (\"SPDX-Metadata\"). The SPDX specification contains numerous
|
|
||||||
// fields where an SPDX document creator may provide relevant explanatory text in SPDX-Metadata. Without
|
|
||||||
// opining on the lawfulness of \"database rights\" (in jurisdictions where applicable), such explanatory text
|
|
||||||
// is copyrightable subject matter in most Berne Convention countries. By using the SPDX specification, or any
|
|
||||||
// portion hereof, you hereby agree that any copyright rights (as determined by your jurisdiction) in any
|
|
||||||
// SPDX-Metadata, including without limitation explanatory text, shall be subject to the terms of the Creative
|
|
||||||
// Commons CC0 1.0 Universal license. For SPDX-Metadata not containing any copyright rights, you hereby agree
|
|
||||||
// and acknowledge that the SPDX-Metadata is provided to you \"as-is\" and without any representations or
|
|
||||||
// warranties of any kind concerning the SPDX-Metadata, express, implied, statutory or otherwise, including
|
|
||||||
// without limitation warranties of title, merchantability, fitness for a particular purpose, non-infringement,
|
|
||||||
// or the absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not
|
|
||||||
// discoverable, all to the greatest extent permissible under applicable law.
|
|
||||||
DataLicense string `json:"dataLicense"`
|
|
||||||
// Information about an external SPDX document reference including the checksum. This allows for verification of the external references.
|
|
||||||
ExternalDocumentRefs []ExternalDocumentRef `json:"externalDocumentRefs,omitempty"`
|
|
||||||
// Indicates that a particular ExtractedLicensingInfo was defined in the subject SpdxDocument.
|
|
||||||
HasExtractedLicensingInfos []HasExtractedLicensingInfo `json:"hasExtractedLicensingInfos,omitempty"`
|
|
||||||
// note: found in example documents from SPDX, but not in the JSON schema. See https://spdx.github.io/spdx-spec/2-document-creation-information/#25-spdx-document-namespace
|
|
||||||
DocumentNamespace string `json:"documentNamespace"`
|
|
||||||
// note: found in example documents from SPDX, but not in the JSON schema
|
|
||||||
// DocumentDescribes []string `json:"documentDescribes"`
|
|
||||||
Packages []Package `json:"packages"`
|
|
||||||
// Files referenced in the SPDX document
|
|
||||||
Files []File `json:"files,omitempty"`
|
|
||||||
// Snippets referenced in the SPDX document
|
|
||||||
Snippets []Snippet `json:"snippets,omitempty"`
|
|
||||||
// Relationships referenced in the SPDX document
|
|
||||||
Relationships []Relationship `json:"relationships,omitempty"`
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type Element struct {
|
|
||||||
SPDXID string `json:"SPDXID"`
|
|
||||||
// Identify name of this SpdxElement.
|
|
||||||
Name string `json:"name"`
|
|
||||||
// Relationships referenced in the SPDX document
|
|
||||||
Relationships []Relationship `json:"relationships,omitempty"`
|
|
||||||
// Provide additional information about an SpdxElement.
|
|
||||||
Annotations []Annotation `json:"annotations,omitempty"`
|
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
func (e ElementID) String() string {
|
|
||||||
return "SPDXRef-" + string(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DocElementID represents an SPDX element identifier that could be defined
|
|
||||||
// in a different SPDX document, and therefore could have a "DocumentRef-"
|
|
||||||
// portion, such as Relationship 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.
|
|
||||||
type DocElementID struct {
|
|
||||||
DocumentRefID string
|
|
||||||
ElementRefID ElementID
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenderDocElementID takes a DocElementID and returns the string equivalent,
|
|
||||||
// with the SPDXRef- prefix (and, if applicable, the DocumentRef- prefix)
|
|
||||||
// reinserted.
|
|
||||||
func (d DocElementID) String() string {
|
|
||||||
prefix := ""
|
|
||||||
if d.DocumentRefID != "" {
|
|
||||||
prefix = "DocumentRef-" + d.DocumentRefID + ":"
|
|
||||||
}
|
|
||||||
return prefix + d.ElementRefID.String()
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type ExternalDocumentRef struct {
|
|
||||||
// externalDocumentId is a string containing letters, numbers, ., - and/or + which uniquely identifies an external document within this document.
|
|
||||||
ExternalDocumentID string `json:"externalDocumentId"`
|
|
||||||
Checksum Checksum `json:"checksum"`
|
|
||||||
// SPDX ID for SpdxDocument. A propoerty containing an SPDX document.
|
|
||||||
SpdxDocument string `json:"spdxDocument"`
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type ReferenceCategory string
|
|
||||||
|
|
||||||
const (
|
|
||||||
SecurityReferenceCategory ReferenceCategory = "SECURITY"
|
|
||||||
PackageManagerReferenceCategory ReferenceCategory = "PACKAGE_MANAGER"
|
|
||||||
OtherReferenceCategory ReferenceCategory = "OTHER"
|
|
||||||
)
|
|
||||||
|
|
||||||
// source: https://spdx.github.io/spdx-spec/appendix-VI-external-repository-identifiers/
|
|
||||||
|
|
||||||
type ExternalRefType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// see https://nvd.nist.gov/cpe
|
|
||||||
Cpe22ExternalRefType ExternalRefType = "cpe22Type"
|
|
||||||
// see https://nvd.nist.gov/cpe
|
|
||||||
Cpe23ExternalRefType ExternalRefType = "cpe23Type"
|
|
||||||
// see http://repo1.maven.org/maven2/
|
|
||||||
MavenCentralExternalRefType ExternalRefType = "maven-central"
|
|
||||||
// see https://www.npmjs.com/
|
|
||||||
NpmExternalRefType ExternalRefType = "npm"
|
|
||||||
// see https://www.nuget.org/
|
|
||||||
NugetExternalRefType ExternalRefType = "nuget"
|
|
||||||
// see http://bower.io/
|
|
||||||
BowerExternalRefType ExternalRefType = "bower"
|
|
||||||
// see https://github.com/package-url/purl-spec
|
|
||||||
PurlExternalRefType ExternalRefType = "purl"
|
|
||||||
// These point to objects present in the Software Heritage archive by the means of SoftWare Heritage persistent Identifiers (SWHID)
|
|
||||||
SwhExternalRefType ExternalRefType = "swh"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ExternalRef struct {
|
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
// Category for the external reference.
|
|
||||||
ReferenceCategory ReferenceCategory `json:"referenceCategory"`
|
|
||||||
// The unique string with no spaces necessary to access the package-specific information, metadata, or content
|
|
||||||
// within the target location. The format of the locator is subject to constraints defined by the <type>.
|
|
||||||
ReferenceLocator string `json:"referenceLocator"`
|
|
||||||
// Type of the external reference. These are defined in an appendix in the SPDX specification.
|
|
||||||
ReferenceType ExternalRefType `json:"referenceType"`
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type FileType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
DocumentationFileType FileType = "DOCUMENTATION"
|
|
||||||
ImageFileType FileType = "IMAGE"
|
|
||||||
VideoFileType FileType = "VIDEO"
|
|
||||||
ArchiveFileType FileType = "ARCHIVE"
|
|
||||||
SpdxFileType FileType = "SPDX"
|
|
||||||
ApplicationFileType FileType = "APPLICATION"
|
|
||||||
SourceFileType FileType = "SOURCE"
|
|
||||||
BinaryFileType FileType = "BINARY"
|
|
||||||
TextFileType FileType = "TEXT"
|
|
||||||
AudioFileType FileType = "AUDIO"
|
|
||||||
OtherFileType FileType = "OTHER"
|
|
||||||
)
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
Item
|
|
||||||
// (At least one is required.) The checksum property provides a mechanism that can be used to verify that the
|
|
||||||
// contents of a File or Package have not changed.
|
|
||||||
Checksums []Checksum `json:"checksums,omitempty"`
|
|
||||||
// This field provides a place for the SPDX file creator to record file contributors. Contributors could include
|
|
||||||
// names of copyright holders and/or authors who may not be copyright holders yet contributed to the file content.
|
|
||||||
FileContributors []string `json:"fileContributors,omitempty"`
|
|
||||||
// Each element is a SPDX ID for a File.
|
|
||||||
FileDependencies []string `json:"fileDependencies,omitempty"`
|
|
||||||
// The name of the file relative to the root of the package.
|
|
||||||
FileName string `json:"fileName"`
|
|
||||||
// The type of the file
|
|
||||||
FileTypes []string `json:"fileTypes,omitempty"`
|
|
||||||
// This field provides a place for the SPDX file creator to record potential legal notices found in the file.
|
|
||||||
// This may or may not include copyright statements.
|
|
||||||
NoticeText string `json:"noticeText,omitempty"`
|
|
||||||
// Indicates the project in which the SpdxElement originated. Tools must preserve doap:homepage and doap:name
|
|
||||||
// properties and the URI (if one is known) of doap:Project resources that are values of this property. All other
|
|
||||||
// properties of doap:Projects are not directly supported by SPDX and may be dropped when translating to or
|
|
||||||
// from some SPDX formats(deprecated).
|
|
||||||
ArtifactOf []string `json:"artifactOf,omitempty"`
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type HasExtractedLicensingInfo struct {
|
|
||||||
// Verbatim license or licensing notice text that was discovered.
|
|
||||||
ExtractedText string `json:"extractedText"`
|
|
||||||
// A human readable short form license identifier for a license. The license ID is iether on the standard license
|
|
||||||
// oist or the form \"LicenseRef-\"[idString] where [idString] is a unique string containing letters,
|
|
||||||
// numbers, \".\", \"-\" or \"+\".
|
|
||||||
LicenseID string `json:"licenseId"`
|
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
// Identify name of this SpdxElement.
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
SeeAlsos []string `json:"seeAlsos,omitempty"`
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type Item struct {
|
|
||||||
Element
|
|
||||||
// The licenseComments property allows the preparer of the SPDX document to describe why the licensing in
|
|
||||||
// spdx:licenseConcluded was chosen.
|
|
||||||
LicenseComments string `json:"licenseComments,omitempty"`
|
|
||||||
LicenseConcluded string `json:"licenseConcluded"`
|
|
||||||
// The licensing information that was discovered directly within the package. There will be an instance of this
|
|
||||||
// property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.
|
|
||||||
LicenseInfoFromFiles []string `json:"licenseInfoFromFiles,omitempty"`
|
|
||||||
// Licensing information that was discovered directly in the subject file. This is also considered a declared license for the file.
|
|
||||||
LicenseInfoInFiles []string `json:"licenseInfoInFiles,omitempty"`
|
|
||||||
// The text of copyright declarations recited in the Package or File.
|
|
||||||
CopyrightText string `json:"copyrightText,omitempty"`
|
|
||||||
// This field provides a place for the SPDX data creator to record acknowledgements that may be required to be
|
|
||||||
// communicated in some contexts. This is not meant to include the actual complete license text (see
|
|
||||||
// licenseConculded and licenseDeclared), and may or may not include copyright notices (see also copyrightText).
|
|
||||||
// The SPDX data creator may use this field to record other acknowledgements, such as particular clauses from
|
|
||||||
// license texts, which may be necessary or desirable to reproduce.
|
|
||||||
AttributionTexts []string `json:"attributionTexts,omitempty"`
|
|
||||||
}
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type Package struct {
|
|
||||||
Item
|
|
||||||
// The checksum property provides a mechanism that can be used to verify that the contents of a File or
|
|
||||||
// Package have not changed.
|
|
||||||
Checksums []Checksum `json:"checksums,omitempty"`
|
|
||||||
// Provides a detailed description of the package.
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
// The URI at which this package is available for download. Private (i.e., not publicly reachable) URIs are
|
|
||||||
// acceptable as values of this property. The values http://spdx.org/rdf/terms#none and http://spdx.org/rdf/terms#noassertion
|
|
||||||
// may be used to specify that the package is not downloadable or that no attempt was made to determine its
|
|
||||||
// download location, respectively.
|
|
||||||
DownloadLocation string `json:"downloadLocation,omitempty"`
|
|
||||||
// An External Reference allows a Package to reference an external source of additional information, metadata,
|
|
||||||
// enumerations, asset identifiers, or downloadable content believed to be relevant to the Package.
|
|
||||||
ExternalRefs []ExternalRef `json:"externalRefs,omitempty"`
|
|
||||||
// Indicates whether the file content of this package has been available for or subjected to analysis when
|
|
||||||
// creating the SPDX document. If false indicates packages that represent metadata or URI references to a
|
|
||||||
// project, product, artifact, distribution or a component. If set to false, the package must not contain any files
|
|
||||||
FilesAnalyzed bool `json:"filesAnalyzed"`
|
|
||||||
// Indicates that a particular file belongs to a package (elements are SPDX ID for a File).
|
|
||||||
HasFiles []string `json:"hasFiles,omitempty"`
|
|
||||||
// Provide a place for the SPDX file creator to record a web site that serves as the package's home page.
|
|
||||||
// This link can also be used to reference further information about the package referenced by the SPDX file creator.
|
|
||||||
Homepage string `json:"homepage,omitempty"`
|
|
||||||
// List the licenses that have been declared by the authors of the package. Any license information that does not
|
|
||||||
// originate from the package authors, e.g. license information from a third party repository, should not be included in this field.
|
|
||||||
LicenseDeclared string `json:"licenseDeclared"`
|
|
||||||
// The name and, optionally, contact information of the person or organization that originally created the package.
|
|
||||||
// Values of this property must conform to the agent and tool syntax.
|
|
||||||
Originator string `json:"originator,omitempty"`
|
|
||||||
// The base name of the package file name. For example, zlib-1.2.5.tar.gz.
|
|
||||||
PackageFileName string `json:"packageFileName,omitempty"`
|
|
||||||
// A manifest based verification code (the algorithm is defined in section 4.7 of the full specification) of the
|
|
||||||
// SPDX Item. This allows consumers of this data and/or database to determine if an SPDX item they have in hand
|
|
||||||
// is identical to the SPDX item from which the data was produced. This algorithm works even if the SPDX document
|
|
||||||
// is included in the SPDX item.
|
|
||||||
PackageVerificationCode *PackageVerificationCode `json:"packageVerificationCode,omitempty"`
|
|
||||||
// Allows the producer(s) of the SPDX document to describe how the package was acquired and/or changed from the original source.
|
|
||||||
SourceInfo string `json:"sourceInfo,omitempty"`
|
|
||||||
// Provides a short description of the package.
|
|
||||||
Summary string `json:"summary,omitempty"`
|
|
||||||
// The name and, optionally, contact information of the person or organization who was the immediate supplier
|
|
||||||
// of this package to the recipient. The supplier may be different than originator when the software has been
|
|
||||||
// repackaged. Values of this property must conform to the agent and tool syntax.
|
|
||||||
Supplier string `json:"supplier,omitempty"`
|
|
||||||
// Provides an indication of the version of the package that is described by this SpdxDocument.
|
|
||||||
VersionInfo string `json:"versionInfo,omitempty"`
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
// Why are there two package identifier fields Package Checksum and Package Verification?
|
|
||||||
// Although the values of the two fields Package Checksum and Package Verification are similar, they each serve a
|
|
||||||
// different purpose. The Package Checksum provides a unique identifier of a software package which is computed by
|
|
||||||
// taking the SHA1 of the entire software package file. This enables one to quickly determine if two different copies
|
|
||||||
// of a package are the same. One disadvantage of this approach is that one cannot add an SPDX data file into the
|
|
||||||
// original package without changing the Package Checksum value. Alternatively, the Package Verification field enables
|
|
||||||
// the inclusion of an SPDX file. It enables one to quickly verify if one or more of the original package files has
|
|
||||||
// changed. The Package Verification field is a unique identifier that is based on SHAing only the original package
|
|
||||||
// files (e.g., excluding the SPDX file). This allows one to add an SPDX file to the original package without changing
|
|
||||||
// this unique identifier.
|
|
||||||
// source: https://wiki.spdx.org/view/SPDX_FAQ
|
|
||||||
type PackageVerificationCode struct {
|
|
||||||
// "A file that was excluded when calculating the package verification code. This is usually a file containing
|
|
||||||
// SPDX data regarding the package. If a package contains more than one SPDX file all SPDX files must be excluded
|
|
||||||
// from the package verification code. If this is not done it would be impossible to correctly calculate the
|
|
||||||
// verification codes in both files.
|
|
||||||
PackageVerificationCodeExcludedFiles []string `json:"packageVerificationCodeExcludedFiles"`
|
|
||||||
|
|
||||||
// The actual package verification code as a hex encoded value.
|
|
||||||
PackageVerificationCodeValue string `json:"packageVerificationCodeValue"`
|
|
||||||
}
|
|
||||||
@ -1,183 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type Relationship struct {
|
|
||||||
// Id to which the SPDX element is related
|
|
||||||
SpdxElementID string `json:"spdxElementId"`
|
|
||||||
// Describes the type of relationship between two SPDX elements.
|
|
||||||
RelationshipType RelationshipType `json:"relationshipType"`
|
|
||||||
// SPDX ID for SpdxElement. A related SpdxElement.
|
|
||||||
RelatedSpdxElement string `json:"relatedSpdxElement"`
|
|
||||||
Comment string `json:"comment,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// source: https://spdx.github.io/spdx-spec/7-relationships-between-SPDX-elements/
|
|
||||||
type RelationshipType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DescribedByRelationship is to be used when SPDXRef-A is described by SPDXREF-Document.
|
|
||||||
// Example: The package 'WildFly' is described by SPDX document WildFly.spdx.
|
|
||||||
DescribedByRelationship RelationshipType = "DESCRIBED_BY"
|
|
||||||
|
|
||||||
// ContainsRelationship is to be used when SPDXRef-A contains SPDXRef-B.
|
|
||||||
// Example: An ARCHIVE file bar.tgz contains a SOURCE file foo.c.
|
|
||||||
ContainsRelationship RelationshipType = "CONTAINS"
|
|
||||||
|
|
||||||
// ContainedByRelationship is to be used when SPDXRef-A is contained by SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.c is contained by ARCHIVE file bar.tgz
|
|
||||||
ContainedByRelationship RelationshipType = "CONTAINED_BY"
|
|
||||||
|
|
||||||
// DependsOnRelationship is to be used when SPDXRef-A depends on SPDXRef-B.
|
|
||||||
// Example: Package A depends on the presence of package B in order to build and run
|
|
||||||
DependsOnRelationship RelationshipType = "DEPENDS_ON"
|
|
||||||
|
|
||||||
// DependencyOfRelationship is to be used when SPDXRef-A is dependency of SPDXRef-B.
|
|
||||||
// Example: A is explicitly stated as a dependency of B in a machine-readable file. Use when a package manager does not define scopes.
|
|
||||||
DependencyOfRelationship RelationshipType = "DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// DependencyManifestOfRelationship is to be used when SPDXRef-A is a manifest file that lists a set of dependencies for SPDXRef-B.
|
|
||||||
// Example: A file package.json is the dependency manifest of a package foo. Note that only one manifest should be used to define the same dependency graph.
|
|
||||||
DependencyManifestOfRelationship RelationshipType = "DEPENDENCY_MANIFEST_OF"
|
|
||||||
|
|
||||||
// BuildDependencyOfRelationship is to be used when SPDXRef-A is a build dependency of SPDXRef-B.
|
|
||||||
// Example: A is in the compile scope of B in a Maven project.
|
|
||||||
BuildDependencyOfRelationship RelationshipType = "BUILD_DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// DevDependencyOfRelationship is to be used when SPDXRef-A is a development dependency of SPDXRef-B.
|
|
||||||
// Example: A is in the devDependencies scope of B in a Maven project.
|
|
||||||
DevDependencyOfRelationship RelationshipType = "DEV_DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// OptionalDependencyOfRelationship is to be used when SPDXRef-A is an optional dependency of SPDXRef-B.
|
|
||||||
// Example: Use when building the code will proceed even if a dependency cannot be found, fails to install, or is only installed on a specific platform. For example, A is in the optionalDependencies scope of npm project B.
|
|
||||||
OptionalDependencyOfRelationship RelationshipType = "OPTIONAL_DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// ProvidedDependencyOfRelationship is to be used when SPDXRef-A is a to be provided dependency of SPDXRef-B.
|
|
||||||
// Example: A is in the provided scope of B in a Maven project, indicating that the project expects it to be provided, for instance, by the container or JDK.
|
|
||||||
ProvidedDependencyOfRelationship RelationshipType = "PROVIDED_DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// TestDependencyOfRelationship is to be used when SPDXRef-A is a test dependency of SPDXRef-B.
|
|
||||||
// Example: A is in the test scope of B in a Maven project.
|
|
||||||
TestDependencyOfRelationship RelationshipType = "TEST_DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// RuntimeDependencyOfRelationship is to be used when SPDXRef-A is a dependency required for the execution of SPDXRef-B.
|
|
||||||
// Example: A is in the runtime scope of B in a Maven project.
|
|
||||||
RuntimeDependencyOfRelationship RelationshipType = "RUNTIME_DEPENDENCY_OF"
|
|
||||||
|
|
||||||
// ExampleOfRelationship is to be used when SPDXRef-A is an example of SPDXRef-B.
|
|
||||||
// Example: The file or snippet that illustrates how to use an application or library.
|
|
||||||
ExampleOfRelationship RelationshipType = "EXAMPLE_OF"
|
|
||||||
|
|
||||||
// GeneratesRelationship is to be used when SPDXRef-A generates SPDXRef-B.
|
|
||||||
// Example: A SOURCE file makefile.mk generates a BINARY file a.out
|
|
||||||
GeneratesRelationship RelationshipType = "GENERATES"
|
|
||||||
|
|
||||||
// GeneratedFromRelationship is to be used when SPDXRef-A was generated from SPDXRef-B.
|
|
||||||
// Example: A BINARY file a.out has been generated from a SOURCE file makefile.mk. A BINARY file foolib.a is generated from a SOURCE file bar.c.
|
|
||||||
GeneratedFromRelationship RelationshipType = "GENERATED_FROM"
|
|
||||||
|
|
||||||
// AncestorOfRelationship is to be used when SPDXRef-A is an ancestor (same lineage but pre-dates) SPDXRef-B.
|
|
||||||
// Example: A SOURCE file makefile.mk is a version of the original ancestor SOURCE file 'makefile2.mk'
|
|
||||||
AncestorOfRelationship RelationshipType = "ANCESTOR_OF"
|
|
||||||
|
|
||||||
// DescendantOfRelationship is to be used when SPDXRef-A is a descendant of (same lineage but postdates) SPDXRef-B.
|
|
||||||
// Example: A SOURCE file makefile2.mk is a descendant of the original SOURCE file 'makefile.mk'
|
|
||||||
DescendantOfRelationship RelationshipType = "DESCENDANT_OF"
|
|
||||||
|
|
||||||
// VariantOfRelationship is to be used when SPDXRef-A is a variant of (same lineage but not clear which came first) SPDXRef-B.
|
|
||||||
// Example: A SOURCE file makefile2.mk is a variant of SOURCE file makefile.mk if they differ by some edit, but there is no way to tell which came first (no reliable date information).
|
|
||||||
VariantOfRelationship RelationshipType = "VARIANT_OF"
|
|
||||||
|
|
||||||
// DistributionArtifactRelationship is to be used when distributing SPDXRef-A requires that SPDXRef-B also be distributed.
|
|
||||||
// Example: A BINARY file foo.o requires that the ARCHIVE file bar-sources.tgz be made available on distribution.
|
|
||||||
DistributionArtifactRelationship RelationshipType = "DISTRIBUTION_ARTIFACT"
|
|
||||||
|
|
||||||
// PatchForRelationship is to be used when SPDXRef-A is a patch file for (to be applied to) SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.diff is a patch file for SOURCE file foo.c.
|
|
||||||
PatchForRelationship RelationshipType = "PATCH_FOR"
|
|
||||||
|
|
||||||
// PatchAppliedRelationship is to be used when SPDXRef-A is a patch file that has been applied to SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.diff is a patch file that has been applied to SOURCE file 'foo-patched.c'.
|
|
||||||
PatchAppliedRelationship RelationshipType = "PATCH_APPLIED"
|
|
||||||
|
|
||||||
// CopyOfRelationship is to be used when SPDXRef-A is an exact copy of SPDXRef-B.
|
|
||||||
// Example: A BINARY file alib.a is an exact copy of BINARY file a2lib.a.
|
|
||||||
CopyOfRelationship RelationshipType = "COPY_OF"
|
|
||||||
|
|
||||||
// FileAddedRelationship is to be used when SPDXRef-A is a file that was added to SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.c has been added to package ARCHIVE bar.tgz.
|
|
||||||
FileAddedRelationship RelationshipType = "FILE_ADDED"
|
|
||||||
|
|
||||||
// FileDeletedRelationship is to be used when SPDXRef-A is a file that was deleted from SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.diff has been deleted from package ARCHIVE bar.tgz.
|
|
||||||
FileDeletedRelationship RelationshipType = "FILE_DELETED"
|
|
||||||
|
|
||||||
// FileModifiedRelationship is to be used when SPDXRef-A is a file that was modified from SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.c has been modified from SOURCE file foo.orig.c.
|
|
||||||
FileModifiedRelationship RelationshipType = "FILE_MODIFIED"
|
|
||||||
|
|
||||||
// ExpandedFromArchiveRelationship is to be used when SPDXRef-A is expanded from the archive SPDXRef-B.
|
|
||||||
// Example: A SOURCE file foo.c, has been expanded from the archive ARCHIVE file xyz.tgz.
|
|
||||||
ExpandedFromArchiveRelationship RelationshipType = "EXPANDED_FROM_ARCHIVE"
|
|
||||||
|
|
||||||
// DynamicLinkRelationship is to be used when SPDXRef-A dynamically links to SPDXRef-B.
|
|
||||||
// Example: An APPLICATION file 'myapp' dynamically links to BINARY file zlib.so.
|
|
||||||
DynamicLinkRelationship RelationshipType = "DYNAMIC_LINK"
|
|
||||||
|
|
||||||
// StaticLinkRelationship is to be used when SPDXRef-A statically links to SPDXRef-B.
|
|
||||||
// Example: An APPLICATION file 'myapp' statically links to BINARY zlib.a.
|
|
||||||
StaticLinkRelationship RelationshipType = "STATIC_LINK"
|
|
||||||
|
|
||||||
// DataFileOfRelationship is to be used when SPDXRef-A is a data file used in SPDXRef-B.
|
|
||||||
// Example: An IMAGE file 'kitty.jpg' is a data file of an APPLICATION 'hellokitty'.
|
|
||||||
DataFileOfRelationship RelationshipType = "DATA_FILE_OF"
|
|
||||||
|
|
||||||
// TestCaseOfRelationship is to be used when SPDXRef-A is a test case used in testing SPDXRef-B.
|
|
||||||
// Example: A SOURCE file testMyCode.java is a unit test file used to test an APPLICATION MyPackage.
|
|
||||||
TestCaseOfRelationship RelationshipType = "TEST_CASE_OF"
|
|
||||||
|
|
||||||
// BuildToolOfRelationship is to be used when SPDXRef-A is used to build SPDXRef-B.
|
|
||||||
// Example: A SOURCE file makefile.mk is used to build an APPLICATION 'zlib'.
|
|
||||||
BuildToolOfRelationship RelationshipType = "BUILD_TOOL_OF"
|
|
||||||
|
|
||||||
// DevToolOfRelationship is to be used when SPDXRef-A is used as a development tool for SPDXRef-B.
|
|
||||||
// Example: Any tool used for development such as a code debugger.
|
|
||||||
DevToolOfRelationship RelationshipType = "DEV_TOOL_OF"
|
|
||||||
|
|
||||||
// TestOfRelationship is to be used when SPDXRef-A is used for testing SPDXRef-B.
|
|
||||||
// Example: Generic relationship for cases where it's clear that something is used for testing but unclear whether it's TEST_CASE_OF or TEST_TOOL_OF.
|
|
||||||
TestOfRelationship RelationshipType = "TEST_OF"
|
|
||||||
|
|
||||||
// TestToolOfRelationship is to be used when SPDXRef-A is used as a test tool for SPDXRef-B.
|
|
||||||
// Example: Any tool used to test the code such as ESlint.
|
|
||||||
TestToolOfRelationship RelationshipType = "TEST_TOOL_OF"
|
|
||||||
|
|
||||||
// DocumentationOfRelationship is to be used when SPDXRef-A provides documentation of SPDXRef-B.
|
|
||||||
// Example: A DOCUMENTATION file readme.txt documents the APPLICATION 'zlib'.
|
|
||||||
DocumentationOfRelationship RelationshipType = "DOCUMENTATION_OF"
|
|
||||||
|
|
||||||
// OptionalComponentOfRelationship is to be used when SPDXRef-A is an optional component of SPDXRef-B.
|
|
||||||
// Example: A SOURCE file fool.c (which is in the contributors directory) may or may not be included in the build of APPLICATION 'atthebar'.
|
|
||||||
OptionalComponentOfRelationship RelationshipType = "OPTIONAL_COMPONENT_OF"
|
|
||||||
|
|
||||||
// MetafileOfRelationship is to be used when SPDXRef-A is a metafile of SPDXRef-B.
|
|
||||||
// Example: A SOURCE file pom.xml is a metafile of the APPLICATION 'Apache Xerces'.
|
|
||||||
MetafileOfRelationship RelationshipType = "METAFILE_OF"
|
|
||||||
|
|
||||||
// PackageOfRelationship is to be used when SPDXRef-A is used as a package as part of SPDXRef-B.
|
|
||||||
// Example: A Linux distribution contains an APPLICATION package gawk as part of the distribution MyLinuxDistro.
|
|
||||||
PackageOfRelationship RelationshipType = "PACKAGE_OF"
|
|
||||||
|
|
||||||
// AmendsRelationship is to be used when (current) SPDXRef-DOCUMENT amends the SPDX information in SPDXRef-B.
|
|
||||||
// Example: (Current) SPDX document A version 2 contains a correction to a previous version of the SPDX document A version 1. Note the reserved identifier SPDXRef-DOCUMENT for the current document is required.
|
|
||||||
AmendsRelationship RelationshipType = "AMENDS"
|
|
||||||
|
|
||||||
// PrerequisiteForRelationship is to be used when SPDXRef-A is a prerequisite for SPDXRef-B.
|
|
||||||
// Example: A library bar.dll is a prerequisite or dependency for APPLICATION foo.exe
|
|
||||||
PrerequisiteForRelationship RelationshipType = "PREREQUISITE_FOR"
|
|
||||||
|
|
||||||
// HasPrerequisiteRelationship is to be used when SPDXRef-A has as a prerequisite SPDXRef-B.
|
|
||||||
// Example: An APPLICATION foo.exe has prerequisite or dependency on bar.dll
|
|
||||||
HasPrerequisiteRelationship RelationshipType = "HAS_PREREQUISITE"
|
|
||||||
|
|
||||||
// OtherRelationship is to be used for a relationship which has not been defined in the formal SPDX specification. A description of the relationship should be included in the Relationship comments field.
|
|
||||||
OtherRelationship RelationshipType = "OTHER"
|
|
||||||
)
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
type StartPointer struct {
|
|
||||||
Offset int `json:"offset,omitempty"`
|
|
||||||
LineNumber int `json:"lineNumber,omitempty"`
|
|
||||||
// SPDX ID for File
|
|
||||||
Reference string `json:"reference"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type EndPointer struct {
|
|
||||||
Offset int `json:"offset,omitempty"`
|
|
||||||
LineNumber int `json:"lineNumber,omitempty"`
|
|
||||||
// SPDX ID for File
|
|
||||||
Reference string `json:"reference"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Range struct {
|
|
||||||
StartPointer StartPointer `json:"startPointer"`
|
|
||||||
EndPointer EndPointer `json:"endPointer"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Snippet struct {
|
|
||||||
Item
|
|
||||||
// Licensing information that was discovered directly in the subject snippet. This is also considered a declared
|
|
||||||
// license for the snippet. (elements are license expressions)
|
|
||||||
LicenseInfoInSnippets []string `json:"licenseInfoInSnippets"`
|
|
||||||
// SPDX ID for File. File containing the SPDX element (e.g. the file contaning a snippet).
|
|
||||||
SnippetFromFile string `json:"snippetFromFile"`
|
|
||||||
// (At least 1 range is required). This field defines the byte range in the original host file (in X.2) that the
|
|
||||||
// snippet information applies to.
|
|
||||||
Ranges []Range `json:"ranges"`
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
package spdx22
|
|
||||||
|
|
||||||
const Version = "SPDX-2.2"
|
|
||||||
@ -1,207 +0,0 @@
|
|||||||
package packages
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/anchore/syft/internal/presenter/packages/model/spdx22"
|
|
||||||
"github.com/anchore/syft/internal/spdxlicense"
|
|
||||||
"github.com/anchore/syft/syft/pkg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getSPDXExternalRefs(p *pkg.Package) (externalRefs []spdx22.ExternalRef) {
|
|
||||||
externalRefs = make([]spdx22.ExternalRef, 0)
|
|
||||||
for _, c := range p.CPEs {
|
|
||||||
externalRefs = append(externalRefs, spdx22.ExternalRef{
|
|
||||||
ReferenceCategory: spdx22.SecurityReferenceCategory,
|
|
||||||
ReferenceLocator: c.BindToFmtString(),
|
|
||||||
ReferenceType: spdx22.Cpe23ExternalRefType,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.PURL != "" {
|
|
||||||
externalRefs = append(externalRefs, spdx22.ExternalRef{
|
|
||||||
ReferenceCategory: spdx22.PackageManagerReferenceCategory,
|
|
||||||
ReferenceLocator: p.PURL,
|
|
||||||
ReferenceType: spdx22.PurlExternalRefType,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return externalRefs
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXFiles(packageSpdxID string, p *pkg.Package) (files []spdx22.File, fileIDs []string, relationships []spdx22.Relationship) {
|
|
||||||
files = make([]spdx22.File, 0)
|
|
||||||
fileIDs = make([]string, 0)
|
|
||||||
relationships = make([]spdx22.Relationship, 0)
|
|
||||||
|
|
||||||
pkgFileOwner, ok := p.Metadata.(pkg.FileOwner)
|
|
||||||
if !ok {
|
|
||||||
return files, fileIDs, relationships
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ownedFilePath := range pkgFileOwner.OwnedFiles() {
|
|
||||||
baseFileName := filepath.Base(ownedFilePath)
|
|
||||||
pathHash := sha256.Sum256([]byte(ownedFilePath))
|
|
||||||
fileSpdxID := spdx22.ElementID(fmt.Sprintf("File-%s-%x", p.Name, pathHash)).String()
|
|
||||||
|
|
||||||
fileIDs = append(fileIDs, fileSpdxID)
|
|
||||||
|
|
||||||
files = append(files, spdx22.File{
|
|
||||||
FileName: ownedFilePath,
|
|
||||||
Item: spdx22.Item{
|
|
||||||
Element: spdx22.Element{
|
|
||||||
SPDXID: fileSpdxID,
|
|
||||||
Name: baseFileName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
relationships = append(relationships, spdx22.Relationship{
|
|
||||||
SpdxElementID: packageSpdxID,
|
|
||||||
RelationshipType: spdx22.ContainsRelationship,
|
|
||||||
RelatedSpdxElement: fileSpdxID,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return files, fileIDs, relationships
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXLicense(p *pkg.Package) string {
|
|
||||||
// source: https://spdx.github.io/spdx-spec/3-package-information/#313-concluded-license
|
|
||||||
// The options to populate this field are limited to:
|
|
||||||
// A valid SPDX License Expression as defined in Appendix IV;
|
|
||||||
// NONE, if the SPDX file creator concludes there is no license available for this package; or
|
|
||||||
// NOASSERTION if:
|
|
||||||
// (i) the SPDX file creator has attempted to but cannot reach a reasonable objective determination;
|
|
||||||
// (ii) the SPDX file creator has made no attempt to determine this field; or
|
|
||||||
// (iii) the SPDX file creator has intentionally provided no information (no meaning should be implied by doing so).
|
|
||||||
|
|
||||||
if len(p.Licenses) == 0 {
|
|
||||||
return "NONE"
|
|
||||||
}
|
|
||||||
|
|
||||||
// take all licenses and assume an AND expression; for information about license expressions see https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/
|
|
||||||
var parsedLicenses []string
|
|
||||||
for _, l := range p.Licenses {
|
|
||||||
if value, exists := spdxlicense.ID(l); exists {
|
|
||||||
parsedLicenses = append(parsedLicenses, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(parsedLicenses) == 0 {
|
|
||||||
return "NOASSERTION"
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(parsedLicenses, " AND ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func noneIfEmpty(value string) string {
|
|
||||||
if strings.TrimSpace(value) == "" {
|
|
||||||
return "NONE"
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXDownloadLocation(p *pkg.Package) string {
|
|
||||||
// 3.7: Package Download Location
|
|
||||||
// Cardinality: mandatory, one
|
|
||||||
// NONE if there is no download location whatsoever.
|
|
||||||
// NOASSERTION if:
|
|
||||||
// (i) the SPDX file creator has attempted to but cannot reach a reasonable objective determination;
|
|
||||||
// (ii) the SPDX file creator has made no attempt to determine this field; or
|
|
||||||
// (iii) the SPDX file creator has intentionally provided no information (no meaning should be implied by doing so).
|
|
||||||
|
|
||||||
switch metadata := p.Metadata.(type) {
|
|
||||||
case pkg.ApkMetadata:
|
|
||||||
return noneIfEmpty(metadata.URL)
|
|
||||||
case pkg.NpmPackageJSONMetadata:
|
|
||||||
return noneIfEmpty(metadata.URL)
|
|
||||||
default:
|
|
||||||
return "NOASSERTION"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXHomepage(p *pkg.Package) string {
|
|
||||||
switch metadata := p.Metadata.(type) {
|
|
||||||
case pkg.GemMetadata:
|
|
||||||
return metadata.Homepage
|
|
||||||
case pkg.NpmPackageJSONMetadata:
|
|
||||||
return metadata.Homepage
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXSourceInfo(p *pkg.Package) string {
|
|
||||||
answer := ""
|
|
||||||
switch p.Type {
|
|
||||||
case pkg.RpmPkg:
|
|
||||||
answer = "acquired package info from RPM DB"
|
|
||||||
case pkg.ApkPkg:
|
|
||||||
answer = "acquired package info from APK DB"
|
|
||||||
case pkg.DebPkg:
|
|
||||||
answer = "acquired package info from DPKG DB"
|
|
||||||
case pkg.NpmPkg:
|
|
||||||
answer = "acquired package info from installed node module manifest file"
|
|
||||||
case pkg.PythonPkg:
|
|
||||||
answer = "acquired package info from installed python package manifest file"
|
|
||||||
case pkg.JavaPkg, pkg.JenkinsPluginPkg:
|
|
||||||
answer = "acquired package info from installed java archive"
|
|
||||||
case pkg.GemPkg:
|
|
||||||
answer = "acquired package info from installed gem metadata file"
|
|
||||||
case pkg.GoModulePkg:
|
|
||||||
answer = "acquired package info from go module information"
|
|
||||||
case pkg.RustPkg:
|
|
||||||
answer = "acquired package info from rust cargo manifest"
|
|
||||||
default:
|
|
||||||
answer = "acquired package info from the following paths"
|
|
||||||
}
|
|
||||||
var paths []string
|
|
||||||
for _, l := range p.Locations {
|
|
||||||
paths = append(paths, l.RealPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return answer + ": " + strings.Join(paths, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXOriginator(p *pkg.Package) string {
|
|
||||||
switch metadata := p.Metadata.(type) {
|
|
||||||
case pkg.ApkMetadata:
|
|
||||||
return metadata.Maintainer
|
|
||||||
case pkg.NpmPackageJSONMetadata:
|
|
||||||
return metadata.Author
|
|
||||||
case pkg.PythonPackageMetadata:
|
|
||||||
author := metadata.Author
|
|
||||||
if author == "" {
|
|
||||||
return metadata.AuthorEmail
|
|
||||||
}
|
|
||||||
if metadata.AuthorEmail != "" {
|
|
||||||
author += fmt.Sprintf(" <%s>", metadata.AuthorEmail)
|
|
||||||
}
|
|
||||||
return author
|
|
||||||
case pkg.GemMetadata:
|
|
||||||
if len(metadata.Authors) > 0 {
|
|
||||||
return metadata.Authors[0]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
case pkg.RpmdbMetadata:
|
|
||||||
return metadata.Vendor
|
|
||||||
case pkg.DpkgMetadata:
|
|
||||||
return metadata.Maintainer
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSPDXDescription(p *pkg.Package) string {
|
|
||||||
switch metadata := p.Metadata.(type) {
|
|
||||||
case pkg.ApkMetadata:
|
|
||||||
return metadata.Description
|
|
||||||
case pkg.NpmPackageJSONMetadata:
|
|
||||||
return metadata.Description
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
package packages
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/anchore/syft/internal"
|
|
||||||
"github.com/anchore/syft/internal/presenter/packages/model/spdx22"
|
|
||||||
"github.com/anchore/syft/internal/spdxlicense"
|
|
||||||
"github.com/anchore/syft/internal/version"
|
|
||||||
"github.com/anchore/syft/syft/pkg"
|
|
||||||
"github.com/anchore/syft/syft/source"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
const anchoreNamespace = "https://anchore.com/syft"
|
|
||||||
|
|
||||||
// SPDXJsonPresenter is a SPDX presentation object for the syft results (see https://github.com/spdx/spdx-spec)
|
|
||||||
type SPDXJsonPresenter struct {
|
|
||||||
catalog *pkg.Catalog
|
|
||||||
srcMetadata source.Metadata
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSPDXJSONPresenter creates a new JSON presenter object for the given cataloging results.
|
|
||||||
func NewSPDXJSONPresenter(catalog *pkg.Catalog, srcMetadata source.Metadata) *SPDXJsonPresenter {
|
|
||||||
return &SPDXJsonPresenter{
|
|
||||||
catalog: catalog,
|
|
||||||
srcMetadata: srcMetadata,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Present the catalog results to the given writer.
|
|
||||||
func (pres *SPDXJsonPresenter) Present(output io.Writer) error {
|
|
||||||
doc := newSPDXJsonDocument(pres.catalog, pres.srcMetadata)
|
|
||||||
|
|
||||||
enc := json.NewEncoder(output)
|
|
||||||
// prevent > and < from being escaped in the payload
|
|
||||||
enc.SetEscapeHTML(false)
|
|
||||||
enc.SetIndent("", " ")
|
|
||||||
return enc.Encode(&doc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// newSPDXJsonDocument creates and populates a new JSON document struct that follows the SPDX 2.2 spec from the given cataloging results.
|
|
||||||
func newSPDXJsonDocument(catalog *pkg.Catalog, srcMetadata source.Metadata) spdx22.Document {
|
|
||||||
uniqueID := uuid.Must(uuid.NewRandom())
|
|
||||||
|
|
||||||
var name, input, identifier string
|
|
||||||
switch srcMetadata.Scheme {
|
|
||||||
case source.ImageScheme:
|
|
||||||
name = cleanSPDXName(srcMetadata.ImageMetadata.UserInput)
|
|
||||||
input = "image"
|
|
||||||
case source.DirectoryScheme:
|
|
||||||
name = cleanSPDXName(srcMetadata.Path)
|
|
||||||
input = "dir"
|
|
||||||
}
|
|
||||||
|
|
||||||
if name != "." {
|
|
||||||
identifier = path.Join(input, fmt.Sprintf("%s-%s", name, uniqueID.String()))
|
|
||||||
} else {
|
|
||||||
identifier = path.Join(input, uniqueID.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace := path.Join(anchoreNamespace, identifier)
|
|
||||||
packages, files, relationships := newSPDXJsonElements(catalog)
|
|
||||||
|
|
||||||
return spdx22.Document{
|
|
||||||
Element: spdx22.Element{
|
|
||||||
SPDXID: spdx22.ElementID("DOCUMENT").String(),
|
|
||||||
Name: name,
|
|
||||||
},
|
|
||||||
SPDXVersion: spdx22.Version,
|
|
||||||
CreationInfo: spdx22.CreationInfo{
|
|
||||||
Created: time.Now().UTC(),
|
|
||||||
Creators: []string{
|
|
||||||
// note: key-value format derived from the JSON example document examples: https://github.com/spdx/spdx-spec/blob/v2.2/examples/SPDXJSONExample-v2.2.spdx.json
|
|
||||||
"Organization: Anchore, Inc",
|
|
||||||
"Tool: " + internal.ApplicationName + "-" + version.FromBuild().Version,
|
|
||||||
},
|
|
||||||
LicenseListVersion: spdxlicense.Version,
|
|
||||||
},
|
|
||||||
DataLicense: "CC0-1.0",
|
|
||||||
DocumentNamespace: namespace,
|
|
||||||
Packages: packages,
|
|
||||||
Files: files,
|
|
||||||
Relationships: relationships,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSPDXJsonElements(catalog *pkg.Catalog) ([]spdx22.Package, []spdx22.File, []spdx22.Relationship) {
|
|
||||||
packages := make([]spdx22.Package, 0)
|
|
||||||
relationships := make([]spdx22.Relationship, 0)
|
|
||||||
files := make([]spdx22.File, 0)
|
|
||||||
|
|
||||||
for _, p := range catalog.Sorted() {
|
|
||||||
license := getSPDXLicense(p)
|
|
||||||
packageSpdxID := spdx22.ElementID(fmt.Sprintf("Package-%+v-%s-%s", p.Type, p.Name, p.Version)).String()
|
|
||||||
|
|
||||||
packageFiles, fileIDs, packageFileRelationships := getSPDXFiles(packageSpdxID, p)
|
|
||||||
files = append(files, packageFiles...)
|
|
||||||
|
|
||||||
relationships = append(relationships, packageFileRelationships...)
|
|
||||||
|
|
||||||
// note: the license concluded and declared should be the same since we are collecting license information
|
|
||||||
// from the project data itself (the installed package files).
|
|
||||||
packages = append(packages, spdx22.Package{
|
|
||||||
Description: getSPDXDescription(p),
|
|
||||||
DownloadLocation: getSPDXDownloadLocation(p),
|
|
||||||
ExternalRefs: getSPDXExternalRefs(p),
|
|
||||||
FilesAnalyzed: false,
|
|
||||||
HasFiles: fileIDs,
|
|
||||||
Homepage: getSPDXHomepage(p),
|
|
||||||
LicenseDeclared: license, // The Declared License is what the authors of a project believe govern the package
|
|
||||||
Originator: getSPDXOriginator(p),
|
|
||||||
SourceInfo: getSPDXSourceInfo(p),
|
|
||||||
VersionInfo: p.Version,
|
|
||||||
Item: spdx22.Item{
|
|
||||||
LicenseConcluded: license, // The Concluded License field is the license the SPDX file creator believes governs the package
|
|
||||||
Element: spdx22.Element{
|
|
||||||
SPDXID: packageSpdxID,
|
|
||||||
Name: p.Name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return packages, files, relationships
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanSPDXName(name string) string {
|
|
||||||
// remove # according to specification
|
|
||||||
name = strings.Replace(name, "#", "-", -1)
|
|
||||||
|
|
||||||
// remove : for url construction
|
|
||||||
name = strings.Replace(name, ":", "-", -1)
|
|
||||||
|
|
||||||
// clean relative pathing
|
|
||||||
return path.Clean(name)
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package packages
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"regexp"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
var updateSpdxJson = flag.Bool("update-spdx-json", false, "update the *.golden files for spdx-json presenters")
|
|
||||||
|
|
||||||
func TestSPDXJSONDirectoryPresenter(t *testing.T) {
|
|
||||||
catalog, metadata, _ := presenterDirectoryInput(t)
|
|
||||||
assertPresenterAgainstGoldenSnapshot(t,
|
|
||||||
NewSPDXJSONPresenter(catalog, metadata),
|
|
||||||
*updateSpdxJson,
|
|
||||||
spdxJsonRedactor,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSPDXJSONImagePresenter(t *testing.T) {
|
|
||||||
testImage := "image-simple"
|
|
||||||
catalog, metadata, _ := presenterImageInput(t, testImage)
|
|
||||||
assertPresenterAgainstGoldenImageSnapshot(t,
|
|
||||||
NewSPDXJSONPresenter(catalog, metadata),
|
|
||||||
testImage,
|
|
||||||
*updateSpdxJson,
|
|
||||||
spdxJsonRedactor,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func spdxJsonRedactor(s []byte) []byte {
|
|
||||||
// each SBOM reports the time it was generated, which is not useful during snapshot testing
|
|
||||||
s = regexp.MustCompile(`"created": .*`).ReplaceAll(s, []byte("redacted"))
|
|
||||||
|
|
||||||
// each SBOM reports a unique documentNamespace when generated, this is not useful for snapshot testing
|
|
||||||
s = regexp.MustCompile(`"documentNamespace": .*`).ReplaceAll(s, []byte("redacted"))
|
|
||||||
|
|
||||||
// the license list will be updated periodically, the value here should not be directly tested in snapshot tests
|
|
||||||
return regexp.MustCompile(`"licenseListVersion": .*`).ReplaceAll(s, []byte("redacted"))
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user