Browse Source

add AbstractProjectModel.project field, add "shut mono bump" command

shut-new-model
Niklas Rosenstein 9 months ago
parent
commit
6c1a33e6a3
No known key found for this signature in database GPG Key ID: 6D269B33D25F6C6
8 changed files with 94 additions and 26 deletions
  1. + 4
    - 4
      src/shut/commands/commons/bump.py
  2. + 1
    - 0
      src/shut/commands/mono/__init__.py
  3. + 54
    - 0
      src/shut/commands/mono/bump.py
  4. + 9
    - 5
      src/shut/commands/mono/checks.py
  5. + 4
    - 4
      src/shut/commands/pkg/bump.py
  6. + 12
    - 10
      src/shut/model/__init__.py
  7. + 4
    - 0
      src/shut/model/abstract.py
  8. + 6
    - 3
      src/shut/update/generic.py

+ 4
- 4
src/shut/commands/commons/bump.py

@ -119,16 +119,16 @@ def do_bump(args: Args, data: VersionBumpData[AbstractProjectModel]) -> None:
# TODO(NiklasRosenstein): Bump based on changelog
sys.exit('error: missing version argument or bump option')
version_refs = list(get_version_refs(data.obj))
if not version_refs:
sys.exit('error: no version refs found')
# Run checks.
if not args.skip_checks:
res = data.run_checks()
if res != 0:
sys.exit('error: checks failed')
version_refs = list(get_version_refs(data.obj))
if not version_refs:
sys.exit('error: no version refs found')
# Ensure the version is the same accross all refs.
current_version = data.obj.get_version()
is_inconsistent = any(parse_version(x.value) != current_version for x in version_refs)

+ 1
- 0
src/shut/commands/mono/__init__.py

@ -30,6 +30,7 @@ def mono():
"""
from . import bump
from . import checks
from . import new
from . import status

+ 54
- 0
src/shut/commands/mono/bump.py

@ -0,0 +1,54 @@
# -*- coding: utf8 -*-
# Copyright (c) 2020 Niklas Rosenstein
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import os
import logging
import sys
from typing import Iterable
import click
from shut.commands.commons.bump import make_bump_command, VersionBumpData, VersionRef
from shut.model import MonorepoModel, Project
from shut.model.version import get_commit_distance_version, parse_version, Version
from . import mono
from .checks import check_monorepo
from .update import update_monorepo
logger = logging.getLogger(__name__)
class MonorepoBumpdata(VersionBumpData[MonorepoModel]):
def run_checks(self) -> int:
return check_monorepo(self.obj, self.args.warnings_as_errors)
def update(self) -> None:
update_monorepo(self.obj, dry=self.args.dry)
def get_snapshot_version(self) -> Version:
return get_commit_distance_version(
self.obj.directory,
self.obj.version,
self.obj.get_tag(self.obj.version)) or self.obj.version
mono.command()(make_bump_command(MonorepoBumpdata, MonorepoModel))

+ 9
- 5
src/shut/commands/mono/checks.py

@ -39,6 +39,14 @@ import time
logger = logging.getLogger(__name__)
def check_monorepo(monorepo: MonorepoModel, warnings_as_errors: bool = False):
start_time = time.perf_counter()
checks = sorted(get_checks(project, monorepo), key=lambda c: c.name)
seconds = time.perf_counter() - start_time
print_checks_all(monorepo.name, checks, seconds)
return get_checks_status(checks, warnings_as_errors)
@mono.command()
@click.option('-w', '--warnings-as-errors', is_flag=True)
def checks(warnings_as_errors):
@ -49,9 +57,5 @@ def checks(warnings_as_errors):
on the package configuration and entrypoint definition.
"""
start_time = time.perf_counter()
monorepo = project.load_or_exit(expect=MonorepoModel)
checks = sorted(get_checks(project, monorepo), key=lambda c: c.name)
seconds = time.perf_counter() - start_time
print_checks_all(monorepo.name, checks, seconds)
sys.exit(get_checks_status(checks, warnings_as_errors))
sys.exit(check_monorepo(monorepo, warnings_as_errors))

+ 4
- 4
src/shut/commands/pkg/bump.py

@ -52,6 +52,9 @@ class PackageBumpData(VersionBumpData[PackageModel]):
def run_checks(self) -> int:
return check_package(self.obj, self.args.warnings_as_errors)
def update(self) -> None:
update_package(self.obj, dry=self.args.dry)
def get_snapshot_version(self) -> Version:
project = self.project
if project.monorepo and project.monorepo.release.single_version:
@ -61,10 +64,7 @@ class PackageBumpData(VersionBumpData[PackageModel]):
return get_commit_distance_version(
subject.directory,
subject.version,
subject.get_tag(subject.version)) or subject.version
def update(self) -> Version:
update_package(self.obj, dry=self.args.dry)
subject.get_tag(subject.get_version())) or subject.get_version()
pkg.command()(make_bump_command(PackageBumpData, PackageModel))

+ 12
- 10
src/shut/model/__init__.py

@ -32,10 +32,6 @@ registry = Registry(json_registry)
registry.set_option(datamodel, 'skip_defaults', True)
ExcInfo = Tuple
from .abstract import AbstractProjectModel
from .monorepo import MonorepoModel
from .package import PackageModel
def get_existing_file(directory: str, choices: List[str]) -> bool:
for fn in choices:
@ -67,8 +63,8 @@ class Project:
Unexpected = Unexpected
def __init__(self):
self._cache: Dict[str, AbstractProjectModel] = {}
self.subject: AbstractProjectModel = None
self._cache: Dict[str, >'AbstractProjectModel'] = {}
self.subject: >'AbstractProjectModel' = None
self.monorepo: MonorepoModel = None
self.packages: List[PackageModel] = []
self.invalid_packages: List[Tuple[str, ExcInfo]] = []
@ -76,8 +72,8 @@ class Project:
def load(
self,
directory: str = '.',
expect: Type[AbstractProjectModel] = None,
) -> AbstractProjectModel:
expect: Type[>'AbstractProjectModel'] = None,
) -> >'AbstractProjectModel':
"""
Loads all project information from *directory*. This searches in all parent directories
for a package or monorepo configuration, then loads all resources that belong to the
@ -133,12 +129,13 @@ class Project:
#node_collector = NodeCollector()
obj = self._cache[filename] = from_json(type_, data, registry=registry)
obj.filename = filename
obj.project = self
#obj.unknown_keys = list(Stream.concat(
# (x.locator.append(k) for k in x.unknowns)
# for x in node_collector.nodes))
return obj
def _load_monorepo(self, filename: str) -> MonorepoModel:
def _load_monorepo(self, filename: str) -> >'MonorepoModel':
self.monorepo = self._load_object(filename, MonorepoModel)
# Load packages in that monorepo.
@ -153,7 +150,7 @@ class Project:
return self.monorepo
def _load_package(self, filename: str) -> PackageModel:
def _load_package(self, filename: str) -> >'PackageModel':
package = self._load_object(filename, PackageModel)
if package not in self.packages:
self.packages.append(package)
@ -167,3 +164,8 @@ def dump(obj: Any, file_: Union[str, TextIO]) -> None:
else:
data = to_json(obj, registry=registry)
yaml.safe_dump(data, file_, sort_keys=False)
from .abstract import AbstractProjectModel
from .monorepo import MonorepoModel
from .package import PackageModel

+ 4
- 0
src/shut/model/abstract.py

@ -30,6 +30,7 @@ from .version import Version
@datamodel
class AbstractProjectModel(metaclass=abc.ABCMeta):
project: Optional['Project'] = field(derived=True, default=None)
filename: Optional[str] = field(derived=True, default=None)
unknown_keys: List[str] = field(derived=True, default_factory=list)
changelog: ChangelogConfiguration = field(default_factory=ChangelogConfiguration)
@ -51,3 +52,6 @@ class AbstractProjectModel(metaclass=abc.ABCMeta):
def get_changelog_directory(self) -> str:
return os.path.join(os.path.dirname(self.filename), self.changelog.directory)
from . import Project

+ 6
- 3
src/shut/update/generic.py

@ -22,9 +22,9 @@
import re
from typing import Iterable
from shut.model import AbstractProjectModel
from shut.model import AbstractProjectModel, MonorepoModel
from shut.utils.io.virtual import VirtualFiles
from .core import Renderer, register_renderer, VersionRef
from .core import Renderer, get_version_refs, register_renderer, VersionRef
class GenericRenderer(Renderer[AbstractProjectModel]):
@ -42,6 +42,9 @@ class GenericRenderer(Renderer[AbstractProjectModel]):
if match:
yield VersionRef(obj.filename, match.start(1), match.end(1), match.group(1))
if isinstance(obj, MonorepoModel) and obj.release.single_version:
for package in obj.project.packages:
yield from get_version_refs(package)
register_renderer(AbstractProjectModel, GenericRenderer)
register_renderer(AbstractProjectModel, GenericRenderer)

Loading…
Cancel
Save