-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add citation.cff and LICENSE to archive packages and git repos
currently these are not retroactively inserted into archive packages since that would require rebuilding everything. Generating git repos, however, will add them if they are missing ** includes an experimental refactor of metadata transformations which is used to implement the citation file format generation resolves comses/planning#234
- Loading branch information
Showing
8 changed files
with
301 additions
and
18 deletions.
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
Large diffs are not rendered by default.
Oops, something went wrong.
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
1 change: 1 addition & 0 deletions
1
django/library/tests/samples/releases/animals-model/1.0.0/results/analysis.txt
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 |
---|---|---|
@@ -0,0 +1 @@ | ||
result tells us there are more sheep |
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 |
---|---|---|
@@ -0,0 +1,139 @@ | ||
from abc import ABC, abstractmethod | ||
import json | ||
import yaml | ||
|
||
from .models import ReleaseContributor, CodebaseRelease, Codebase | ||
|
||
|
||
def field(name=None, required=False): | ||
"""Register a method as a field in a metadata transformer. | ||
Fields will be included in the resulting metadata | ||
Args: | ||
name (str, optional): resulting name, if different from the method name. | ||
required (bool, optional): if False, will skip the field if the value is falsy. Defaults to False. | ||
""" | ||
|
||
def decorator(method): | ||
method.is_field = True | ||
method.field_name = name or method.__name__ | ||
method.required = required | ||
return method | ||
|
||
return decorator | ||
|
||
|
||
class Transformer(ABC): | ||
INITIAL_DATA = {} | ||
|
||
@abstractmethod | ||
def __init__(self): | ||
pass | ||
|
||
def create_fields_dict(self, **kwargs) -> dict: | ||
"""returns a dictionary with fields registered with @field decorators | ||
:param kwargs: additional fields to include in the metadata | ||
""" | ||
for name in dir(self): | ||
method = getattr(self, name) | ||
if getattr(method, "is_field", False) and callable(method): | ||
field_name = method.field_name | ||
value = method() | ||
required = getattr(method, "required", False) | ||
if value or required: | ||
kwargs[field_name] = value | ||
return kwargs | ||
|
||
def build(self, **kwargs): | ||
"""Build metadata from INITIAL_DATA and fields | ||
:param kwargs: additional fields to include in the metadata | ||
:return: self | ||
""" | ||
self._metadata = self.INITIAL_DATA.copy() | ||
self._metadata.update(self.create_fields_dict(**kwargs)) | ||
return self | ||
|
||
@property | ||
def metadata(self): | ||
if not hasattr(self, "_metadata"): | ||
raise AttributeError("Metadata must be generated by calling build()") | ||
return self._metadata | ||
|
||
def to_dict(self): | ||
return self.metadata.copy() | ||
|
||
def to_json(self): | ||
return json.dumps(self.metadata) | ||
|
||
def to_yaml(self): | ||
return yaml.dump(self.metadata) | ||
|
||
|
||
class ReleaseTransformer(Transformer): | ||
|
||
def __init__(self, release: CodebaseRelease): | ||
self.release = release | ||
self.codebase = release.codebase | ||
|
||
|
||
class CodebaseTransformer(Transformer): | ||
|
||
def __init__(self, codebase: Codebase): | ||
self.codebase = codebase | ||
self.metadata = self.INITIAL_DATA.copy() | ||
|
||
|
||
class ReleaseCodeMeta(ReleaseTransformer): | ||
pass | ||
|
||
|
||
class ReleaseCitation(ReleaseTransformer): | ||
"""Transform CodebaseRelease metadata into the Citation File Format | ||
(https://citation-file-format.github.io/) version 1.2.0 | ||
""" | ||
|
||
INITIAL_DATA = {"cff-version": "1.2.0"} | ||
|
||
@field(required=True) | ||
def message(self): | ||
return "If you use this software, please cite it using the metadata from this file." | ||
|
||
@field(required=True) | ||
def authors(self): | ||
return [ | ||
{ | ||
"family-names": author.contributor.get_family_name(), | ||
"given-names": author.contributor.get_given_name(), | ||
} | ||
for author in ReleaseContributor.objects.authors(self.release) | ||
] | ||
|
||
@field(required=True) | ||
def title(self): | ||
return self.codebase.title | ||
|
||
@field() | ||
def version(self): | ||
return self.release.version_number | ||
|
||
@field() | ||
def abstract(self): | ||
return self.codebase.description.raw | ||
|
||
@field() | ||
def keywords(self): | ||
return [tag.name for tag in self.codebase.tags.all()] | ||
|
||
@field() | ||
def license(self): | ||
return self.release.license.name | ||
|
||
@field(name="date-released") | ||
def date_released(self): | ||
return ( | ||
self.release.last_published_on.strftime("%Y-%m-%d") | ||
if self.release.live | ||
else None | ||
) |
Oops, something went wrong.