Skip to content

Commit c2e4ea9

Browse files
authored
Merge pull request #725 from tiran/update_extra_environ
feat: update_extra_environ hook
2 parents 8357c18 + 1e6cf9a commit c2e4ea9

File tree

9 files changed

+136
-43
lines changed

9 files changed

+136
-43
lines changed

docs/hooks.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,25 @@ functions with default implementations, so it is only necessary to
2626
implement the functions needed to make it possible to build the
2727
package.
2828

29+
Package settings hooks
30+
----------------------
31+
32+
.. py:currentmodule:: fromager.packagesettings
33+
34+
.. autofromagerhook:: default_update_extra_environ
35+
36+
The ``update_extra_environ`` can modify the extra environment variables
37+
from settings file with dynamic values. The hook must update the
38+
``extra_environ`` dict in-place.
39+
40+
The hook is called multiple times during a build. The ``version``
41+
argument is *None* for ``get_build_backend_dependencies`` and
42+
``get_build_sdist_dependencies``. For ``get_install_dependencies_of_sdist``,
43+
``build_sdist``, and ``build_wheel``, the ``version`` argument
44+
contains the resolved version.
45+
46+
.. versionadded:: 0.60
47+
2948
Dependency hooks
3049
----------------
3150

e2e/stevedore_override/build/lib/package_plugins/stevedore.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

e2e/stevedore_override/src/package_plugins/stevedore.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@
99
logger = logging.getLogger(__name__)
1010

1111

12+
def update_extra_environ(
13+
*,
14+
ctx: context.WorkContext,
15+
req: Requirement,
16+
version: Version | None,
17+
sdist_root_dir: pathlib.Path,
18+
extra_environ: dict[str, str],
19+
build_env: build_environment.BuildEnvironment,
20+
) -> None:
21+
"""Update extra_environ in-place"""
22+
logger.info("update_extra_environ resolved_version=%s", version)
23+
marker = ctx.work_dir / "update_extra_environ.txt"
24+
with marker.open(encoding="utf-8", mode="a") as f:
25+
f.write(f"{version}\n")
26+
return None
27+
28+
1229
def build_sdist(
1330
ctx: context.WorkContext,
1431
extra_environ: dict,

e2e/test_pep517_build_sdist.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ fromager \
4949

5050
EXPECTED_FILES="
5151
$OUTDIR/sdists-repo/builds/stevedore-*.tar.gz
52+
$OUTDIR/work-dir/update_extra_environ.txt
5253
"
5354

5455
pass=true

src/fromager/bootstrapper.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ def bootstrap(self, req: Requirement, req_type: RequirementType) -> Version:
324324
install_dependencies = dependencies.get_install_dependencies_of_sdist(
325325
ctx=self.ctx,
326326
req=req,
327+
version=resolved_version,
327328
sdist_root_dir=sdist_root_dir,
328329
build_env=build_env,
329330
)

src/fromager/dependencies.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@
1212
import tomlkit
1313
from packaging.metadata import Metadata
1414
from packaging.requirements import Requirement
15+
from packaging.version import Version
1516

16-
from . import build_environment, external_commands, overrides, requirements_file
17+
from . import (
18+
build_environment,
19+
external_commands,
20+
overrides,
21+
packagesettings,
22+
requirements_file,
23+
)
1724

1825
if typing.TYPE_CHECKING:
1926
from . import context
@@ -110,7 +117,13 @@ def get_build_backend_dependencies(
110117
logger.debug(
111118
f"file {build_backend_req_file} does not exist, getting dependencies from hook"
112119
)
113-
extra_environ = pbi.get_extra_environ(build_env=build_env)
120+
extra_environ = packagesettings.get_extra_environ(
121+
ctx=ctx,
122+
req=req,
123+
version=None,
124+
sdist_root_dir=sdist_root_dir,
125+
build_env=build_env,
126+
)
114127
orig_deps = overrides.find_and_invoke(
115128
req.name,
116129
"get_build_backend_dependencies",
@@ -175,7 +188,13 @@ def get_build_sdist_dependencies(
175188
logger.debug(
176189
f"file {build_sdist_req_file} does not exist, getting dependencies from hook"
177190
)
178-
extra_environ = pbi.get_extra_environ(build_env=build_env)
191+
extra_environ = packagesettings.get_extra_environ(
192+
ctx=ctx,
193+
req=req,
194+
version=None,
195+
sdist_root_dir=sdist_root_dir,
196+
build_env=build_env,
197+
)
179198
orig_deps = overrides.find_and_invoke(
180199
req.name,
181200
"get_build_sdist_dependencies",
@@ -227,6 +246,7 @@ def get_install_dependencies_of_sdist(
227246
*,
228247
ctx: context.WorkContext,
229248
req: Requirement,
249+
version: Version,
230250
sdist_root_dir: pathlib.Path,
231251
build_env: build_environment.BuildEnvironment,
232252
) -> set[Requirement]:
@@ -238,14 +258,21 @@ def get_install_dependencies_of_sdist(
238258
f"getting install requirements for {req} from sdist in {sdist_root_dir}"
239259
)
240260
pbi = ctx.package_build_info(req)
261+
extra_environ = packagesettings.get_extra_environ(
262+
ctx=ctx,
263+
req=req,
264+
version=version,
265+
sdist_root_dir=sdist_root_dir,
266+
build_env=build_env,
267+
)
241268
build_dir = pbi.build_dir(sdist_root_dir)
242-
extra_environ = pbi.get_extra_environ(build_env=build_env)
243269
orig_deps = overrides.find_and_invoke(
244270
req.name,
245271
"get_install_dependencies_of_sdist",
246272
default_get_install_dependencies_of_sdist,
247273
ctx=ctx,
248274
req=req,
275+
version=version,
249276
sdist_root_dir=sdist_root_dir,
250277
build_env=build_env,
251278
extra_environ=extra_environ,
@@ -264,6 +291,7 @@ def default_get_install_dependencies_of_sdist(
264291
*,
265292
ctx: context.WorkContext,
266293
req: Requirement,
294+
version: Version,
267295
sdist_root_dir: pathlib.Path,
268296
build_env: build_environment.BuildEnvironment,
269297
extra_environ: dict[str, str],

src/fromager/packagesettings.py

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import logging
24
import os
35
import pathlib
@@ -19,7 +21,7 @@
1921
from . import overrides
2022

2123
if typing.TYPE_CHECKING:
22-
from . import build_environment
24+
from . import build_environment, context
2325

2426
logger = logging.getLogger(__name__)
2527

@@ -419,7 +421,7 @@ def from_mapping(
419421
*,
420422
source: pathlib.Path | str | None,
421423
has_config: bool,
422-
) -> "PackageSettings":
424+
) -> PackageSettings:
423425
"""Load from a dict"""
424426
package = Package(canonicalize_name(package, validate=True))
425427
try:
@@ -436,7 +438,7 @@ def from_string(
436438
raw_yaml: str,
437439
*,
438440
source: pathlib.Path | str | None = None,
439-
) -> "PackageSettings":
441+
) -> PackageSettings:
440442
"""Load from raw yaml string"""
441443
parsed: typing.Any = yaml.safe_load(raw_yaml)
442444
if parsed is None:
@@ -449,7 +451,7 @@ def from_string(
449451
return cls.from_mapping(package, parsed, source=source, has_config=True)
450452

451453
@classmethod
452-
def from_file(cls, filename: pathlib.Path) -> "PackageSettings":
454+
def from_file(cls, filename: pathlib.Path) -> PackageSettings:
453455
"""Load from file
454456
455457
Raises :exc:`FileNotFound` when the file is not found.
@@ -461,7 +463,7 @@ def from_file(cls, filename: pathlib.Path) -> "PackageSettings":
461463
return cls.from_string(filename.stem, raw_yaml, source=filename)
462464

463465
@classmethod
464-
def from_default(cls, package: str | Package) -> "PackageSettings":
466+
def from_default(cls, package: str | Package) -> PackageSettings:
465467
"""Create a default package setting"""
466468
return cls.from_mapping(package, {}, source="default", has_config=False)
467469

@@ -558,7 +560,7 @@ class PackageBuildInfo:
558560
Public API for PackageSettings with i
559561
"""
560562

561-
def __init__(self, settings: "Settings", ps: PackageSettings) -> None:
563+
def __init__(self, settings: Settings, ps: PackageSettings) -> None:
562564
self._variant = typing.cast(Variant, settings.variant)
563565
self._patches_dir = settings.patches_dir
564566
self._variant_changelog = settings.variant_changelog()
@@ -763,7 +765,7 @@ def get_extra_environ(
763765
self,
764766
*,
765767
template_env: dict[str, str] | None = None,
766-
build_env: "build_environment.BuildEnvironment | None" = None,
768+
build_env: build_environment.BuildEnvironment | None = None,
767769
) -> dict[str, str]:
768770
"""Get extra environment variables for a variant
769771
@@ -894,7 +896,7 @@ def from_string(
894896
raw_yaml: str,
895897
*,
896898
source: pathlib.Path | str | None = None,
897-
) -> "SettingsFile":
899+
) -> SettingsFile:
898900
"""Load from raw yaml string"""
899901
parsed: typing.Any = yaml.safe_load(raw_yaml)
900902
if parsed is None:
@@ -916,7 +918,7 @@ def from_string(
916918
) from err
917919

918920
@classmethod
919-
def from_file(cls, filename: pathlib.Path) -> "SettingsFile":
921+
def from_file(cls, filename: pathlib.Path) -> SettingsFile:
920922
"""Load from file
921923
922924
Raises :exc:`FileNotFound` when the file is not found.
@@ -958,7 +960,7 @@ def from_files(
958960
variant: Variant | str,
959961
patches_dir: pathlib.Path,
960962
max_jobs: int | None,
961-
) -> "Settings":
963+
) -> Settings:
962964
"""Create Settings from settings.yaml and directory"""
963965
if settings_file.is_file():
964966
settings = SettingsFile.from_file(settings_file)
@@ -1082,3 +1084,41 @@ def all_variants(self) -> set[Variant]:
10821084
for ps in self._package_settings.values():
10831085
variants.update(ps.variants.keys())
10841086
return variants
1087+
1088+
1089+
def default_update_extra_environ(
1090+
*,
1091+
ctx: context.WorkContext,
1092+
req: Requirement,
1093+
version: Version | None,
1094+
sdist_root_dir: pathlib.Path,
1095+
extra_environ: dict[str, str],
1096+
build_env: build_environment.BuildEnvironment,
1097+
) -> None:
1098+
"""Update extra_environ in-place"""
1099+
return None
1100+
1101+
1102+
def get_extra_environ(
1103+
*,
1104+
ctx: context.WorkContext,
1105+
req: Requirement,
1106+
version: Version | None,
1107+
sdist_root_dir: pathlib.Path,
1108+
build_env: build_environment.BuildEnvironment,
1109+
) -> dict[str, str]:
1110+
"""Get extra environment variables from settings and update hook"""
1111+
pbi = ctx.package_build_info(req)
1112+
extra_environ = pbi.get_extra_environ(build_env=build_env)
1113+
overrides.find_and_invoke(
1114+
req.name,
1115+
"update_extra_environ",
1116+
default_update_extra_environ,
1117+
ctx=ctx,
1118+
req=req,
1119+
version=version,
1120+
sdist_root_dir=sdist_root_dir,
1121+
extra_environ=extra_environ,
1122+
build_env=build_env,
1123+
)
1124+
return extra_environ

src/fromager/sources.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
gitutils,
2323
metrics,
2424
overrides,
25+
packagesettings,
2526
pyproject,
2627
requirements_file,
2728
resolver,
@@ -568,7 +569,13 @@ def build_sdist(
568569
build_dir = pbi.build_dir(sdist_root_dir)
569570

570571
logger.info(f"building {ctx.variant} source distribution for {req} in {build_dir}")
571-
extra_environ = pbi.get_extra_environ(build_env=build_env)
572+
extra_environ = packagesettings.get_extra_environ(
573+
ctx=ctx,
574+
req=req,
575+
version=version,
576+
sdist_root_dir=sdist_root_dir,
577+
build_env=build_env,
578+
)
572579
if req.url:
573580
# The default approach to making an sdist is to make a tarball from the
574581
# source directory, since most of the time we got the source directory

src/fromager/wheels.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
external_commands,
2525
metrics,
2626
overrides,
27+
packagesettings,
2728
requirements_file,
2829
resolver,
2930
sources,
@@ -270,7 +271,13 @@ def build_wheel(
270271

271272
# add package and variant env vars, package's parallel job vars, and
272273
# build_env's virtual env vars.
273-
extra_environ = pbi.get_extra_environ(build_env=build_env)
274+
extra_environ = packagesettings.get_extra_environ(
275+
ctx=ctx,
276+
req=req,
277+
version=version,
278+
sdist_root_dir=sdist_root_dir,
279+
build_env=build_env,
280+
)
274281

275282
if (
276283
pbi.build_ext_parallel

0 commit comments

Comments
 (0)