Skip to content

Commit 5954f70

Browse files
authored
better test + more logs (#2)
* get this working on windows * more logs + better tests
1 parent 80aa4e0 commit 5954f70

File tree

5 files changed

+64
-43
lines changed

5 files changed

+64
-43
lines changed

hatch_build_scripts/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.3"
1+
__version__ = "0.0.4"

hatch_build_scripts/plugin.py

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
import logging
44
import os
55
import shutil
6-
from dataclasses import MISSING, dataclass, fields
6+
from collections.abc import Sequence
7+
from dataclasses import MISSING, asdict, dataclass, fields
78
from functools import cached_property
89
from pathlib import Path
910
from subprocess import run
10-
from typing import Any, Sequence
11+
from typing import Any
1112

1213
import pathspec
1314
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
1415

15-
logger = logging.getLogger(__name__)
16+
log = logging.getLogger(__name__)
17+
log_level = logging.getLevelName(os.getenv("HATCH_BUILD_SCRIPTS_LOG_LEVEL", "INFO"))
18+
log.setLevel(log_level)
1619

1720

1821
class BuildScriptsHook(BuildHookInterface):
@@ -30,28 +33,34 @@ def initialize(
3033
for script in all_scripts:
3134
if script.clean_out_dir:
3235
out_dir = Path(self.root, script.out_dir)
33-
logger.info(f"Cleaning {out_dir}")
36+
log.debug(f"Cleaning {out_dir}")
3437
shutil.rmtree(out_dir, ignore_errors=True)
3538
elif script.clean_artifacts:
3639
for out_file in script.out_files(self.root):
40+
log.debug(f"Cleaning {out_file}")
3741
out_file.unlink(missing_ok=True)
3842

3943
for script in all_scripts:
44+
log.debug(f"Script config: {asdict(script)}")
4045
work_dir = Path(self.root, script.work_dir)
4146
out_dir = Path(self.root, script.out_dir)
4247
out_dir.mkdir(parents=True, exist_ok=True)
4348

4449
for cmd in script.commands:
50+
log.info(f"Running command: {cmd}")
4551
run(cmd, cwd=str(work_dir), check=True, shell=True) # noqa: S602
4652

47-
logger.info(f"Copying artifacts to {out_dir}")
48-
for artifact_file in script.artifact_files():
49-
src_file = work_dir / artifact_file
50-
out_file = out_dir / artifact_file
53+
log.info(f"Copying artifacts to {out_dir}")
54+
for work_file in script.work_files(self.root, relative=True):
55+
src_file = work_dir / work_file
56+
out_file = out_dir / work_file
57+
log.debug(f"Copying {src_file} to {out_file}")
5158
if src_file not in created:
5259
out_file.parent.mkdir(parents=True, exist_ok=True)
5360
shutil.copyfile(src_file, out_file)
5461
created.add(out_file)
62+
else:
63+
log.debug(f"Skipping {src_file} - already exists")
5564

5665
build_data["artifacts"].append(str(out_dir.relative_to(self.root)))
5766

@@ -91,27 +100,32 @@ def __post_init__(self) -> None:
91100
self.out_dir = conv_path(self.out_dir)
92101
self.work_dir = conv_path(self.work_dir)
93102

94-
def work_files(self, root: str | Path) -> Sequence[Path]:
95-
"""Get the files that will be used by the script."""
96-
work_dir = Path(root, self.work_dir)
97-
if not work_dir.exists():
103+
def work_files(self, root: str | Path, *, relative: bool = False) -> Sequence[Path]:
104+
"""Get files in the work directory that match the artifacts spec."""
105+
abs_dir = Path(root, self.work_dir)
106+
if not abs_dir.exists():
98107
return []
99-
return [Path(root, self.work_dir, f) for f in self.artifacts_spec.match_tree(work_dir)]
100-
101-
def out_files(self, root: str | Path) -> Sequence[Path]:
102-
"""Get the files that will be created by the script."""
103-
out_dir = Path(root, self.out_dir)
104-
if not out_dir.exists():
108+
return [
109+
Path(f) if relative else abs_dir / f
110+
for f in self.artifacts_spec.match_tree(abs_dir)
111+
]
112+
113+
def out_files(self, root: str | Path, *, relative: bool = False) -> Sequence[Path]:
114+
"""Get files in the output directory that match the artifacts spec."""
115+
abs_dir = Path(root, self.out_dir)
116+
if not abs_dir.exists():
105117
return []
106-
return [Path(root, self.out_dir, f) for f in self.artifacts_spec.match_tree(out_dir)]
107-
108-
def artifact_files(self) -> Sequence[Path]:
109-
return [Path(conv_path(p)) for p in self.artifacts_spec.match_tree(self.work_dir)]
118+
return [
119+
Path(f) if relative else abs_dir / f
120+
for f in self.artifacts_spec.match_tree(abs_dir)
121+
]
110122

111123
@cached_property
112124
def artifacts_spec(self) -> pathspec.PathSpec:
113125
"""A pathspec for the artifacts."""
114-
return pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, self.artifacts)
126+
return pathspec.PathSpec.from_lines(
127+
pathspec.patterns.GitWildMatchPattern, self.artifacts
128+
)
115129

116130

117131
def dataclass_defaults(obj: Any) -> dict[str, Any]:

pyproject.toml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ style = [
6060
"ruff {args:.}",
6161
"black --check --diff {args:.}",
6262
]
63-
fmt = [
63+
fix = [
6464
"black {args:.}",
6565
"ruff --fix {args:.}",
6666
"style",
@@ -71,13 +71,11 @@ all = [
7171
]
7272

7373
[tool.black]
74-
target-version = ["py37"]
75-
line-length = 100
74+
target-version = ["py39"]
7675
skip-string-normalization = true
7776

7877
[tool.ruff]
79-
target-version = "py37"
80-
line-length = 100
78+
target-version = "py39"
8179
select = [
8280
"A",
8381
"ARG",
@@ -128,4 +126,4 @@ ban-relative-imports = "all"
128126

129127
[tool.ruff.per-file-ignores]
130128
# Tests can use magic values, assertions, and relative imports
131-
"tests/**/*" = ["PLR2004", "S101", "TID252"]
129+
"tests/**/*" = ["PLR2004", "S101", "TID252", "S603"]

tests/test_plugin.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,26 @@
44

55

66
def test_plugin(tmpdir):
7-
(tmpdir / "some-dir").mkdir()
8-
(tmpdir / "another-dir").mkdir()
7+
tmp_lib_dir = tmpdir / "lib"
8+
tmp_lib_dir.mkdir()
99

10-
some_dir_out = tmpdir / "some-dir-out"
10+
(tmp_lib_dir / "some-dir").mkdir()
11+
(tmp_lib_dir / "another-dir").mkdir()
12+
13+
some_dir_out = tmp_lib_dir / "some-dir-out"
1114
some_dir_out.mkdir()
1215
# we expect that this file will not be cleaned
1316
(some_dir_out / "module.py").write_text('print("hello")', "utf-8")
1417
# we expect that this file will be cleaned
1518
(some_dir_out / "f3.txt").write_text("this should be cleaned", "utf-8")
1619

17-
another_dir_out = tmpdir / "another-dir-out"
20+
another_dir_out = tmp_lib_dir / "another-dir-out"
1821
another_dir_out.mkdir()
1922
# we expect that this file will be cleaned
2023
(another_dir_out / "module.py").write_text('print("hello")', "utf-8")
2124

2225
proj = create_project(
23-
tmpdir,
26+
tmp_lib_dir,
2427
[
2528
OneScriptConfig(
2629
out_dir="fake",
@@ -52,10 +55,14 @@ def test_plugin(tmpdir):
5255

5356
proj.build()
5457

58+
extract_dir = tmpdir / "extract"
59+
extract_dir.mkdir()
60+
5561
with proj.dist() as dist:
56-
files = {file.filename for file in dist.filelist}
62+
dist.extractall(extract_dir)
63+
64+
assert (extract_dir / "fake" / "fake.txt").exists()
65+
assert (extract_dir / "some-dir-out" / "module.py").exists()
5766

58-
assert "fake/fake.txt" in files
59-
assert "some-dir-out/module.py" in files
60-
assert "another-dir-out/module.py" not in files
61-
assert "some-dir-out/f3.txt" not in files
67+
assert not (extract_dir / "some-dir-out" / "f3.txt").exists()
68+
assert not (extract_dir / "another-dir-out" / "module.py").exists()

tests/utils.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import subprocess
44
import sys
55
import zipfile
6+
from collections.abc import Iterator, Sequence
67
from contextlib import contextmanager
78
from dataclasses import asdict
89
from pathlib import Path
9-
from typing import Iterator, Sequence
1010

1111
import toml
1212

@@ -53,7 +53,7 @@ def __init__(self, path: Path) -> None:
5353

5454
def build(self) -> None:
5555
subprocess.run(
56-
[ # noqa: S603
56+
[
5757
sys.executable,
5858
"-m",
5959
"pip",
@@ -65,7 +65,9 @@ def build(self) -> None:
6565
check=True,
6666
)
6767
subprocess.run(
68-
[sys.executable, "-m", "hatch", "build"], cwd=self.path, check=True # noqa: S603
68+
[sys.executable, "-m", "hatch", "build"],
69+
cwd=self.path,
70+
check=True,
6971
)
7072

7173
@contextmanager

0 commit comments

Comments
 (0)