Skip to content

Commit cd3be8a

Browse files
committed
feat: from-cmake for overrides
Signed-off-by: Henry Schreiner <[email protected]>
1 parent c299548 commit cd3be8a

File tree

5 files changed

+76
-3
lines changed

5 files changed

+76
-3
lines changed

Diff for: docs/configuration.md

+2
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,8 @@ take several values, including several based on [PEP 508][]:
713713
`on`, `yes`, `y`, `t`, or a number more than 0.
714714
- `state`: The state of the build, one of `sdist`, `wheel`, `editable`,
715715
`metadata_wheel`, and `metadata_editable`. Takes a regex.
716+
- `from-sdist`: This will be true if the `PKG-INFO` file exists, that is, if this is
717+
coming from an SDist. Takes a bool.
716718

717719
At least one must be provided. Then you can specify any collection of valid
718720
options, and those will override if all the items in the `if` are true. They

Diff for: src/scikit_build_core/resources/scikit-build.schema.json

+4
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,10 @@
624624
"type": "string",
625625
"description": "The state of the build, one of `sdist`, `wheel`, `editable`, `metadata_wheel`, and `metadata_editable`. Takes a regex."
626626
},
627+
"from-sdist": {
628+
"type": "boolean",
629+
"description": "Whether the build is from an sdist."
630+
},
627631
"env": {
628632
"type": "object",
629633
"patternProperties": {

Diff for: src/scikit_build_core/settings/skbuild_read_settings.py

+26-3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def override_match(
7171
current_state: Literal[
7272
"sdist", "wheel", "editable", "metadata_wheel", "metadata_editable"
7373
],
74+
has_dist_info: bool,
7475
python_version: str | None = None,
7576
implementation_name: str | None = None,
7677
implementation_version: str | None = None,
@@ -79,8 +80,14 @@ def override_match(
7980
platform_node: str | None = None,
8081
env: dict[str, str] | None = None,
8182
state: str | None = None,
83+
from_sdist: bool | None = None,
8284
) -> bool:
85+
# This makes a matches list. A match is a string; if it's an empty string,
86+
# then it did not match. If it's not empty, it did match, and the string
87+
# will be printed in the logs - it's the match reason. If match_all is True,
88+
# then all must match, otherwise any match will count.
8389
matches = []
90+
8491
if current_env is None:
8592
current_env = os.environ
8693

@@ -124,6 +131,12 @@ def override_match(
124131
match_msg = regex_match(current_state, state)
125132
matches.append(match_msg)
126133

134+
if from_sdist is not None:
135+
if has_dist_info:
136+
matches.append("from sdist due to PKG-INFO" if from_sdist else "")
137+
else:
138+
matches.append("" if from_sdist else "not from sdist, no PKG-INFO")
139+
127140
if env:
128141
for key, value in env.items():
129142
if isinstance(value, bool):
@@ -272,8 +285,10 @@ def process_overides(
272285
env: Mapping[str, str] | None = None,
273286
) -> None:
274287
"""
275-
Process overrides into the main dictionary if they match. Modifies the input dictionary.
288+
Process overrides into the main dictionary if they match. Modifies the input
289+
dictionary. Must be run from the package directory.
276290
"""
291+
has_dist_info = Path("PKG-INFO").is_file()
277292

278293
for override in tool_skb.pop("overrides", []):
279294
matched = True
@@ -288,7 +303,11 @@ def process_overides(
288303
any_override = if_override.pop("any")
289304
select = {k.replace("-", "_"): v for k, v in any_override.items()}
290305
matched = override_match(
291-
match_all=False, current_env=env, current_state=state, **select
306+
match_all=False,
307+
current_env=env,
308+
current_state=state,
309+
has_dist_info=has_dist_info,
310+
**select,
292311
)
293312

294313
inherit_override = override.pop("inherit", {})
@@ -299,7 +318,11 @@ def process_overides(
299318
select = {k.replace("-", "_"): v for k, v in if_override.items()}
300319
if select:
301320
matched = matched and override_match(
302-
match_all=True, current_env=env, current_state=state, **select
321+
match_all=True,
322+
current_env=env,
323+
current_state=state,
324+
has_dist_info=has_dist_info,
325+
**select,
303326
)
304327
if matched:
305328
for key, value in override.items():

Diff for: src/scikit_build_core/settings/skbuild_schema.py

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ def generate_skbuild_schema(tool_name: str = "scikit-build") -> dict[str, Any]:
116116
"type": "string",
117117
"description": "The state of the build, one of `sdist`, `wheel`, `editable`, `metadata_wheel`, and `metadata_editable`. Takes a regex.",
118118
},
119+
"from-sdist": {
120+
"type": "boolean",
121+
"description": "Whether the build is from an sdist.",
122+
},
119123
"env": {
120124
"type": "object",
121125
"patternProperties": {

Diff for: tests/test_settings_overrides.py

+40
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,43 @@ def test_skbuild_overrides_inherit(inherit: str, tmp_path: Path):
490490
assert settings.wheel.exclude == ["xx", "yy", "x", "y"]
491491
assert settings.install.components == ["c", "d", "a", "b"]
492492
assert settings.cmake.define == {"a": "A", "b": "B", "c": "C"}
493+
494+
495+
@pytest.mark.parametrize("from_sdist", [True, False])
496+
def test_skbuild_overrides_from_sdist(
497+
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, from_sdist: bool
498+
):
499+
pyproject_toml = (
500+
tmp_path / ("from_sdist" if from_sdist else "not_from_sdist") / "pyproject.toml"
501+
)
502+
pyproject_toml.parent.mkdir(exist_ok=True)
503+
pyproject_toml.write_text(
504+
dedent(
505+
"""\
506+
[tool.scikit-build]
507+
cmake.version = ">=3.15"
508+
wheel.cmake = false
509+
sdist.cmake = false
510+
511+
[[tool.scikit-build.overrides]]
512+
if.from-sdist = false
513+
wheel.cmake = true
514+
515+
[[tool.scikit-build.overrides]]
516+
if.from-sdist = true
517+
sdist.cmake = true
518+
"""
519+
),
520+
encoding="utf-8",
521+
)
522+
523+
if from_sdist:
524+
pyproject_toml.parent.joinpath("PKG-INFO").touch(exist_ok=True)
525+
526+
monkeypatch.chdir(pyproject_toml.parent)
527+
528+
settings_reader = SettingsReader.from_file(pyproject_toml, state="wheel")
529+
settings = settings_reader.settings
530+
531+
assert settings.wheel.cmake != from_sdist
532+
assert settings.sdist.cmake == from_sdist

0 commit comments

Comments
 (0)