Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional-editable-build #80

Merged
merged 3 commits into from
Oct 10, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/source/get_started/config.md
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ Or with all options given:
ensured-targets = ["foo/generated.txt"]
skip-if-exists = ["foo/generated.txt"]
install-pre-commit-hook = true
optional-editable-build = true

[tool.hatch.build.hooks.jupyter-builder.build-kwargs]
build_cmd = "build:src"
@@ -67,6 +68,12 @@ You can also use `editable-build-kwargs` if the parameters should differ
in editable mode. If only the build command is different, you can use
`editable_build_cmd` in `build-kwargs` instead.

### optional-editable-build

The optional `optional-editable-build` parameter can be set to `true` to
show a warning instead of erroring if the build fails in editable mode.
This can be used when build artifacts are optional for local development.

### install-pre-commit-hook

The optional `install-pre-commit-hook` boolean causes a `pre-commit` hook to be installed during an editable install.
10 changes: 9 additions & 1 deletion hatch_jupyter_builder/plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import typing as t
import warnings
from dataclasses import dataclass, field, fields

from hatchling.builders.hooks.plugin.interface import BuildHookInterface
@@ -24,6 +25,7 @@ class JupyterBuildConfig:
editable_build_kwargs: t.Mapping[str, str] = field(default_factory=dict)
ensured_targets: t.List[str] = field(default_factory=list)
skip_if_exists: t.List[str] = field(default_factory=list)
optional_editable_build: str = ""


class JupyterBuildHook(BuildHookInterface):
@@ -72,7 +74,13 @@ def initialize(self, version, build_data):
build_kwargs = normalize_kwargs(build_kwargs)
log.info(f"Building with {config.build_function}")
log.info(f"With kwargs: {build_kwargs}")
build_func(self.target_name, version, **build_kwargs)
try:
build_func(self.target_name, version, **build_kwargs)
except Exception as e:
if version == "editable" and config.optional_editable_build.lower() == "true":
warnings.warn(f"Encountered build error:\n{e}")
else:
raise e
else:
log.info("Skipping build")

27 changes: 25 additions & 2 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import platform
import subprocess
import sys
import venv
import warnings
from pathlib import Path

import pytest
@@ -41,16 +43,37 @@ def foo(target_name, version, foo_bar=None, fizz_buzz=None):

config["skip-if-exists"] = ["foo", "bar"]
assert hook.initialize("standard", {})
del config["skip-if-exists"]

config["editable-build-kwargs"] = {"foo-bar": "2", "fizz_buzz": "3"}
assert hook.initialize("editable", {})

hook = JupyterBuildHook(tmp_path, config, {}, {}, tmp_path, "foo")
assert not hook.initialize("standard", {})

os.environ["SKIP_JUPYTER_BUILD"] = "1"
text = """
def foo(target_name, version, foo_bar=None, fizz_buzz=None):
raise RuntimeError('trigger error')
"""
test.write_text(text, encoding="utf-8")
# Force a re-import
del sys.modules["test"]

hook = JupyterBuildHook(tmp_path, config, {}, {}, tmp_path, "wheel")
with pytest.raises(RuntimeError):
hook.initialize("editable", {})

os.environ["SKIP_JUPYTER_BUILDER"] = "1"
assert not hook.initialize("standard", {})
del os.environ["SKIP_JUPYTER_BUILD"]
del os.environ["SKIP_JUPYTER_BUILDER"]

config["optional-editable-build"] = "true"
hook = JupyterBuildHook(tmp_path, config, {}, {}, tmp_path, "wheel")
with warnings.catch_warnings():
warnings.simplefilter("ignore")
assert hook.initialize("editable", {})

del sys.modules["test"]


HERE = Path(__file__).parent
2 changes: 2 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -53,6 +53,8 @@ def test_get_build_func(tmp_path):
with pytest.raises(AttributeError):
utils.get_build_func("test.bar")

del sys.modules["test"]


def test_should_skip(tmp_path):
assert not utils.should_skip("a")