Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit b4c63da

Browse files
committed
fixup! Run extensive tests in CI when relevant files change
1 parent 06e329c commit b4c63da

File tree

1 file changed

+50
-55
lines changed

1 file changed

+50
-55
lines changed

ci/calculate-exhaustive-matrix.py

Lines changed: 50 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,35 @@
1010
from dataclasses import dataclass
1111
from os import getenv
1212
from pathlib import Path
13+
from typing import TypedDict
1314

1415

1516
REPO_ROOT = Path(__file__).parent.parent
1617
GIT = ["git", "-C", REPO_ROOT]
1718

19+
# Don't run exhaustive tests if these files change, even if they contaiin a function
20+
# definition.
1821
IGNORE_FILES = [
1922
"src/math/support/",
2023
"src/libm_helper.rs",
2124
"src/math/arch/intrinsics.rs",
2225
]
23-
"""Don't run exhaustive tests if these files change, even if they contaiin a function
24-
definition."""
26+
27+
TYPES = ["f16", "f32", "f64", "f128"]
28+
29+
30+
class FunctionDef(TypedDict):
31+
"""Type for an entry in `function-definitions.json`"""
32+
33+
sources: list[str]
34+
type: str
2535

2636

2737
@dataclass
2838
class Context:
2939
gh_ref: str | None
3040
changed: list[Path]
31-
defs: dict[str, dict[str, list[str] | str]]
32-
"""A list of all available functions by name."""
41+
defs: dict[str, FunctionDef]
3342

3443
def __init__(self) -> None:
3544
self.gh_ref = getenv("GITHUB_REF")
@@ -44,85 +53,71 @@ def __init__(self) -> None:
4453

4554
def _init_change_list(self):
4655
"""Create a list of files that have been changed. This uses GITHUB_REF if
47-
available, otherwise a diff between `HEAD` and `master`."""
56+
available, otherwise a diff between `HEAD` and `master`.
57+
"""
4858

4959
# For pull requests, GitHub creates a ref `refs/pull/1234/merge` (1234 being
5060
# the PR number), and sets this as `GITHUB_REF`.
5161
ref = self.gh_ref
52-
if ref is not None:
53-
eprint(f"using ref `{ref}`")
54-
if "merge" not in ref:
55-
# If the ref is not for `merge` then we are not in PR CI
56-
eprint("No diff available for ref")
57-
return
58-
59-
# The ref is for a dummy merge commit. We can extract the merge base by
60-
# inspecting all parents (`^@`).
61-
merge_sha = sp.check_output(
62-
GIT + ["show-ref", "--hash", ref], text=True
63-
).strip()
64-
merge_log = sp.check_output(GIT + ["log", "-1", merge_sha], text=True)
65-
eprint(f"Merge:\n{merge_log}\n")
66-
67-
parents = (
68-
sp.check_output(GIT + ["rev-parse", f"{merge_sha}^@"], text=True)
69-
.strip()
70-
.splitlines()
71-
)
72-
assert len(parents) == 2, f"expected two-parent merge but got:\n{parents}"
73-
base = parents[0]
74-
incoming = parents[1]
75-
else:
76-
# When running locally, allow providing a rev via `MERGE_BASE`. Otherwise
77-
# assume `HEAD -> MASTER`
78-
base = getenv("MERGE_BASE")
79-
if base is None:
80-
base = sp.check_output(
81-
GIT + ["merge-base", "HEAD", "master"], text=True
82-
)
83-
incoming = "HEAD"
84-
85-
base = base.strip()
86-
incoming = incoming.strip()
62+
eprint(f"using ref `{ref}`")
63+
if ref is None or "merge" not in ref:
64+
# If the ref is not for `merge` then we are not in PR CI
65+
eprint("No diff available for ref")
66+
return
67+
68+
# The ref is for a dummy merge commit. We can extract the merge base by
69+
# inspecting all parents (`^@`).
70+
merge_sha = sp.check_output(
71+
GIT + ["show-ref", "--hash", ref], text=True
72+
).strip()
73+
merge_log = sp.check_output(GIT + ["log", "-1", merge_sha], text=True)
74+
eprint(f"Merge:\n{merge_log}\n")
75+
76+
parents = (
77+
sp.check_output(GIT + ["rev-parse", f"{merge_sha}^@"], text=True)
78+
.strip()
79+
.splitlines()
80+
)
81+
assert len(parents) == 2, f"expected two-parent merge but got:\n{parents}"
82+
base = parents[0].strip()
83+
incoming = parents[1].strip()
8784

8885
eprint(f"base: {base}, incoming: {incoming}")
8986
textlist = sp.check_output(
9087
GIT + ["diff", base, incoming, "--name-only"], text=True
9188
)
9289
self.changed = [Path(p) for p in textlist.splitlines()]
9390

91+
@staticmethod
92+
def _ignore_file(fname: str) -> bool:
93+
return any(fname.startswith(pfx) for pfx in IGNORE_FILES)
94+
9495
def changed_routines(self) -> dict[str, list[str]]:
9596
"""Create a list of routines for which one or more files have been updated,
9697
separated by type.
9798
"""
9899
routines = set()
99100
for name, meta in self.defs.items():
100-
def_list = meta["sources"]
101-
add = False
102-
for fname in def_list:
103-
# Skip if the file was not changed
104-
if Path(fname) not in self.changed:
105-
continue
106-
107-
# Don't update if changes to the file should be ignored
108-
if any(fname.startswith(pfx) for pfx in IGNORE_FILES):
109-
continue
101+
# Don't update if changes to the file should be ignored
102+
sources = (f for f in meta["sources"] if not self._ignore_file(f))
110103

111-
add = True
104+
# Select changed files
105+
changed = [f for f in sources if Path(f) in self.changed]
112106

113-
if add:
107+
if len(changed) > 0:
108+
eprint(f"changed files for {name}: {changed}")
114109
routines.add(name)
115110

116-
ret = {}
111+
ret = {ty: [] for ty in TYPES}
117112
for r in sorted(routines):
118-
ret.setdefault(self.defs[r]["type"], []).append(r)
113+
ret[self.defs[r]["type"]].append(r)
119114

120115
return ret
121116

122117
def make_workflow_output(self) -> str:
123118
changed = self.changed_routines()
124119
ret = []
125-
for ty in ["f16", "f32", "f64", "f128"]:
120+
for ty in TYPES:
126121
ty_changed = changed.get(ty, [])
127122
item = {
128123
"ty": ty,

0 commit comments

Comments
 (0)