Skip to content

Commit

Permalink
kraken-build/: feature: Add kraken.build module which allows import…
Browse files Browse the repository at this point in the history
…ing the current `context` and `project` from a build script as if calling `Context.current()` or `Project.current()`
  • Loading branch information
NiklasRosenstein committed Jan 7, 2024
1 parent 8d0b978 commit a33acfe
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .kraken.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def configure_project(project: Project) -> None:
python.mypy(additional_args=["--exclude", "src/tests/integration/.*/data/.*"])

if project.directory.joinpath("tests").is_dir():
python.pytest(ignore_dirs=["src/tests/integration"])
# Explicit list of test directories, Pytest skips the build directory if not specified explicitly.
python.pytest(ignore_dirs=["src/tests/integration"], include_dirs=["src/kraken/build"])

if project.directory.joinpath("tests/integration").is_dir():
python.pytest(
name="pytestIntegration",
Expand Down
5 changes: 5 additions & 0 deletions kraken-build/.changelog/_unreleased.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[[entries]]
id = "f0b6da17-e82e-451b-b919-81529b97cd30"
type = "feature"
description = "Add `kraken.build` module which allows importing the current `context` and `project` from a build script as if calling `Context.current()` or `Project.current()`"
author = "@NiklasRosenstein"
1 change: 1 addition & 0 deletions kraken-build/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ keywords = []
license = "MIT"
name = "kraken-build"
packages = [
{include = "kraken/build", from = "src"},
{include = "kraken/common", from = "src"},
{include = "kraken/core", from = "src"},
{include = "kraken/std", from = "src"},
Expand Down
11 changes: 11 additions & 0 deletions kraken-build/src/kraken/build/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from kraken.core import Context, Project
from .utils.import_helper import _KrakenBuildModuleWrapper

# Install a wrapper around the module object to allow build-scripts to always import the current (i.e. their own)
# project and the Kraken build context.
context: Context
project: Project

_KrakenBuildModuleWrapper.install(__name__)

__all__ = ["context", "project"]
36 changes: 36 additions & 0 deletions kraken-build/src/kraken/build/tests/test_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest
from kraken.core import Context, Project
from pathlib import Path


def test_import_current_context_and_project_from_kraken_build() -> None:
""" Test that you can import the current Kraken build context and project from `kraken.build`. """

with pytest.raises(RuntimeError):
from kraken.build import context

with pytest.raises(RuntimeError):
from kraken.build import project

with Context(Path.cwd()).as_current() as ctx:
with Project("test", Path.cwd(), None, ctx).as_current() as proj:
from kraken.build import context, project # noqa: F811

assert context is ctx
assert project is proj

with Project("subproject", Path.cwd() / "subproject", None, ctx).as_current() as subproj:
from kraken.build import context, project # noqa: F811

assert context is ctx
assert project is subproj

from kraken.build import context

assert context is ctx

with pytest.raises(RuntimeError):
from kraken.build import project

with pytest.raises(RuntimeError):
from kraken.build import context
25 changes: 25 additions & 0 deletions kraken-build/src/kraken/build/utils/import_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sys
import types
from typing import Any
from kraken.core import Context, Project


class _KrakenBuildModuleWrapper:
""" A wrapper for the `kraken.build` module to allow build-scripts to always import the current (i.e. their own)
project and the Kraken build context. """

def __init__(self, module: types.ModuleType) -> None:
self.__module = module

def __getattr__(self, name: str) -> Any:
if name == "context":
return Context.current()
elif name == "project":
return Project.current()
else:
return getattr(self.__module, name)

@staticmethod
def install(module_name: str) -> None:
""" Install the wrapper around the given module. """
sys.modules[module_name] = _KrakenBuildModuleWrapper(sys.modules[module_name]) # type: ignore[assignment]

0 comments on commit a33acfe

Please sign in to comment.