-
Notifications
You must be signed in to change notification settings - Fork 275
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
New metadata API: add MetadataInfo and TargetFile classes #1223
Closed
MVrachev
wants to merge
9
commits into
theupdateframework:develop
from
MVrachev:complex-metadata-classes
Closed
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
a141580
New API: Add root use case in couple of tests
MVrachev 7cfd100
New API: Timestamp - make length and hashes optional
MVrachev b3e98b9
NEW API: Fix documentation indentation
MVrachev cbf4664
New API: Document that _type is not protected
MVrachev 8cc785c
New API: Add MetadataInfo class
MVrachev 6259f31
New API: Add TargetFile class
MVrachev c37bdd2
New API: Make sure we are not changing dict arg
MVrachev b9c70aa
New API: Add a TODO comments
MVrachev 383e260
New API: Disable irrelevant pylint warnings
MVrachev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -570,22 +570,66 @@ def update( | |
self.meta[metadata_fn] = MetadataInfo(version, length, hashes) | ||
|
||
|
||
class TargetInfo: | ||
"""A container with information about a particular target file. | ||
Instances of TargetInfo are used as values in a dictionary | ||
called "targets" in Targets. | ||
|
||
Attributes: | ||
length: An integer indicating the length of the target file. | ||
hashes: A dictionary containing hash algorithms and the | ||
hashes resulted from applying them over the target file:: | ||
|
||
'hashes': { | ||
'<HASH ALGO 1>': '<TARGET FILE HASH 1>', | ||
'<HASH ALGO 2>': '<TARGET FILE HASH 2>', | ||
... | ||
} | ||
|
||
custom: An optional dictionary which may include version numbers, | ||
dependencies, or any other data that the application wants | ||
to include to describe the target file:: | ||
|
||
'custom': { | ||
'type': 'metadata', | ||
'file_permissions': '0644', | ||
... | ||
} // optional | ||
|
||
""" | ||
|
||
def __init__(self, length: int, hashes: JsonDict, | ||
custom: Optional[JsonDict] = None) -> None: | ||
self.length = length | ||
self.hashes = hashes | ||
self.custom = custom | ||
|
||
|
||
def __eq__(self, other: 'TargetInfo') -> bool: | ||
"""Compare objects by their values instead of by their addresses.""" | ||
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. Same comment about identity here. |
||
return (self.length == other.length and | ||
self.hashes == other.hashes and | ||
self.custom == other.custom) | ||
|
||
|
||
def to_dict(self) -> JsonDict: | ||
"""Returns the JSON-serializable dictionary representation of self. """ | ||
json_dict = {'length': self.length, 'hashes': self.hashes} | ||
|
||
if self.custom is not None: | ||
json_dict['custom'] = self.custom | ||
|
||
return json_dict | ||
|
||
|
||
class Targets(Signed): | ||
"""A container for the signed part of targets metadata. | ||
|
||
Attributes: | ||
targets: A dictionary that contains information about target files:: | ||
|
||
{ | ||
'<TARGET FILE NAME>': { | ||
'length': <TARGET FILE SIZE>, | ||
'hashes': { | ||
'<HASH ALGO 1>': '<TARGET FILE HASH 1>', | ||
'<HASH ALGO 2>': '<TARGETS FILE HASH 2>', | ||
... | ||
}, | ||
'custom': <CUSTOM OPAQUE DICT> // optional | ||
}, | ||
'<TARGET FILE NAME>': <TargetInfo INSTANCE>, | ||
... | ||
} | ||
|
||
|
@@ -629,25 +673,41 @@ class Targets(Signed): | |
# pylint: disable=too-many-arguments | ||
def __init__( | ||
self, _type: str, version: int, spec_version: str, | ||
expires: datetime, targets: JsonDict, delegations: JsonDict | ||
) -> None: | ||
expires: datetime, targets: Dict[str, TargetInfo], | ||
delegations: JsonDict) -> None: | ||
super().__init__(_type, version, spec_version, expires) | ||
# TODO: Add class for meta | ||
self.targets = targets | ||
|
||
# TODO: Add Key and Role classes | ||
self.delegations = delegations | ||
|
||
|
||
@classmethod | ||
def from_dict(cls, signed_dict: JsonDict) -> 'Targets': | ||
"""Creates Targets object from its JSON/dict representation. """ | ||
for target_path in signed_dict['targets'].keys(): | ||
signed_dict['targets'][target_path] = TargetInfo( | ||
**signed_dict['targets'][target_path]) | ||
|
||
return super().from_dict(signed_dict) | ||
|
||
|
||
# Serialization. | ||
def to_dict(self) -> JsonDict: | ||
"""Returns the JSON-serializable dictionary representation of self. """ | ||
json_dict = super().to_dict() | ||
target_dict = {} | ||
for target_path, target_file_obj in self.targets.items(): | ||
target_dict[target_path] = target_file_obj.to_dict() | ||
|
||
json_dict.update({ | ||
'targets': self.targets, | ||
'targets': target_dict, | ||
'delegations': self.delegations, | ||
}) | ||
return json_dict | ||
|
||
# Modification. | ||
def update(self, filename: str, fileinfo: JsonDict) -> None: | ||
"""Assigns passed target file info to meta dict. """ | ||
self.targets[filename] = fileinfo | ||
self.targets[filename] = TargetInfo(fileinfo['length'], | ||
fileinfo['hashes'], fileinfo.get('custom')) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Similar to the above suggestion, I'd welcome feedback on whether this is clearer or not?