Browse Source

replace use of nr.databind in shut.changog with databind

shut-new-model
Niklas Rosenstein 9 months ago
parent
commit
0eacf15a82
No known key found for this signature in database GPG Key ID: 6D269B33D25F6C6
7 changed files with 64 additions and 59 deletions
  1. + 5
    - 7
      src/shut/changelog/__init__.py
  2. + 15
    - 17
      src/shut/changelog/manager.py
  3. + 12
    - 9
      src/shut/changelog/v1.py
  4. + 20
    - 17
      src/shut/changelog/v2.py
  5. + 7
    - 5
      src/shut/changelog/v3.py
  6. + 5
    - 3
      src/shut/commands/changelog/__init__.py
  7. + 0
    - 1
      src/shut/model/author.py

+ 5
- 7
src/shut/changelog/__init__.py

@ -33,17 +33,15 @@ This is achieved by assigning a keyword to every changelog, and that keyword ind
the type of change and whether it is breaking an API.
"""
from typing import Any, Type, TypeVar
T = TypeVar('T')
from typing import Any, Type, T
class _ChangelogBase:
"""
Base class for #nr.databind.core.Struct subclasses that represent the deserialized
form of a changelog in a specific version. A newer version should reference the
predecessor in the #Supersedes class-level attribute and implement the #adapt()
method in order to automatically support migrating to the next version.
Base class for datamodels subclasses that represent the deserialized form of a changelog in
a specific version. A newer version should reference the predecessor in the #Supersedes
class-level attribute and implement the #adapt() method in order to automatically support
migrating to the next version.
"""
Supersedes: Type[T] = None

+ 15
- 17
src/shut/changelog/manager.py

@ -19,33 +19,31 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
from shore.util.version import Version
from . import v1, v2, v3
from nr.databind.core import ObjectMapper, SkipDefaults
from nr.databind.json import JsonModule
from typing import Iterable, Optional
import datetime
import os
from typing import Iterable, Optional, Union
from databind.core import datamodel, field
from databind.json import from_json, to_json
import yaml
mapper = ObjectMapper(JsonModule())
supported_changelog_types = (
v3.Changelog,
v2.Changelog,
v1.Changelog,
)
from shut.model import registry
from shut.model.version import Version
from . import v1, v2, v3
AllChangelogTypes = Union[v3.Changelog, v2.Changelog, v1.Changelog]
@datamodel
class Changelog:
"""
Represents a changelog on disk.
"""
def __init__(self, filename: str, version: Optional[Version]) -> None:
self.filename = filename
self.version = version
self.data = v3.Changelog(changes=[])
filename: Optional[str] = field(derived=True, default=None)
version: Optional[Version]
data: v3.Changelog = field(default_factory=lambda: v3.Changelog(changes=[]))
@property
def entries(self):
@ -62,7 +60,7 @@ class Changelog:
with open(self.filename) as fp:
raw_data = yaml.safe_load(fp)
data = mapper.deserialize(raw_data, supported_changelog_types, filename=self.filename)
data = from_json(AllChangelogTypes, raw_data, registry=registry)
if not isinstance(data, v3.Changelog):
data = v3.Changelog.migrate(data)
@ -73,7 +71,7 @@ class Changelog:
if create_directory:
os.makedirs(os.path.dirname(self.filename), exist_ok=True)
data = mapper.serialize(self.data, v3.Changelog)
data = to_json(self.data, v3.Changelog)
with open(self.filename, 'w') as fp:
yaml.safe_dump(data, fp, sort_keys=False)

+ 12
- 9
src/shut/changelog/v1.py

@ -23,22 +23,25 @@
The V1 of changelogs.
"""
from typing import List, Generic, T, Union
from databind.core import datamodel, field
from . import _ChangelogBase
from nr.databind.core import Collection, Field, Struct
class Entry(Struct):
@datamodel
class Entry:
"""
Represents a changelog entry in the V1 changelog format.
"""
types = Field([str])
issues = Field([(str, int)], default=list)
components = Field([str])
description = Field(str)
types: List[str]
issues: List[Union[str, int]] = field(default_factory=list)
components: List[str]
description: str
class Changelog(_ChangelogBase, Collection, list):
class ChangelogType(Generic[T], _ChangelogBase):
Supersedes = None # _ChangelogBase
item_type = Entry # Collection
Entry = Entry
Changelog = ChangelogType[Entry]

+ 20
- 17
src/shut/changelog/v2.py

@ -23,28 +23,30 @@
The V3 of changelogs.
"""
from . import _ChangelogBase, v1
from nr.databind.core import Collection, Field, FieldName, Struct
import enum
from typing import List, Generic, T
from databind.core import datamodel, field
from . import _ChangelogBase, v1
class Type(enum.Enum):
fix = 0
improvement = 1
change = 3
refactor = 4
feature = 5
docs = 6
tests = 7
fix = enum.auto()
improvement = enum.auto()
change = enum.auto()
refactor = enum.auto()
feature = enum.auto()
docs = enum.auto()
tests = enum.auto()
class Entry(Struct):
@datamodel
class Entry:
Type = Type
type_ = Field(Type, FieldName('type'))
component = Field(str)
description = Field(str)
fixes = Field([str])
type_: Type = field(altname='type')
component: str
description: str
fixes: List[str]
@classmethod
def from_v1(cls, v1_entry: v1.Entry) -> 'Entry':
@ -60,11 +62,12 @@ class Entry(Struct):
)
class Changelog(_ChangelogBase, Collection, list):
class ChangelogType(Generic[T], _ChangelogBase):
Supersedes = v1.Changelog # _ChangelogBase
item_type = Entry # Collection
Entry = Entry
@classmethod
def adapt(cls, v1_changelog: v1.Changelog) -> 'Changelog':
return cls(map(Entry.from_v1, v1_changelog))
Changelog = ChangelogType[Entry]

+ 7
- 5
src/shut/changelog/v3.py

@ -23,17 +23,19 @@
The V2 of changelogs.
"""
from . import _ChangelogBase, v2
from nr.databind.core import Field, Struct
import datetime
from typing import List, Optional
from databind.core import datamodel, field
from . import _ChangelogBase, v2
class Changelog(_ChangelogBase, Struct):
@datamodel
class Changelog(_ChangelogBase):
Supersedes = v2.Changelog # _ChangelogBase
Entry = v2.Entry
release_date = Field(datetime.date, default=None)
changes = Field([v2.Entry])
release_date: Optional[datetime.date] = field(default=None)
changes: List[v2.Entry]
@classmethod
def adapt(cls, v2_changelog: v2.Changelog) -> 'Changelog':

+ 5
- 3
src/shut/commands/changelog/__init__.py

@ -23,6 +23,7 @@ import logging
import sys
from typing import List, Optional
from databind.json import from_json, to_json
from nr.utils.git import Git
from termcolor import colored
import click
@ -31,8 +32,9 @@ import yaml
from shore.__main__ import _edit_text, _editor_open
from .. import shut, commons, project
from shut.changelog import v3
from shut.changelog.manager import mapper, ChangelogManager
from shut.changelog.manager import ChangelogManager
from shut.changelog.render import render as render_changelogs
from shut.model import registry
from shut.model.version import parse_version
from shut.model.package import PackageModel
@ -96,8 +98,8 @@ def changelog(**args):
# Allow the user to edit the entry if no description is provided or the
# -e,--edit option was set.
if not entry.description or args['edit']:
serialized = yaml.safe_dump(mapper.serialize(entry, v3.Changelog.Entry), sort_keys=False)
entry = mapper.deserialize(yaml.safe_load(_edit_text(serialized)), v3.Changelog.Entry)
serialized = yaml.safe_dump(to_json(entry, v3.Changelog.Entry, registry=registry), sort_keys=False)
entry = from_json(v3.Changelog.Entry, yaml.safe_load(_edit_text(serialized)), registry=registry)
# Validate the entry contents (need a description and at least one type and component).
if not entry.description or not entry.component:

+ 0
- 1
src/shut/model/author.py

@ -20,7 +20,6 @@
# IN THE SOFTWARE.
from databind.core import datamodel
from nr.databind.json import JsonSerializer
import re

Loading…
Cancel
Save