Skip to content

Commit 1f4329d

Browse files
aepfliclaude
andcommitted
fix: sync test-harness files to source tree for dev and CI testing
The hatch build hook includes files in sdist/wheel via force_include, but tests run from the source tree. Add a sync script that copies files from the test-harness submodule, called by poe before test/cov. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Simon Schrottner <simon.schrottner@gmail.com>
1 parent ca2059a commit 1f4329d

4 files changed

Lines changed: 65 additions & 32 deletions

File tree

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/resolvers/process/flags.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ def __init__(
2525
super().__init__()
2626
self._emit_provider_configuration_changed = emit_provider_configuration_changed
2727

28-
def update(self, flags_data: dict) -> list[str]:
28+
def update(self, flags_data: dict) -> None:
2929
changed_keys = super().update(flags_data)
3030
if self._emit_provider_configuration_changed is not None:
3131
self._emit_provider_configuration_changed(
3232
ProviderEventDetails(
33-
flags_changed=list(self.flags.keys()),
33+
flags_changed=changed_keys,
3434
metadata=dict(self.flag_set_metadata),
3535
)
3636
)
37-
return changed_keys
Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,39 @@
11
"""Hatch build hook to copy test-harness evaluator files into the package."""
22

3+
import shutil
34
from pathlib import Path
45

56
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
67

7-
# Relative to the testkit package root
8-
TEST_HARNESS_EVALUATOR = Path(
9-
"../../providers/openfeature-provider-flagd/openfeature/test-harness/evaluator"
10-
)
11-
DEST_BASE = "src/openfeature/contrib/tools/flagd/testkit"
8+
DEST_BASE = Path("src/openfeature/contrib/tools/flagd/testkit")
129

1310

1411
class TestHarnessCopyHook(BuildHookInterface):
1512
PLUGIN_NAME = "test-harness-copy"
1613

1714
def initialize(self, version: str, build_data: dict) -> None:
1815
root = Path(self.root)
19-
src = root / TEST_HARNESS_EVALUATOR
20-
21-
# When building wheel from sdist, the submodule isn't available
22-
# but the files were already force-included in the sdist.
23-
if not src.exists():
24-
return
25-
26-
force = build_data.setdefault("force_include", {})
27-
28-
# Map submodule gherkin files -> package features/
29-
gherkin_src = src / "gherkin"
30-
for path in gherkin_src.rglob("*"):
31-
if path.is_file():
32-
rel = path.relative_to(gherkin_src)
33-
force[str(path)] = f"{DEST_BASE}/features/{rel}"
34-
35-
# Map submodule flag files -> package flag_data/
36-
flags_src = src / "flags"
37-
for path in flags_src.rglob("*"):
38-
if path.is_file():
39-
rel = path.relative_to(flags_src)
40-
force[str(path)] = f"{DEST_BASE}/flag_data/{rel}"
16+
features_dest = root / DEST_BASE / "features"
17+
flags_dest = root / DEST_BASE / "flag_data"
18+
19+
# Copy from submodule if files don't exist yet
20+
if not features_dest.exists() or not flags_dest.exists():
21+
src = (
22+
root
23+
/ "../../providers/openfeature-provider-flagd"
24+
/ "openfeature/test-harness/evaluator"
25+
)
26+
if src.exists():
27+
if not features_dest.exists():
28+
shutil.copytree(src / "gherkin", features_dest)
29+
if not flags_dest.exists():
30+
shutil.copytree(src / "flags", flags_dest)
31+
32+
# Force-include gitignored files into both sdist and wheel
33+
if features_dest.exists() and flags_dest.exists():
34+
force = build_data.setdefault("force_include", {})
35+
for dest_dir in (features_dest, flags_dest):
36+
for path in dest_dir.rglob("*"):
37+
if path.is_file():
38+
rel = str(path.relative_to(root))
39+
force[rel] = rel
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Copy test-harness evaluator files into the package source tree.
2+
3+
Used by `poe sync-test-harness` for local development and CI testing.
4+
The hatch build hook (hatch_build.py) handles inclusion in wheel/sdist.
5+
"""
6+
7+
import shutil
8+
from pathlib import Path
9+
10+
ROOT = Path(__file__).parent
11+
TEST_HARNESS_EVALUATOR = (
12+
ROOT / "../../providers/openfeature-provider-flagd/openfeature/test-harness/evaluator"
13+
).resolve()
14+
DEST_BASE = ROOT / "src/openfeature/contrib/tools/flagd/testkit"
15+
16+
17+
def sync() -> None:
18+
if not TEST_HARNESS_EVALUATOR.exists():
19+
msg = (
20+
f"Test harness evaluator not found at {TEST_HARNESS_EVALUATOR}. "
21+
"Make sure submodules are initialized."
22+
)
23+
raise FileNotFoundError(msg)
24+
25+
for src_name, dest_name in [("gherkin", "features"), ("flags", "flag_data")]:
26+
src = TEST_HARNESS_EVALUATOR / src_name
27+
dest = DEST_BASE / dest_name
28+
if dest.exists():
29+
shutil.rmtree(dest)
30+
shutil.copytree(src, dest)
31+
32+
33+
if __name__ == "__main__":
34+
sync()

tools/openfeature-flagd-api-testkit/pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ disallow_any_generics = false
6868
omit = ["tests/**"]
6969

7070
[tool.poe.tasks]
71-
test = "pytest tests"
72-
test-cov = "coverage run -m pytest tests"
71+
sync-test-harness = "python hatch_build_sync.py"
72+
test = ["sync-test-harness", {cmd = "pytest tests"}]
73+
test-cov = ["sync-test-harness", {cmd = "coverage run -m pytest tests"}]
7374
cov-report = "coverage xml"
7475
cov = [
7576
"test-cov",

0 commit comments

Comments
 (0)