Skip to content

Commit

Permalink
Add type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
chadrik committed May 19, 2024
1 parent a13f7bb commit fa8d564
Show file tree
Hide file tree
Showing 23 changed files with 565 additions and 394 deletions.
9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.mypy]
files = ["src/rez/"]
exclude = [
'.*/rez/data/.*',
'.*/rez/vendor/.*',
'.*/rez/tests/.*',
]
disable_error_code = ["var-annotated", "import-not-found"]
62 changes: 40 additions & 22 deletions src/rez/build_process.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the Rez Project

from __future__ import annotations

from rez.packages import iter_packages
from rez.exceptions import BuildProcessError, BuildContextResolveError, \
Expand All @@ -18,6 +18,12 @@
import getpass
import os.path
import sys
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from rez.build_system import BuildSystem
from rez.packages import Package, Variant
from rez.release_vcs import ReleaseVCS
from rez.developer_package import DeveloperPackage


debug_print = config.debug_printer("package_release")
Expand All @@ -29,9 +35,16 @@ def get_build_process_types():
return plugin_manager.get_plugins('build_process')


def create_build_process(process_type, working_dir, build_system, package=None,
vcs=None, ensure_latest=True, skip_repo_errors=False,
ignore_existing_tag=False, verbose=False, quiet=False):
def create_build_process(process_type: str,
working_dir: str,
build_system: BuildSystem,
package=None,
vcs: ReleaseVCS | None = None,
ensure_latest: bool = True,
skip_repo_errors: bool = False,
ignore_existing_tag: bool = False,
verbose: bool = False,
quiet: bool = False) -> BuildProcess:
"""Create a :class:`BuildProcess` instance.
.. warning::
Expand Down Expand Up @@ -77,7 +90,8 @@ class BuildProcess(object):
def name(cls):
raise NotImplementedError

def __init__(self, working_dir, build_system, package=None, vcs=None,
def __init__(self, working_dir: str, build_system: BuildSystem, package=None,
vcs: ReleaseVCS | None = None,
ensure_latest=True, skip_repo_errors=False,
ignore_existing_tag=False, verbose=False, quiet=False):
"""Create a BuildProcess.
Expand Down Expand Up @@ -119,14 +133,15 @@ def __init__(self, working_dir, build_system, package=None, vcs=None,
self.package.config.build_directory)

@property
def package(self):
def package(self) -> DeveloperPackage:
return self.build_system.package

@property
def working_dir(self):
def working_dir(self) -> str:
return self.build_system.working_dir

def build(self, install_path=None, clean=False, install=False, variants=None):
def build(self, install_path: str | None = None, clean: bool = False,
install=False, variants: list[int] | None = None) -> int:
"""Perform the build process.
Iterates over the package's variants, resolves the environment for
Expand All @@ -149,7 +164,8 @@ def build(self, install_path=None, clean=False, install=False, variants=None):
"""
raise NotImplementedError

def release(self, release_message=None, variants=None):
def release(self, release_message: str | None = None,
variants: list[int] | None = None) -> int:
"""Perform the release process.
Iterates over the package's variants, building and installing each into
Expand All @@ -167,7 +183,7 @@ def release(self, release_message=None, variants=None):
"""
raise NotImplementedError

def get_changelog(self):
def get_changelog(self) -> str | None:
"""Get the changelog since last package release.
Returns:
Expand Down Expand Up @@ -215,7 +231,7 @@ def visit_variants(self, func, variants=None, **kwargs):

return num_visited, results

def get_package_install_path(self, path):
def get_package_install_path(self, path: str) -> str:
"""Return the installation path for a package (where its payload goes).
Args:
Expand All @@ -230,7 +246,8 @@ def get_package_install_path(self, path):
package_version=self.package.version
)

def create_build_context(self, variant, build_type, build_path):
def create_build_context(self, variant: Variant, build_type: BuildType,
build_path: str) -> tuple[ResolvedContext, str]:
"""Create a context to build the variant within."""
request = variant.get_requires(build_requires=True,
private_build_requires=True)
Expand Down Expand Up @@ -274,7 +291,7 @@ def create_build_context(self, variant, build_type, build_path):
raise BuildContextResolveError(context)
return context, rxt_filepath

def pre_release(self):
def pre_release(self) -> None:
release_settings = self.package.config.plugins.release_vcs

# test that the release path exists
Expand Down Expand Up @@ -322,7 +339,7 @@ def pre_release(self):
else:
break

def post_release(self, release_message=None):
def post_release(self, release_message=None) -> None:
tag_name = self.get_current_tag_name()

if self.vcs is None:
Expand All @@ -332,7 +349,7 @@ def post_release(self, release_message=None):
with self.repo_operation():
self.vcs.create_release_tag(tag_name=tag_name, message=release_message)

def get_current_tag_name(self):
def get_current_tag_name(self) -> str:
release_settings = self.package.config.plugins.release_vcs
try:
tag_name = self.package.format(release_settings.tag_name)
Expand All @@ -342,7 +359,7 @@ def get_current_tag_name(self):
tag_name = "unversioned"
return tag_name

def run_hooks(self, hook_event, **kwargs):
def run_hooks(self, hook_event, **kwargs) -> None:
hook_names = self.package.config.release_hooks or []
hooks = create_release_hooks(hook_names, self.working_dir)

Expand All @@ -362,7 +379,7 @@ def run_hooks(self, hook_event, **kwargs):
% (hook_event.label, hook.name(),
e.__class__.__name__, str(e)))

def get_previous_release(self):
def get_previous_release(self) -> Package | None:
release_path = self.package.config.release_packages_path
it = iter_packages(self.package.name, paths=[release_path])
packages = sorted(it, key=lambda x: x.version, reverse=True)
Expand All @@ -372,18 +389,19 @@ def get_previous_release(self):
return package
return None

def get_changelog(self):
def get_changelog(self) -> str | None:
previous_package = self.get_previous_release()
if previous_package:
previous_revision = previous_package.revision
else:
previous_revision = None

changelog = None
with self.repo_operation():
changelog = self.vcs.get_changelog(
previous_revision,
max_revisions=config.max_package_changelog_revisions)
if self.vcs:
with self.repo_operation():
changelog = self.vcs.get_changelog(
previous_revision,
max_revisions=config.max_package_changelog_revisions)

return changelog

Expand Down
43 changes: 32 additions & 11 deletions src/rez/build_system.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the Rez Project
from __future__ import annotations


import argparse
import os.path
from typing import TYPE_CHECKING, TypedDict


from rez.build_process import BuildType
from rez.exceptions import BuildSystemError
from rez.packages import get_developer_package
from rez.rex_bindings import VariantBinding

if TYPE_CHECKING:
from rez.developer_package import DeveloperPackage
from rez.resolved_context import ResolvedContext
from rez.packages import Package, Variant


class BuildResult(TypedDict):
success: bool
extra_files: list[str]
build_env_script: str


def get_buildsys_types():
"""Returns the available build system implementations - cmake, make etc."""
from rez.plugin_managers import plugin_manager
return plugin_manager.get_plugins('build_system')


def get_valid_build_systems(working_dir, package=None):
def get_valid_build_systems(working_dir: str,
package: Package | None = None) -> list[type[BuildSystem]]:
"""Returns the build system classes that could build the source in given dir.
Args:
Expand Down Expand Up @@ -67,9 +82,9 @@ def get_valid_build_systems(working_dir, package=None):
return clss


def create_build_system(working_dir, buildsys_type=None, package=None, opts=None,
def create_build_system(working_dir: str, buildsys_type=None, package=None, opts=None,
write_build_scripts=False, verbose=False,
build_args=[], child_build_args=[]):
build_args=[], child_build_args=[]) -> BuildSystem:
"""Return a new build system that can build the source in working_dir."""
from rez.plugin_managers import plugin_manager

Expand Down Expand Up @@ -104,11 +119,12 @@ class BuildSystem(object):
"""A build system, such as cmake, make, Scons etc.
"""
@classmethod
def name(cls):
def name(cls) -> str:
"""Return the name of the build system, eg 'make'."""
raise NotImplementedError

def __init__(self, working_dir, opts=None, package=None,
def __init__(self, working_dir: str, opts=None,
package: DeveloperPackage | None = None,
write_build_scripts=False, verbose=False, build_args=[],
child_build_args=[]):
"""Create a build system instance.
Expand Down Expand Up @@ -143,12 +159,12 @@ def __init__(self, working_dir, opts=None, package=None,
self.opts = opts

@classmethod
def is_valid_root(cls, path):
def is_valid_root(cls, path: str) -> bool:
"""Return True if this build system can build the source in path."""
raise NotImplementedError

@classmethod
def child_build_system(cls):
def child_build_system(cls) -> str | None:
"""Returns the child build system.
Some build systems, such as cmake, don't build the source directly.
Expand All @@ -163,7 +179,7 @@ def child_build_system(cls):
return None

@classmethod
def bind_cli(cls, parser, group):
def bind_cli(cls, parser: argparse.ArgumentParser, group):
"""Expose parameters to an argparse.ArgumentParser that are specific
to this build system.
Expand All @@ -174,8 +190,13 @@ def bind_cli(cls, parser, group):
"""
pass

def build(self, context, variant, build_path, install_path, install=False,
build_type=BuildType.local):
def build(self,
context: ResolvedContext,
variant: Variant,
build_path: str,
install_path: str,
install: bool = False,
build_type=BuildType.local) -> BuildResult:
"""Implement this method to perform the actual build.
Args:
Expand Down
10 changes: 8 additions & 2 deletions src/rez/cli/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
'''
Build a package from source.
'''
from __future__ import annotations

import os
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from rez.developer_package import DeveloperPackage


# Cache the developer package loaded from cwd. This is so the package is only
# loaded once, even though it's required once at arg parsing time (to determine
# valid build system types), and once at command run time.
#
_package = None
_package: DeveloperPackage | None = None


def get_current_developer_package():
def get_current_developer_package() -> DeveloperPackage:
from rez.packages import get_developer_package

global _package
Expand Down
20 changes: 13 additions & 7 deletions src/rez/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
import re
import copy

from typing_extensions import Protocol


class Validatable(Protocol):
def validate(self, data):
pass


class _Deprecation(object):
def __init__(self, removed_in, extra=None):
Expand Down Expand Up @@ -54,7 +61,7 @@ class Setting(object):
Note that lazy setting validation only happens on main configuration
settings - plugin settings are validated on load only.
"""
schema = Schema(object)
schema: Validatable = Schema(object)

def __init__(self, config, key):
self.config = config
Expand Down Expand Up @@ -135,7 +142,7 @@ def _validate(self, data):


class Str(Setting):
schema = Schema(str)
schema: Validatable = Schema(str)

def _parse_env_var(self, value):
return value
Expand All @@ -153,7 +160,7 @@ class OptionalStr(Str):


class StrList(Setting):
schema = Schema([str])
schema: Validatable = Schema([str])
sep = ','

def _parse_env_var(self, value):
Expand Down Expand Up @@ -184,8 +191,7 @@ def validate(self, data):


class OptionalStrList(StrList):
schema = Or(And(None, Use(lambda x: [])),
[str])
schema = Or(And(None, Use(lambda x: [])), [str])


class PathList(StrList):
Expand Down Expand Up @@ -219,7 +225,7 @@ def _parse_env_var(self, value):


class Bool(Setting):
schema = Schema(bool)
schema: Validatable = Schema(bool)
true_words = frozenset(["1", "true", "t", "yes", "y", "on"])
false_words = frozenset(["0", "false", "f", "no", "n", "off"])
all_words = true_words | false_words
Expand Down Expand Up @@ -255,7 +261,7 @@ def _parse_env_var(self, value):


class Dict(Setting):
schema = Schema(dict)
schema: Validatable = Schema(dict)

def _parse_env_var(self, value):
items = value.split(",")
Expand Down

0 comments on commit fa8d564

Please sign in to comment.