builder: parametrize package type

and fix a few cases of builders that didn't inherit from
BuilderWithDefaults
This commit is contained in:
Harmen Stoppels 2025-04-16 10:44:20 +02:00
parent b932c14008
commit cdc67d6105
23 changed files with 38 additions and 29 deletions

View File

@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
from typing import List
from typing import Generic, List
import llnl.util.lang
@ -127,7 +127,7 @@ def execute_install_time_tests(builder: spack.builder.Builder):
builder.pkg.tester.phase_tests(builder, "install", builder.install_time_test_callbacks)
class BuilderWithDefaults(spack.builder.Builder):
class BuilderWithDefaults(Generic[spack.builder.B], spack.builder.Builder[spack.builder.B]):
"""Base class for all specific builders with common callbacks registered."""
# Check that self.prefix is there after installation

View File

@ -79,7 +79,7 @@ def with_or_without(self, *args, **kwargs):
@spack.builder.builder("autotools")
class AutotoolsBuilder(BuilderWithDefaults):
class AutotoolsBuilder(BuilderWithDefaults[AutotoolsPackage]):
"""The autotools builder encodes the default way of installing software built
with autotools. It has four phases that can be overridden, if need be:

View File

@ -5,6 +5,8 @@
import spack.directives
import spack.package_base
from ._checks import BuilderWithDefaults
class BundlePackage(spack.package_base.PackageBase):
"""General purpose bundle, or no-code, package class."""
@ -23,7 +25,7 @@ class BundlePackage(spack.package_base.PackageBase):
@spack.builder.builder("bundle")
class BundleBuilder(spack.builder.Builder):
class BundleBuilder(BuilderWithDefaults[BundlePackage]):
phases = ("install",)
def install(self, pkg, spec, prefix):

View File

@ -30,7 +30,7 @@ class CargoPackage(spack.package_base.PackageBase):
@spack.builder.builder("cargo")
class CargoBuilder(BuilderWithDefaults):
class CargoBuilder(BuilderWithDefaults[CargoPackage]):
"""The Cargo builder encodes the most common way of building software with
a rust Cargo.toml file. It has two phases that can be overridden, if need be:

View File

@ -284,7 +284,7 @@ def define_from_variant(self, cmake_var: str, variant: Optional[str] = None) ->
@spack.builder.builder("cmake")
class CMakeBuilder(BuilderWithDefaults):
class CMakeBuilder(BuilderWithDefaults[CMakePackage]):
"""The cmake builder encodes the default way of building software with CMake. IT
has three phases that can be overridden:

View File

@ -28,7 +28,7 @@ class Package(spack.package_base.PackageBase):
@spack.builder.builder("generic")
class GenericBuilder(BuilderWithDefaults):
class GenericBuilder(BuilderWithDefaults[Package]):
"""A builder for a generic build system, that require packagers
to implement an "install" phase.
"""

View File

@ -33,7 +33,7 @@ class GoPackage(spack.package_base.PackageBase):
@spack.builder.builder("go")
class GoBuilder(BuilderWithDefaults):
class GoBuilder(BuilderWithDefaults[GoPackage]):
"""The Go builder encodes the most common way of building software with
a golang go.mod file. It has two phases that can be overridden, if need be:

View File

@ -14,6 +14,8 @@
from spack.directives import build_system, depends_on, extends
from spack.multimethod import when
from ._checks import BuilderWithDefaults
class LuaPackage(spack.package_base.PackageBase):
"""Specialized class for lua packages"""
@ -49,7 +51,7 @@ def luarocks(self):
@spack.builder.builder("lua")
class LuaBuilder(spack.builder.Builder):
class LuaBuilder(BuilderWithDefaults[LuaPackage]):
phases = ("unpack", "generate_luarocks_config", "preprocess", "install")
#: Names associated with package methods in the old build-system format

View File

@ -38,7 +38,7 @@ class MakefilePackage(spack.package_base.PackageBase):
@spack.builder.builder("makefile")
class MakefileBuilder(BuilderWithDefaults):
class MakefileBuilder(BuilderWithDefaults[MakefilePackage]):
"""The Makefile builder encodes the most common way of building software with
Makefiles. It has three phases that can be overridden, if need be:

View File

@ -35,7 +35,7 @@ class MavenPackage(spack.package_base.PackageBase):
@spack.builder.builder("maven")
class MavenBuilder(BuilderWithDefaults):
class MavenBuilder(BuilderWithDefaults[MavenPackage]):
"""The Maven builder encodes the default way to build software with Maven.
It has two phases that can be overridden, if need be:

View File

@ -67,7 +67,7 @@ def flags_to_build_system_args(self, flags):
@spack.builder.builder("meson")
class MesonBuilder(BuilderWithDefaults):
class MesonBuilder(BuilderWithDefaults[MesonPackage]):
"""The Meson builder encodes the default way to build software with Meson.
The builder has three phases that can be overridden, if need be:

View File

@ -27,7 +27,7 @@ class MSBuildPackage(spack.package_base.PackageBase):
@spack.builder.builder("msbuild")
class MSBuildBuilder(BuilderWithDefaults):
class MSBuildBuilder(BuilderWithDefaults[MSBuildPackage]):
"""The MSBuild builder encodes the most common way of building software with
Mircosoft's MSBuild tool. It has two phases that can be overridden, if need be:

View File

@ -27,7 +27,7 @@ class NMakePackage(spack.package_base.PackageBase):
@spack.builder.builder("nmake")
class NMakeBuilder(BuilderWithDefaults):
class NMakeBuilder(BuilderWithDefaults[NMakePackage]):
"""The NMake builder encodes the most common way of building software with
Mircosoft's NMake tool. It has two phases that can be overridden, if need be:

View File

@ -31,7 +31,7 @@ class OctavePackage(spack.package_base.PackageBase):
@spack.builder.builder("octave")
class OctaveBuilder(BuilderWithDefaults):
class OctaveBuilder(BuilderWithDefaults[OctavePackage]):
"""The octave builder provides the following phases that can be overridden:
1. :py:meth:`~.OctaveBuilder.install`

View File

@ -89,7 +89,7 @@ def test_use(self):
@spack.builder.builder("perl")
class PerlBuilder(BuilderWithDefaults):
class PerlBuilder(BuilderWithDefaults[PerlPackage]):
"""The perl builder provides four phases that can be overridden, if required:
1. :py:meth:`~.PerlBuilder.configure`

View File

@ -428,7 +428,7 @@ def libs(self) -> LibraryList:
@spack.builder.builder("python_pip")
class PythonPipBuilder(BuilderWithDefaults):
class PythonPipBuilder(BuilderWithDefaults[PythonPackage]):
phases = ("install",)
#: Names associated with package methods in the old build-system format

View File

@ -33,7 +33,7 @@ class QMakePackage(spack.package_base.PackageBase):
@spack.builder.builder("qmake")
class QMakeBuilder(BuilderWithDefaults):
class QMakeBuilder(BuilderWithDefaults[QMakePackage]):
"""The qmake builder provides three phases that can be overridden:
1. :py:meth:`~.QMakeBuilder.qmake`

View File

@ -18,6 +18,8 @@
from spack.util.environment import env_flag
from spack.util.executable import Executable, ProcessError
from ._checks import BuilderWithDefaults
def _homepage(cls: "RacketPackage") -> Optional[str]:
if cls.racket_name:
@ -47,7 +49,7 @@ class RacketPackage(PackageBase):
@spack.builder.builder("racket")
class RacketBuilder(spack.builder.Builder):
class RacketBuilder(BuilderWithDefaults[RacketPackage]):
"""The Racket builder provides an ``install`` phase that can be overridden."""
phases = ("install",)

View File

@ -29,7 +29,7 @@ class RubyPackage(spack.package_base.PackageBase):
@spack.builder.builder("ruby")
class RubyBuilder(BuilderWithDefaults):
class RubyBuilder(BuilderWithDefaults[RubyPackage]):
"""The Ruby builder provides two phases that can be overridden if required:
#. :py:meth:`~.RubyBuilder.build`

View File

@ -30,7 +30,7 @@ class SConsPackage(spack.package_base.PackageBase):
@spack.builder.builder("scons")
class SConsBuilder(BuilderWithDefaults):
class SConsBuilder(BuilderWithDefaults[SConsPackage]):
"""The Scons builder provides the following phases that can be overridden:
1. :py:meth:`~.SConsBuilder.build`

View File

@ -106,7 +106,7 @@ def test_imports(self):
@spack.builder.builder("sip")
class SIPBuilder(BuilderWithDefaults):
class SIPBuilder(BuilderWithDefaults[SIPPackage]):
"""The SIP builder provides the following phases that can be overridden:
* configure

View File

@ -32,7 +32,7 @@ class WafPackage(spack.package_base.PackageBase):
@spack.builder.builder("waf")
class WafBuilder(BuilderWithDefaults):
class WafBuilder(BuilderWithDefaults[WafPackage]):
"""The WAF builder provides the following phases that can be overridden:
* configure

View File

@ -5,7 +5,7 @@
import collections.abc
import copy
import functools
from typing import Dict, List, Optional, Tuple, Type
from typing import Dict, Generic, List, Optional, Tuple, Type, TypeVar
import spack.error
import spack.multimethod
@ -393,7 +393,10 @@ def copy(self):
return copy.deepcopy(self)
class BaseBuilder(metaclass=BuilderMeta):
B = TypeVar("B", bound=spack.package_base.PackageBase)
class BaseBuilder(Generic[B], metaclass=BuilderMeta):
"""An interface for builders, without any phases defined. This class is exposed in the package
API, so that packagers can create a single class to define ``setup_build_environment`` and
``@run_before`` and ``@run_after`` callbacks that can be shared among different builders.
@ -402,7 +405,7 @@ class BaseBuilder(metaclass=BuilderMeta):
.. code-block:: python
class AnyBuilder(BaseBuilder):
class AnyBuilder(BaseBuilder[AnyPackage]):
@run_after("install")
def fixup_install(self):
# do something after the package is installed
@ -418,7 +421,7 @@ class AutotoolsBuilder(autotools.AutotoolsBuilder, AnyBuilder):
pass
"""
def __init__(self, pkg: spack.package_base.PackageBase) -> None:
def __init__(self, pkg: B) -> None:
self.pkg = pkg
@property
@ -484,7 +487,7 @@ def __str__(self):
return f'"{self.__class__.__name__}" builder for "{self.spec.format(fmt)}"'
class Builder(BaseBuilder, collections.abc.Sequence):
class Builder(Generic[B], BaseBuilder[B], collections.abc.Sequence):
"""A builder is a class that, given a package object (i.e. associated with concrete spec),
knows how to install it.
@ -511,7 +514,7 @@ class Builder(BaseBuilder, collections.abc.Sequence):
def archive_files(self) -> List[str]:
return []
def __init__(self, pkg: spack.package_base.PackageBase) -> None:
def __init__(self, pkg: B) -> None:
super().__init__(pkg)
self.callbacks = {}
for phase in self.phases: