-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade the 'Document' class to the SPDX 2.1 specification #71
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,78 @@ | |
from spdx import config | ||
|
||
|
||
@total_ordering | ||
class ExternalDocumentRef(object): | ||
""" | ||
External Document References entity that contains the following fields : | ||
- external_document_id: A unique string containing letters, numbers, '.', | ||
'-' or '+'. | ||
- spdx_document_uri: The unique ID of the SPDX document being referenced. | ||
- check_sum: The checksum of the referenced SPDX document. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why check_sum instead of checksum? |
||
""" | ||
|
||
def __init__(self, external_document_id=None, spdx_document_uri=None, | ||
check_sum=None): | ||
self.external_document_id = external_document_id | ||
self.spdx_document_uri = spdx_document_uri | ||
self.check_sum = check_sum | ||
|
||
def __eq__(self, other): | ||
return ( | ||
isinstance(other, ExternalDocumentRef) | ||
and self.external_document_id == other.external_document_id | ||
and self.spdx_document_uri == other.spdx_document_uri | ||
and self.check_sum == other.check_sum | ||
) | ||
|
||
def __lt__(self, other): | ||
return ( | ||
(self.external_document_id, self.spdx_document_uri, | ||
self.check_sum) < | ||
(other.external_document_id, other.spdx_document_uri, | ||
other.check_sum,) | ||
) | ||
|
||
def validate(self, messages=None): | ||
""" | ||
Validate all fields of the ExternalDocumentRef class and update the | ||
messages list with user friendly error messages for display. | ||
""" | ||
messages = messages if messages is not None else [] | ||
|
||
return (self.validate_ext_doc_id(messages) and | ||
self.validate_spdx_doc_uri(messages) and | ||
self.validate_chksum(messages) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. being consistent would be nice: use checksum everywhere? |
||
) | ||
|
||
def validate_ext_doc_id(self, messages=None): | ||
messages = messages if messages is not None else [] | ||
|
||
if self.external_document_id: | ||
return True | ||
else: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This else is not needed.... but this is minor. |
||
messages.append('ExternalDocumentRef has no External Document ID.') | ||
return False | ||
|
||
def validate_spdx_doc_uri(self, messages=None): | ||
messages = messages if messages is not None else [] | ||
|
||
if self.spdx_document_uri: | ||
return True | ||
else: | ||
messages.append('ExternalDocumentRef has no SPDX Document URI.') | ||
return False | ||
|
||
def validate_chksum(self, messages=None): | ||
messages = messages if messages is not None else [] | ||
|
||
if self.check_sum: | ||
return True | ||
else: | ||
messages.append('ExternalDocumentRef has no Checksum.') | ||
return False | ||
|
||
|
||
def _add_parens(required, text): | ||
""" | ||
Add parens around a license expression if `required` is True, otherwise | ||
|
@@ -189,7 +261,13 @@ class Document(object): | |
Represent an SPDX document with these fields: | ||
- version: Spec version. Mandatory, one - Type: Version. | ||
- data_license: SPDX-Metadata license. Mandatory, one. Type: License. | ||
- name: Name of the document. Mandatory, one. Type: str. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need to make this mandatory? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had referred to https://spdx.org/sites/cpstandard/files/pages/files/spdxversion2.1.pdf#page=11 where the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leave as is. |
||
- spdx_id: SPDX Identifier for the document to refer to itself in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need to make this mandatory too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had referred to https://spdx.org/sites/cpstandard/files/pages/files/spdxversion2.1.pdf#page=10 where the |
||
relationship to other elements. Mandatory, one. Type: str. | ||
- ext_document_references: External SPDX documents referenced within the | ||
given SPDX document. Optional, one or many. Type: ExternalDocumentRef | ||
- comment: Comments on the SPDX file, optional one. Type: str | ||
- namespace: SPDX document specific namespace. Mandatory, one. Type: str | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need to make this mandatory again? Note that your doc does not seem to be what happens: this does not seem mandatory in the code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
has been defined which will throw an error if the namespace is not defined :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's ok for now |
||
- creation_info: SPDX file creation info. Mandatory, one. Type: CreationInfo | ||
- package: Package described by this document. Mandatory, one. Type: Package | ||
- extracted_licenses: List of licenses extracted that are not part of the | ||
|
@@ -198,12 +276,17 @@ class Document(object): | |
Type: Review. | ||
""" | ||
|
||
def __init__(self, version=None, data_license=None, comment=None, package=None): | ||
def __init__(self, version=None, data_license=None, name=None, spdx_id=None, | ||
namespace=None, comment=None, package=None): | ||
# avoid recursive impor | ||
from spdx.creationinfo import CreationInfo | ||
self.version = version | ||
self.data_license = data_license | ||
self.name = name | ||
self.spdx_id = spdx_id | ||
self.ext_document_references = [] | ||
self.comment = comment | ||
self.namespace = namespace | ||
self.creation_info = CreationInfo() | ||
self.package = package | ||
self.extracted_licenses = [] | ||
|
@@ -215,6 +298,9 @@ def add_review(self, review): | |
def add_extr_lic(self, lic): | ||
self.extracted_licenses.append(lic) | ||
|
||
def add_ext_document_reference(self, ext_doc_ref): | ||
self.ext_document_references.append(ext_doc_ref) | ||
|
||
@property | ||
def files(self): | ||
return self.package.files | ||
|
@@ -237,11 +323,14 @@ def validate(self, messages=None): | |
|
||
return (self.validate_version(messages) | ||
and self.validate_data_lics(messages) | ||
and self.validate_name(messages) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we likely want the validation to be strict or not.... Note that this PR can still go through and this can be fixed afterwards There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm planning to handle the validation part after Phase 1 ? Is that okay ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
and self.validate_spdx_id(messages) | ||
and self.validate_namespace(messages) | ||
and self.validate_ext_document_references(messages) | ||
and self.validate_creation_info(messages) | ||
and self.validate_package(messages) | ||
and self.validate_extracted_licenses(messages) | ||
and self.validate_reviews(messages) | ||
) | ||
and self.validate_reviews(messages)) | ||
|
||
def validate_version(self, messages=None): | ||
# FIXME: messages should be returned | ||
|
@@ -268,6 +357,55 @@ def validate_data_lics(self, messages=None): | |
messages.append('Document data license must be CC0-1.0.') | ||
return False | ||
|
||
def validate_name(self, messages=None): | ||
# FIXME: messages should be returned | ||
messages = messages if messages is not None else [] | ||
|
||
if self.name is None: | ||
messages.append('Document has no name.') | ||
return False | ||
else: | ||
return True | ||
|
||
def validate_namespace(self, messages=None): | ||
# FIXME: messages should be returned | ||
messages = messages if messages is not None else [] | ||
|
||
if self.namespace is None: | ||
messages.append('Document has no namespace.') | ||
return False | ||
else: | ||
return True | ||
|
||
def validate_spdx_id(self, messages=None): | ||
# FIXME: messages should be returned | ||
messages = messages if messages is not None else [] | ||
|
||
if self.spdx_id is None: | ||
messages.append('Document has no SPDX Identifier.') | ||
return False | ||
|
||
if self.spdx_id.endswith('SPDXRef-DOCUMENT'): | ||
return True | ||
else: | ||
messages.append('Invalid Document SPDX Identifier value.') | ||
return False | ||
|
||
def validate_ext_document_references(self, messages=None): | ||
# FIXME: messages should be returned | ||
messages = messages if messages is not None else [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could a simpler |
||
|
||
valid = True | ||
for doc in self.ext_document_references: | ||
if isinstance(doc, ExternalDocumentRef): | ||
valid = doc.validate(messages) and valid | ||
else: | ||
messages.append( | ||
'External document references must be of the type ' | ||
'spdx.document.ExternalDocumentRef and not ' + type(doc)) | ||
valid = False | ||
return valid | ||
|
||
def validate_reviews(self, messages=None): | ||
# FIXME: messages should be returned | ||
messages = messages if messages is not None else [] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good usage of this 👍