Compare commits

..

1 Commits

Author SHA1 Message Date
Harmen Stoppels
25c74506a3 cmake.py: include transitive run deps in CMAKE_PREFIX_PATH
- Run deps often need to be located during the build
- In cases like python-venv and python, where there's a direct build dep
  on both, but python-venv has a run dep on python, meaning we'd rather
  see python-venv in path before python topologically.
2024-11-28 18:27:15 +01:00
14 changed files with 258 additions and 446 deletions

View File

@@ -2773,6 +2773,22 @@ def prefixes(path):
return paths return paths
@system_path_filter
def md5sum(file):
"""Compute the MD5 sum of a file.
Args:
file (str): file to be checksummed
Returns:
MD5 sum of the file's content
"""
md5 = hashlib.md5()
with open(file, "rb") as f:
md5.update(f.read())
return md5.digest()
@system_path_filter @system_path_filter
def remove_directory_contents(dir): def remove_directory_contents(dir):
"""Remove all contents of a directory.""" """Remove all contents of a directory."""

View File

@@ -170,7 +170,7 @@ def get_cmake_prefix_path(pkg: spack.package_base.PackageBase) -> List[str]:
edges = traverse.traverse_topo_edges_generator( edges = traverse.traverse_topo_edges_generator(
traverse.with_artificial_edges([pkg.spec]), traverse.with_artificial_edges([pkg.spec]),
visitor=traverse.MixedDepthVisitor( visitor=traverse.MixedDepthVisitor(
direct=dt.BUILD | dt.TEST, transitive=dt.LINK, key=traverse.by_dag_hash direct=dt.BUILD | dt.TEST, transitive=dt.LINK | dt.RUN, key=traverse.by_dag_hash
), ),
key=traverse.by_dag_hash, key=traverse.by_dag_hash,
root=False, root=False,

View File

@@ -607,9 +607,6 @@ def test_stringify_version(version_str):
v.string = None v.string = None
assert str(v) == version_str assert str(v) == version_str
v.string = None
assert v.string == version_str
def test_len(): def test_len():
a = Version("1.2.3.4") a = Version("1.2.3.4")

View File

@@ -25,13 +25,11 @@
) )
from .version_types import ( from .version_types import (
ClosedOpenRange, ClosedOpenRange,
ConcreteVersion,
GitVersion, GitVersion,
StandardVersion, StandardVersion,
Version, Version,
VersionList, VersionList,
VersionRange, VersionRange,
VersionType,
_next_version, _next_version,
_prev_version, _prev_version,
from_string, from_string,
@@ -42,23 +40,21 @@
any_version: VersionList = VersionList([":"]) any_version: VersionList = VersionList([":"])
__all__ = [ __all__ = [
"ClosedOpenRange",
"ConcreteVersion",
"EmptyRangeError",
"GitVersion",
"StandardVersion",
"Version", "Version",
"VersionChecksumError",
"VersionError",
"VersionList",
"VersionLookupError",
"VersionRange", "VersionRange",
"VersionType",
"_next_version",
"_prev_version",
"any_version",
"from_string",
"infinity_versions",
"is_git_version",
"ver", "ver",
"from_string",
"is_git_version",
"infinity_versions",
"_prev_version",
"_next_version",
"VersionList",
"ClosedOpenRange",
"StandardVersion",
"GitVersion",
"VersionError",
"VersionChecksumError",
"VersionLookupError",
"EmptyRangeError",
"any_version",
] ]

View File

@@ -3,9 +3,10 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import numbers
import re import re
from bisect import bisect_left from bisect import bisect_left
from typing import Dict, Iterable, Iterator, List, Optional, Tuple, Union from typing import List, Optional, Tuple, Union
from spack.util.spack_yaml import syaml_dict from spack.util.spack_yaml import syaml_dict
@@ -31,44 +32,26 @@
class VersionStrComponent: class VersionStrComponent:
"""Internal representation of the string (non-integer) components of Spack versions.
Versions comprise string and integer components (see ``SEGMENT_REGEX`` above).
This represents a string component, which is either some component consisting only
of alphabetical characters, *or* a special "infinity version" like ``main``,
``develop``, ``master``, etc.
For speed, Spack versions are designed to map to Python tuples, so that we can use
Python's fast lexicographic tuple comparison on them. ``VersionStrComponent`` is
designed to work as a component in these version tuples, and as such must compare
directly with ``int`` or other ``VersionStrComponent`` objects.
"""
__slots__ = ["data"] __slots__ = ["data"]
data: Union[int, str] def __init__(self, data):
def __init__(self, data: Union[int, str]):
# int for infinity index, str for literal. # int for infinity index, str for literal.
self.data = data self.data: Union[int, str] = data
@staticmethod @staticmethod
def from_string(string: str) -> "VersionStrComponent": def from_string(string):
value: Union[int, str] = string
if len(string) >= iv_min_len: if len(string) >= iv_min_len:
try: try:
value = infinity_versions.index(string) string = infinity_versions.index(string)
except ValueError: except ValueError:
pass pass
return VersionStrComponent(value) return VersionStrComponent(string)
def __hash__(self) -> int: def __hash__(self):
return hash(self.data) return hash(self.data)
def __str__(self) -> str: def __str__(self):
return ( return (
("infinity" if self.data >= len(infinity_versions) else infinity_versions[self.data]) ("infinity" if self.data >= len(infinity_versions) else infinity_versions[self.data])
if isinstance(self.data, int) if isinstance(self.data, int)
@@ -78,61 +61,38 @@ def __str__(self) -> str:
def __repr__(self) -> str: def __repr__(self) -> str:
return f'VersionStrComponent("{self}")' return f'VersionStrComponent("{self}")'
def __eq__(self, other: object) -> bool: def __eq__(self, other):
return isinstance(other, VersionStrComponent) and self.data == other.data return isinstance(other, VersionStrComponent) and self.data == other.data
# ignore typing for certain parts of these methods b/c a) they are performance-critical, and def __lt__(self, other):
# b) mypy isn't smart enough to figure out that if l_inf and r_inf are the same, comparing lhs_inf = isinstance(self.data, int)
# self.data and other.data is type safe.
def __lt__(self, other: object) -> bool:
l_inf = isinstance(self.data, int)
if isinstance(other, int): if isinstance(other, int):
return not l_inf return not lhs_inf
r_inf = isinstance(other.data, int) # type: ignore rhs_inf = isinstance(other.data, int)
return (not l_inf and r_inf) if l_inf ^ r_inf else self.data < other.data # type: ignore return (not lhs_inf and rhs_inf) if lhs_inf ^ rhs_inf else self.data < other.data
def __gt__(self, other: object) -> bool: def __le__(self, other):
l_inf = isinstance(self.data, int)
if isinstance(other, int):
return l_inf
r_inf = isinstance(other.data, int) # type: ignore
return (l_inf and not r_inf) if l_inf ^ r_inf else self.data > other.data # type: ignore
def __le__(self, other: object) -> bool:
return self < other or self == other return self < other or self == other
def __ge__(self, other: object) -> bool: def __gt__(self, other):
lhs_inf = isinstance(self.data, int)
if isinstance(other, int):
return lhs_inf
rhs_inf = isinstance(other.data, int)
return (lhs_inf and not rhs_inf) if lhs_inf ^ rhs_inf else self.data > other.data
def __ge__(self, other):
return self > other or self == other return self > other or self == other
# Tuple types that make up the internal representation of StandardVersion. def parse_string_components(string: str) -> Tuple[tuple, tuple]:
# We use Tuples so that Python can quickly compare versions.
#: Version components are integers for numeric parts, VersionStrComponents for string parts.
VersionComponentTuple = Tuple[Union[int, VersionStrComponent], ...]
#: A Prerelease identifier is a constant for alpha/beta/rc/final and one optional number.
#: Most versions will have this set to ``(FINAL,)``. Prereleases will have some other
#: initial constant followed by a number, e.g. ``(RC, 1)``.
PrereleaseTuple = Tuple[int, ...]
#: Actual version tuple, including the split version number itself and the prerelease,
#: all represented as tuples.
VersionTuple = Tuple[VersionComponentTuple, PrereleaseTuple]
#: Separators from a parsed version.
SeparatorTuple = Tuple[str, ...]
def parse_string_components(string: str) -> Tuple[VersionTuple, SeparatorTuple]:
"""Parse a string into a ``VersionTuple`` and ``SeparatorTuple``."""
string = string.strip() string = string.strip()
if string and not VALID_VERSION.match(string): if string and not VALID_VERSION.match(string):
raise ValueError("Bad characters in version string: %s" % string) raise ValueError("Bad characters in version string: %s" % string)
segments = SEGMENT_REGEX.findall(string) segments = SEGMENT_REGEX.findall(string)
separators: Tuple[str] = tuple(m[2] for m in segments) separators = tuple(m[2] for m in segments)
prerelease: Tuple[int, ...] prerelease: Tuple[int, ...]
# <version>(alpha|beta|rc)<number> # <version>(alpha|beta|rc)<number>
@@ -149,150 +109,63 @@ def parse_string_components(string: str) -> Tuple[VersionTuple, SeparatorTuple]:
else: else:
prerelease = (FINAL,) prerelease = (FINAL,)
release: VersionComponentTuple = tuple( release = tuple(int(m[0]) if m[0] else VersionStrComponent.from_string(m[1]) for m in segments)
int(m[0]) if m[0] else VersionStrComponent.from_string(m[1]) for m in segments
)
return (release, prerelease), separators return (release, prerelease), separators
class VersionType: class ConcreteVersion:
"""Base type for all versions in Spack (ranges, lists, regular versions, and git versions). pass
Versions in Spack behave like sets, and support some basic set operations. There are
four subclasses of ``VersionType``:
* ``StandardVersion``: a single, concrete version, e.g. 3.4.5 or 5.4b0.
* ``GitVersion``: subclass of ``StandardVersion`` for handling git repositories.
* ``ClosedOpenRange``: an inclusive version range, closed or open, e.g. ``3.0:5.0``,
``3.0:``, or ``:5.0``
* ``VersionList``: An ordered list of any of the above types.
Notably, when Spack parses a version, it's always a range *unless* specified with
``@=`` to make it concrete.
"""
def intersection(self, other: "VersionType") -> "VersionType":
"""Any versions contained in both self and other, or empty VersionList if no overlap."""
raise NotImplementedError
def intersects(self, other: "VersionType") -> bool:
"""Whether self and other overlap."""
raise NotImplementedError
def overlaps(self, other: "VersionType") -> bool:
"""Whether self and other overlap (same as ``intersects()``)."""
return self.intersects(other)
def satisfies(self, other: "VersionType") -> bool:
"""Whether self is entirely contained in other."""
raise NotImplementedError
def union(self, other: "VersionType") -> "VersionType":
"""Return a VersionType containing self and other."""
raise NotImplementedError
# We can use SupportsRichComparisonT in Python 3.8 or later, but alas in 3.6 we need
# to write all the operators out
def __eq__(self, other: object) -> bool:
raise NotImplementedError
def __lt__(self, other: object) -> bool:
raise NotImplementedError
def __gt__(self, other: object) -> bool:
raise NotImplementedError
def __ge__(self, other: object) -> bool:
raise NotImplementedError
def __le__(self, other: object) -> bool:
raise NotImplementedError
def __hash__(self) -> int:
raise NotImplementedError
class ConcreteVersion(VersionType): def _stringify_version(versions: Tuple[tuple, tuple], separators: tuple) -> str:
"""Base type for versions that represents a single (non-range or list) version."""
def _stringify_version(versions: VersionTuple, separators: Tuple[str, ...]) -> str:
"""Create a string representation from version components."""
release, prerelease = versions release, prerelease = versions
string = ""
components = [f"{rel}{sep}" for rel, sep in zip(release, separators)] for i in range(len(release)):
string += f"{release[i]}{separators[i]}"
if prerelease[0] != FINAL: if prerelease[0] != FINAL:
components.append(PRERELEASE_TO_STRING[prerelease[0]]) string += f"{PRERELEASE_TO_STRING[prerelease[0]]}{separators[len(release)]}"
if len(prerelease) > 1: if len(prerelease) > 1:
components.append(separators[len(release)]) string += str(prerelease[1])
components.append(str(prerelease[1])) return string
return "".join(components)
class StandardVersion(ConcreteVersion): class StandardVersion(ConcreteVersion):
"""Class to represent versions""" """Class to represent versions"""
__slots__ = ["version", "_string", "separators"] __slots__ = ["version", "string", "separators"]
_string: str def __init__(self, string: Optional[str], version: Tuple[tuple, tuple], separators: tuple):
version: VersionTuple self.string = string
separators: Tuple[str, ...]
def __init__(self, string: str, version: VersionTuple, separators: Tuple[str, ...]):
"""Create a StandardVersion from a string and parsed version components.
Arguments:
string: The original version string, or ``""`` if the it is not available.
version: A tuple as returned by ``parse_string_components()``. Contains two tuples:
one with alpha or numeric components and another with prerelease components.
separators: separators parsed from the original version string.
If constructed with ``string=""``, the string will be lazily constructed from components
when ``str()`` is called.
"""
self._string = string
self.version = version self.version = version
self.separators = separators self.separators = separators
@staticmethod @staticmethod
def from_string(string: str) -> "StandardVersion": def from_string(string: str):
return StandardVersion(string, *parse_string_components(string)) return StandardVersion(string, *parse_string_components(string))
@staticmethod @staticmethod
def typemin() -> "StandardVersion": def typemin():
return _STANDARD_VERSION_TYPEMIN return _STANDARD_VERSION_TYPEMIN
@staticmethod @staticmethod
def typemax() -> "StandardVersion": def typemax():
return _STANDARD_VERSION_TYPEMAX return _STANDARD_VERSION_TYPEMAX
@property def __bool__(self):
def string(self) -> str:
if not self._string:
self._string = _stringify_version(self.version, self.separators)
return self._string
@string.setter
def string(self, string) -> None:
self._string = string
def __bool__(self) -> bool:
return True return True
def __eq__(self, other: object) -> bool: def __eq__(self, other):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.version == other.version return self.version == other.version
return False return False
def __ne__(self, other: object) -> bool: def __ne__(self, other):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.version != other.version return self.version != other.version
return True return True
def __lt__(self, other: object) -> bool: def __lt__(self, other):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.version < other.version return self.version < other.version
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
@@ -300,7 +173,7 @@ def __lt__(self, other: object) -> bool:
return self <= other.lo return self <= other.lo
return NotImplemented return NotImplemented
def __le__(self, other: object) -> bool: def __le__(self, other):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.version <= other.version return self.version <= other.version
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
@@ -308,7 +181,7 @@ def __le__(self, other: object) -> bool:
return self <= other.lo return self <= other.lo
return NotImplemented return NotImplemented
def __ge__(self, other: object) -> bool: def __ge__(self, other):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.version >= other.version return self.version >= other.version
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
@@ -316,25 +189,25 @@ def __ge__(self, other: object) -> bool:
return self > other.lo return self > other.lo
return NotImplemented return NotImplemented
def __gt__(self, other: object) -> bool: def __gt__(self, other):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.version > other.version return self.version > other.version
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
return self > other.lo return self > other.lo
return NotImplemented return NotImplemented
def __iter__(self) -> Iterator: def __iter__(self):
return iter(self.version[0]) return iter(self.version[0])
def __len__(self) -> int: def __len__(self):
return len(self.version[0]) return len(self.version[0])
def __getitem__(self, idx: Union[int, slice]): def __getitem__(self, idx):
cls = type(self) cls = type(self)
release = self.version[0] release = self.version[0]
if isinstance(idx, int): if isinstance(idx, numbers.Integral):
return release[idx] return release[idx]
elif isinstance(idx, slice): elif isinstance(idx, slice):
@@ -347,38 +220,45 @@ def __getitem__(self, idx: Union[int, slice]):
if string_arg: if string_arg:
string_arg.pop() # We don't need the last separator string_arg.pop() # We don't need the last separator
return cls.from_string("".join(string_arg)) string_arg = "".join(string_arg)
return cls.from_string(string_arg)
else: else:
return StandardVersion.from_string("") return StandardVersion.from_string("")
raise TypeError(f"{cls.__name__} indices must be integers or slices") message = "{cls.__name__} indices must be integers"
raise TypeError(message.format(cls=cls))
def __str__(self) -> str: def __str__(self):
return self.string return self.string or _stringify_version(self.version, self.separators)
def __repr__(self) -> str: def __repr__(self) -> str:
# Print indirect repr through Version(...) # Print indirect repr through Version(...)
return f'Version("{str(self)}")' return f'Version("{str(self)}")'
def __hash__(self) -> int: def __hash__(self):
# If this is a final release, do not hash the prerelease part for backward compat. # If this is a final release, do not hash the prerelease part for backward compat.
return hash(self.version if self.is_prerelease() else self.version[0]) return hash(self.version if self.is_prerelease() else self.version[0])
def __contains__(rhs, lhs) -> bool: def __contains__(rhs, lhs):
# We should probably get rid of `x in y` for versions, since # We should probably get rid of `x in y` for versions, since
# versions still have a dual interpretation as singleton sets # versions still have a dual interpretation as singleton sets
# or elements. x in y should be: is the lhs-element in the # or elements. x in y should be: is the lhs-element in the
# rhs-set. Instead this function also does subset checks. # rhs-set. Instead this function also does subset checks.
if isinstance(lhs, VersionType): if isinstance(lhs, (StandardVersion, ClosedOpenRange, VersionList)):
return lhs.satisfies(rhs) return lhs.satisfies(rhs)
raise TypeError(f"'in' not supported for instances of {type(lhs)}") raise ValueError(lhs)
def intersects(self, other: VersionType) -> bool: def intersects(self, other: Union["StandardVersion", "GitVersion", "ClosedOpenRange"]) -> bool:
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self == other return self == other
return other.intersects(self) return other.intersects(self)
def satisfies(self, other: VersionType) -> bool: def overlaps(self, other) -> bool:
return self.intersects(other)
def satisfies(
self, other: Union["ClosedOpenRange", "StandardVersion", "GitVersion", "VersionList"]
) -> bool:
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return False return False
@@ -391,19 +271,19 @@ def satisfies(self, other: VersionType) -> bool:
if isinstance(other, VersionList): if isinstance(other, VersionList):
return other.intersects(self) return other.intersects(self)
raise NotImplementedError return NotImplemented
def union(self, other: VersionType) -> VersionType: def union(self, other: Union["ClosedOpenRange", "StandardVersion"]):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self if self == other else VersionList([self, other]) return self if self == other else VersionList([self, other])
return other.union(self) return other.union(self)
def intersection(self, other: VersionType) -> VersionType: def intersection(self, other: Union["ClosedOpenRange", "StandardVersion"]):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self if self == other else VersionList() return self if self == other else VersionList()
return other.intersection(self) return other.intersection(self)
def isdevelop(self) -> bool: def isdevelop(self):
"""Triggers on the special case of the `@develop-like` version.""" """Triggers on the special case of the `@develop-like` version."""
return any( return any(
isinstance(p, VersionStrComponent) and isinstance(p.data, int) for p in self.version[0] isinstance(p, VersionStrComponent) and isinstance(p.data, int) for p in self.version[0]
@@ -424,7 +304,7 @@ def dotted_numeric_string(self) -> str:
return ".".join(str(v) for v in numeric) return ".".join(str(v) for v in numeric)
@property @property
def dotted(self) -> "StandardVersion": def dotted(self):
"""The dotted representation of the version. """The dotted representation of the version.
Example: Example:
@@ -438,7 +318,7 @@ def dotted(self) -> "StandardVersion":
return type(self).from_string(self.string.replace("-", ".").replace("_", ".")) return type(self).from_string(self.string.replace("-", ".").replace("_", "."))
@property @property
def underscored(self) -> "StandardVersion": def underscored(self):
"""The underscored representation of the version. """The underscored representation of the version.
Example: Example:
@@ -453,7 +333,7 @@ def underscored(self) -> "StandardVersion":
return type(self).from_string(self.string.replace(".", "_").replace("-", "_")) return type(self).from_string(self.string.replace(".", "_").replace("-", "_"))
@property @property
def dashed(self) -> "StandardVersion": def dashed(self):
"""The dashed representation of the version. """The dashed representation of the version.
Example: Example:
@@ -467,7 +347,7 @@ def dashed(self) -> "StandardVersion":
return type(self).from_string(self.string.replace(".", "-").replace("_", "-")) return type(self).from_string(self.string.replace(".", "-").replace("_", "-"))
@property @property
def joined(self) -> "StandardVersion": def joined(self):
"""The joined representation of the version. """The joined representation of the version.
Example: Example:
@@ -482,7 +362,7 @@ def joined(self) -> "StandardVersion":
self.string.replace(".", "").replace("-", "").replace("_", "") self.string.replace(".", "").replace("-", "").replace("_", "")
) )
def up_to(self, index: int) -> "StandardVersion": def up_to(self, index):
"""The version up to the specified component. """The version up to the specified component.
Examples: Examples:
@@ -602,7 +482,7 @@ def ref_version(self) -> StandardVersion:
) )
return self._ref_version return self._ref_version
def intersects(self, other: VersionType) -> bool: def intersects(self, other):
# For concrete things intersects = satisfies = equality # For concrete things intersects = satisfies = equality
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return self == other return self == other
@@ -612,14 +492,19 @@ def intersects(self, other: VersionType) -> bool:
return self.ref_version.intersects(other) return self.ref_version.intersects(other)
if isinstance(other, VersionList): if isinstance(other, VersionList):
return any(self.intersects(rhs) for rhs in other) return any(self.intersects(rhs) for rhs in other)
raise TypeError(f"'intersects()' not supported for instances of {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def intersection(self, other: VersionType) -> VersionType: def intersection(self, other):
if isinstance(other, ConcreteVersion): if isinstance(other, ConcreteVersion):
return self if self == other else VersionList() return self if self == other else VersionList()
return other.intersection(self) return other.intersection(self)
def satisfies(self, other: VersionType) -> bool: def overlaps(self, other) -> bool:
return self.intersects(other)
def satisfies(
self, other: Union["GitVersion", StandardVersion, "ClosedOpenRange", "VersionList"]
):
# Concrete versions mean we have to do an equality check # Concrete versions mean we have to do an equality check
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return self == other return self == other
@@ -629,9 +514,9 @@ def satisfies(self, other: VersionType) -> bool:
return self.ref_version.satisfies(other) return self.ref_version.satisfies(other)
if isinstance(other, VersionList): if isinstance(other, VersionList):
return any(self.satisfies(rhs) for rhs in other) return any(self.satisfies(rhs) for rhs in other)
raise TypeError(f"'satisfies()' not supported for instances of {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def __str__(self) -> str: def __str__(self):
s = f"git.{self.ref}" if self.has_git_prefix else self.ref s = f"git.{self.ref}" if self.has_git_prefix else self.ref
# Note: the solver actually depends on str(...) to produce the effective version. # Note: the solver actually depends on str(...) to produce the effective version.
# So when a lookup is attached, we require the resolved version to be printed. # So when a lookup is attached, we require the resolved version to be printed.
@@ -649,7 +534,7 @@ def __repr__(self):
def __bool__(self): def __bool__(self):
return True return True
def __eq__(self, other: object) -> bool: def __eq__(self, other):
# GitVersion cannot be equal to StandardVersion, otherwise == is not transitive # GitVersion cannot be equal to StandardVersion, otherwise == is not transitive
return ( return (
isinstance(other, GitVersion) isinstance(other, GitVersion)
@@ -657,10 +542,10 @@ def __eq__(self, other: object) -> bool:
and self.ref_version == other.ref_version and self.ref_version == other.ref_version
) )
def __ne__(self, other: object) -> bool: def __ne__(self, other):
return not self == other return not self == other
def __lt__(self, other: object) -> bool: def __lt__(self, other):
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return (self.ref_version, self.ref) < (other.ref_version, other.ref) return (self.ref_version, self.ref) < (other.ref_version, other.ref)
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
@@ -668,9 +553,9 @@ def __lt__(self, other: object) -> bool:
return self.ref_version < other return self.ref_version < other
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
return self.ref_version < other return self.ref_version < other
raise TypeError(f"'<' not supported between instances of {type(self)} and {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def __le__(self, other: object) -> bool: def __le__(self, other):
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return (self.ref_version, self.ref) <= (other.ref_version, other.ref) return (self.ref_version, self.ref) <= (other.ref_version, other.ref)
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
@@ -679,9 +564,9 @@ def __le__(self, other: object) -> bool:
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
# Equality is not a thing # Equality is not a thing
return self.ref_version < other return self.ref_version < other
raise TypeError(f"'<=' not supported between instances of {type(self)} and {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def __ge__(self, other: object) -> bool: def __ge__(self, other):
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return (self.ref_version, self.ref) >= (other.ref_version, other.ref) return (self.ref_version, self.ref) >= (other.ref_version, other.ref)
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
@@ -689,9 +574,9 @@ def __ge__(self, other: object) -> bool:
return self.ref_version >= other return self.ref_version >= other
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
return self.ref_version > other return self.ref_version > other
raise TypeError(f"'>=' not supported between instances of {type(self)} and {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def __gt__(self, other: object) -> bool: def __gt__(self, other):
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
return (self.ref_version, self.ref) > (other.ref_version, other.ref) return (self.ref_version, self.ref) > (other.ref_version, other.ref)
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
@@ -699,14 +584,14 @@ def __gt__(self, other: object) -> bool:
return self.ref_version >= other return self.ref_version >= other
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
return self.ref_version > other return self.ref_version > other
raise TypeError(f"'>' not supported between instances of {type(self)} and {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def __hash__(self): def __hash__(self):
# hashing should not cause version lookup # hashing should not cause version lookup
return hash(self.ref) return hash(self.ref)
def __contains__(self, other: object) -> bool: def __contains__(self, other):
raise NotImplementedError raise Exception("Not implemented yet")
@property @property
def ref_lookup(self): def ref_lookup(self):
@@ -764,7 +649,7 @@ def up_to(self, index) -> StandardVersion:
return self.ref_version.up_to(index) return self.ref_version.up_to(index)
class ClosedOpenRange(VersionType): class ClosedOpenRange:
def __init__(self, lo: StandardVersion, hi: StandardVersion): def __init__(self, lo: StandardVersion, hi: StandardVersion):
if hi < lo: if hi < lo:
raise EmptyRangeError(f"{lo}..{hi} is an empty range") raise EmptyRangeError(f"{lo}..{hi} is an empty range")
@@ -772,14 +657,14 @@ def __init__(self, lo: StandardVersion, hi: StandardVersion):
self.hi: StandardVersion = hi self.hi: StandardVersion = hi
@classmethod @classmethod
def from_version_range(cls, lo: StandardVersion, hi: StandardVersion) -> "ClosedOpenRange": def from_version_range(cls, lo: StandardVersion, hi: StandardVersion):
"""Construct ClosedOpenRange from lo:hi range.""" """Construct ClosedOpenRange from lo:hi range."""
try: try:
return ClosedOpenRange(lo, _next_version(hi)) return ClosedOpenRange(lo, _next_version(hi))
except EmptyRangeError as e: except EmptyRangeError as e:
raise EmptyRangeError(f"{lo}:{hi} is an empty range") from e raise EmptyRangeError(f"{lo}:{hi} is an empty range") from e
def __str__(self) -> str: def __str__(self):
# This simplifies 3.1:<3.2 to 3.1:3.1 to 3.1 # This simplifies 3.1:<3.2 to 3.1:3.1 to 3.1
# 3:3 -> 3 # 3:3 -> 3
hi_prev = _prev_version(self.hi) hi_prev = _prev_version(self.hi)
@@ -841,9 +726,9 @@ def __gt__(self, other):
def __contains__(rhs, lhs): def __contains__(rhs, lhs):
if isinstance(lhs, (ConcreteVersion, ClosedOpenRange, VersionList)): if isinstance(lhs, (ConcreteVersion, ClosedOpenRange, VersionList)):
return lhs.satisfies(rhs) return lhs.satisfies(rhs)
raise TypeError(f"'in' not supported between instances of {type(rhs)} and {type(lhs)}") raise ValueError(f"Unexpected type {type(lhs)}")
def intersects(self, other: VersionType) -> bool: def intersects(self, other: Union[ConcreteVersion, "ClosedOpenRange", "VersionList"]):
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
return self.lo <= other < self.hi return self.lo <= other < self.hi
if isinstance(other, GitVersion): if isinstance(other, GitVersion):
@@ -852,18 +737,23 @@ def intersects(self, other: VersionType) -> bool:
return (self.lo < other.hi) and (other.lo < self.hi) return (self.lo < other.hi) and (other.lo < self.hi)
if isinstance(other, VersionList): if isinstance(other, VersionList):
return any(self.intersects(rhs) for rhs in other) return any(self.intersects(rhs) for rhs in other)
raise TypeError(f"'intersects' not supported for instances of {type(other)}") raise ValueError(f"Unexpected type {type(other)}")
def satisfies(self, other: VersionType) -> bool: def satisfies(self, other: Union["ClosedOpenRange", ConcreteVersion, "VersionList"]):
if isinstance(other, ConcreteVersion): if isinstance(other, ConcreteVersion):
return False return False
if isinstance(other, ClosedOpenRange): if isinstance(other, ClosedOpenRange):
return not (self.lo < other.lo or other.hi < self.hi) return not (self.lo < other.lo or other.hi < self.hi)
if isinstance(other, VersionList): if isinstance(other, VersionList):
return any(self.satisfies(rhs) for rhs in other) return any(self.satisfies(rhs) for rhs in other)
raise TypeError(f"'satisfies()' not supported for instances of {type(other)}") raise ValueError(other)
def _union_if_not_disjoint(self, other: VersionType) -> Optional["ClosedOpenRange"]: def overlaps(self, other: Union["ClosedOpenRange", ConcreteVersion, "VersionList"]) -> bool:
return self.intersects(other)
def _union_if_not_disjoint(
self, other: Union["ClosedOpenRange", ConcreteVersion]
) -> Optional["ClosedOpenRange"]:
"""Same as union, but returns None when the union is not connected. This function is not """Same as union, but returns None when the union is not connected. This function is not
implemented for version lists as right-hand side, as that makes little sense.""" implemented for version lists as right-hand side, as that makes little sense."""
if isinstance(other, StandardVersion): if isinstance(other, StandardVersion):
@@ -880,9 +770,9 @@ def _union_if_not_disjoint(self, other: VersionType) -> Optional["ClosedOpenRang
else None else None
) )
raise TypeError(f"'union()' not supported for instances of {type(other)}") raise TypeError(f"Unexpected type {type(other)}")
def union(self, other: VersionType) -> VersionType: def union(self, other: Union["ClosedOpenRange", ConcreteVersion, "VersionList"]):
if isinstance(other, VersionList): if isinstance(other, VersionList):
v = other.copy() v = other.copy()
v.add(self) v.add(self)
@@ -891,51 +781,35 @@ def union(self, other: VersionType) -> VersionType:
result = self._union_if_not_disjoint(other) result = self._union_if_not_disjoint(other)
return result if result is not None else VersionList([self, other]) return result if result is not None else VersionList([self, other])
def intersection(self, other: VersionType) -> VersionType: def intersection(self, other: Union["ClosedOpenRange", ConcreteVersion]):
# range - version -> singleton or nothing. # range - version -> singleton or nothing.
if isinstance(other, ClosedOpenRange):
# range - range -> range or nothing.
max_lo = max(self.lo, other.lo)
min_hi = min(self.hi, other.hi)
return ClosedOpenRange(max_lo, min_hi) if max_lo < min_hi else VersionList()
if isinstance(other, ConcreteVersion): if isinstance(other, ConcreteVersion):
return other if self.intersects(other) else VersionList() return other if self.intersects(other) else VersionList()
raise TypeError(f"'intersection()' not supported for instances of {type(other)}") # range - range -> range or nothing.
max_lo = max(self.lo, other.lo)
min_hi = min(self.hi, other.hi)
return ClosedOpenRange(max_lo, min_hi) if max_lo < min_hi else VersionList()
class VersionList(VersionType): class VersionList:
"""Sorted, non-redundant list of Version and ClosedOpenRange elements.""" """Sorted, non-redundant list of Version and ClosedOpenRange elements."""
versions: List[VersionType] def __init__(self, vlist=None):
self.versions: List[Union[StandardVersion, GitVersion, ClosedOpenRange]] = []
def __init__(self, vlist: Optional[Union[str, VersionType, Iterable]] = None):
if vlist is None: if vlist is None:
self.versions = [] pass
elif isinstance(vlist, str): elif isinstance(vlist, str):
vlist = from_string(vlist) vlist = from_string(vlist)
if isinstance(vlist, VersionList): if isinstance(vlist, VersionList):
self.versions = vlist.versions self.versions = vlist.versions
else: else:
self.versions = [vlist] self.versions = [vlist]
else:
elif isinstance(vlist, (ConcreteVersion, ClosedOpenRange)):
self.versions = [vlist]
elif isinstance(vlist, VersionList):
self.versions = vlist[:]
elif isinstance(vlist, Iterable):
self.versions = []
for v in vlist: for v in vlist:
self.add(ver(v)) self.add(ver(v))
else: def add(self, item: Union[StandardVersion, GitVersion, ClosedOpenRange, "VersionList"]):
raise TypeError(f"Cannot construct VersionList from {type(vlist)}")
def add(self, item: VersionType) -> None:
if isinstance(item, (StandardVersion, GitVersion)): if isinstance(item, (StandardVersion, GitVersion)):
i = bisect_left(self, item) i = bisect_left(self, item)
# Only insert when prev and next are not intersected. # Only insert when prev and next are not intersected.
@@ -991,7 +865,7 @@ def concrete_range_as_version(self) -> Optional[ConcreteVersion]:
return v.lo return v.lo
return None return None
def copy(self) -> "VersionList": def copy(self):
return VersionList(self) return VersionList(self)
def lowest(self) -> Optional[StandardVersion]: def lowest(self) -> Optional[StandardVersion]:
@@ -1015,7 +889,7 @@ def preferred(self) -> Optional[StandardVersion]:
"""Get the preferred (latest) version in the list.""" """Get the preferred (latest) version in the list."""
return self.highest_numeric() or self.highest() return self.highest_numeric() or self.highest()
def satisfies(self, other: VersionType) -> bool: def satisfies(self, other) -> bool:
# This exploits the fact that version lists are "reduced" and normalized, so we can # This exploits the fact that version lists are "reduced" and normalized, so we can
# never have a list like [1:3, 2:4] since that would be normalized to [1:4] # never have a list like [1:3, 2:4] since that would be normalized to [1:4]
if isinstance(other, VersionList): if isinstance(other, VersionList):
@@ -1024,9 +898,9 @@ def satisfies(self, other: VersionType) -> bool:
if isinstance(other, (ConcreteVersion, ClosedOpenRange)): if isinstance(other, (ConcreteVersion, ClosedOpenRange)):
return all(lhs.satisfies(other) for lhs in self) return all(lhs.satisfies(other) for lhs in self)
raise TypeError(f"'satisfies()' not supported for instances of {type(other)}") raise ValueError(f"Unsupported type {type(other)}")
def intersects(self, other: VersionType) -> bool: def intersects(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
s = o = 0 s = o = 0
while s < len(self) and o < len(other): while s < len(self) and o < len(other):
@@ -1041,16 +915,19 @@ def intersects(self, other: VersionType) -> bool:
if isinstance(other, (ClosedOpenRange, StandardVersion)): if isinstance(other, (ClosedOpenRange, StandardVersion)):
return any(v.intersects(other) for v in self) return any(v.intersects(other) for v in self)
raise TypeError(f"'intersects()' not supported for instances of {type(other)}") raise ValueError(f"Unsupported type {type(other)}")
def to_dict(self) -> Dict: def overlaps(self, other) -> bool:
return self.intersects(other)
def to_dict(self):
"""Generate human-readable dict for YAML.""" """Generate human-readable dict for YAML."""
if self.concrete: if self.concrete:
return syaml_dict([("version", str(self[0]))]) return syaml_dict([("version", str(self[0]))])
return syaml_dict([("versions", [str(v) for v in self])]) return syaml_dict([("versions", [str(v) for v in self])])
@staticmethod @staticmethod
def from_dict(dictionary) -> "VersionList": def from_dict(dictionary):
"""Parse dict from to_dict.""" """Parse dict from to_dict."""
if "versions" in dictionary: if "versions" in dictionary:
return VersionList(dictionary["versions"]) return VersionList(dictionary["versions"])
@@ -1058,29 +935,27 @@ def from_dict(dictionary) -> "VersionList":
return VersionList([Version(dictionary["version"])]) return VersionList([Version(dictionary["version"])])
raise ValueError("Dict must have 'version' or 'versions' in it.") raise ValueError("Dict must have 'version' or 'versions' in it.")
def update(self, other: "VersionList") -> None: def update(self, other: "VersionList"):
self.add(other) for v in other.versions:
self.add(v)
def union(self, other: VersionType) -> VersionType: def union(self, other: "VersionList"):
result = self.copy() result = self.copy()
result.add(other) result.update(other)
return result return result
def intersection(self, other: VersionType) -> "VersionList": def intersection(self, other: "VersionList") -> "VersionList":
result = VersionList() result = VersionList()
if isinstance(other, VersionList): for lhs, rhs in ((self, other), (other, self)):
for lhs, rhs in ((self, other), (other, self)): for x in lhs:
for x in lhs: i = bisect_left(rhs.versions, x)
i = bisect_left(rhs.versions, x) if i > 0:
if i > 0: result.add(rhs[i - 1].intersection(x))
result.add(rhs[i - 1].intersection(x)) if i < len(rhs):
if i < len(rhs): result.add(rhs[i].intersection(x))
result.add(rhs[i].intersection(x)) return result
return result
else:
return self.intersection(VersionList(other))
def intersect(self, other: VersionType) -> bool: def intersect(self, other) -> bool:
"""Intersect this spec's list with other. """Intersect this spec's list with other.
Return True if the spec changed as a result; False otherwise Return True if the spec changed as a result; False otherwise
@@ -1090,7 +965,6 @@ def intersect(self, other: VersionType) -> bool:
self.versions = isection.versions self.versions = isection.versions
return changed return changed
# typing this and getitem are a pain in Python 3.6
def __contains__(self, other): def __contains__(self, other):
if isinstance(other, (ClosedOpenRange, StandardVersion)): if isinstance(other, (ClosedOpenRange, StandardVersion)):
i = bisect_left(self, other) i = bisect_left(self, other)
@@ -1104,52 +978,52 @@ def __contains__(self, other):
def __getitem__(self, index): def __getitem__(self, index):
return self.versions[index] return self.versions[index]
def __iter__(self) -> Iterator: def __iter__(self):
return iter(self.versions) return iter(self.versions)
def __reversed__(self) -> Iterator: def __reversed__(self):
return reversed(self.versions) return reversed(self.versions)
def __len__(self) -> int: def __len__(self):
return len(self.versions) return len(self.versions)
def __bool__(self) -> bool: def __bool__(self):
return bool(self.versions) return bool(self.versions)
def __eq__(self, other) -> bool: def __eq__(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
return self.versions == other.versions return self.versions == other.versions
return False return False
def __ne__(self, other) -> bool: def __ne__(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
return self.versions != other.versions return self.versions != other.versions
return False return False
def __lt__(self, other) -> bool: def __lt__(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
return self.versions < other.versions return self.versions < other.versions
return NotImplemented return NotImplemented
def __le__(self, other) -> bool: def __le__(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
return self.versions <= other.versions return self.versions <= other.versions
return NotImplemented return NotImplemented
def __ge__(self, other) -> bool: def __ge__(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
return self.versions >= other.versions return self.versions >= other.versions
return NotImplemented return NotImplemented
def __gt__(self, other) -> bool: def __gt__(self, other):
if isinstance(other, VersionList): if isinstance(other, VersionList):
return self.versions > other.versions return self.versions > other.versions
return NotImplemented return NotImplemented
def __hash__(self) -> int: def __hash__(self):
return hash(tuple(self.versions)) return hash(tuple(self.versions))
def __str__(self) -> str: def __str__(self):
if not self.versions: if not self.versions:
return "" return ""
@@ -1157,7 +1031,7 @@ def __str__(self) -> str:
f"={v}" if isinstance(v, StandardVersion) else str(v) for v in self.versions f"={v}" if isinstance(v, StandardVersion) else str(v) for v in self.versions
) )
def __repr__(self) -> str: def __repr__(self):
return str(self.versions) return str(self.versions)
@@ -1232,10 +1106,12 @@ def _next_version(v: StandardVersion) -> StandardVersion:
release = release[:-1] + (_next_version_str_component(release[-1]),) release = release[:-1] + (_next_version_str_component(release[-1]),)
else: else:
release = release[:-1] + (release[-1] + 1,) release = release[:-1] + (release[-1] + 1,)
components = [""] * (2 * len(release))
# Avoid constructing a string here for performance. Instead, pass "" to components[::2] = release
# StandardVersion to lazily stringify. components[1::2] = separators[: len(release)]
return StandardVersion("", (release, prerelease), separators) if prerelease_type != FINAL:
components.extend((PRERELEASE_TO_STRING[prerelease_type], prerelease[1]))
return StandardVersion("".join(str(c) for c in components), (release, prerelease), separators)
def _prev_version(v: StandardVersion) -> StandardVersion: def _prev_version(v: StandardVersion) -> StandardVersion:
@@ -1254,15 +1130,19 @@ def _prev_version(v: StandardVersion) -> StandardVersion:
release = release[:-1] + (_prev_version_str_component(release[-1]),) release = release[:-1] + (_prev_version_str_component(release[-1]),)
else: else:
release = release[:-1] + (release[-1] - 1,) release = release[:-1] + (release[-1] - 1,)
components = [""] * (2 * len(release))
components[::2] = release
components[1::2] = separators[: len(release)]
if prerelease_type != FINAL:
components.extend((PRERELEASE_TO_STRING[prerelease_type], *prerelease[1:]))
# Avoid constructing a string here for performance. Instead, pass "" to # this is only used for comparison functions, so don't bother making a string
# StandardVersion to lazily stringify. return StandardVersion(None, (release, prerelease), separators)
return StandardVersion("", (release, prerelease), separators)
def Version(string: Union[str, int]) -> ConcreteVersion: def Version(string: Union[str, int]) -> Union[GitVersion, StandardVersion]:
if not isinstance(string, (str, int)): if not isinstance(string, (str, int)):
raise TypeError(f"Cannot construct a version from {type(string)}") raise ValueError(f"Cannot construct a version from {type(string)}")
string = str(string) string = str(string)
if is_git_version(string): if is_git_version(string):
return GitVersion(string) return GitVersion(string)
@@ -1275,7 +1155,7 @@ def VersionRange(lo: Union[str, StandardVersion], hi: Union[str, StandardVersion
return ClosedOpenRange.from_version_range(lo, hi) return ClosedOpenRange.from_version_range(lo, hi)
def from_string(string: str) -> VersionType: def from_string(string) -> Union[VersionList, ClosedOpenRange, StandardVersion, GitVersion]:
"""Converts a string to a version object. This is private. Client code should use ver().""" """Converts a string to a version object. This is private. Client code should use ver()."""
string = string.replace(" ", "") string = string.replace(" ", "")
@@ -1304,17 +1184,17 @@ def from_string(string: str) -> VersionType:
return VersionRange(v, v) return VersionRange(v, v)
def ver(obj: Union[VersionType, str, list, tuple, int, float]) -> VersionType: def ver(obj) -> Union[VersionList, ClosedOpenRange, StandardVersion, GitVersion]:
"""Parses a Version, VersionRange, or VersionList from a string """Parses a Version, VersionRange, or VersionList from a string
or list of strings. or list of strings.
""" """
if isinstance(obj, VersionType): if isinstance(obj, (list, tuple)):
return obj return VersionList(obj)
elif isinstance(obj, str): elif isinstance(obj, str):
return from_string(obj) return from_string(obj)
elif isinstance(obj, (list, tuple)):
return VersionList(obj)
elif isinstance(obj, (int, float)): elif isinstance(obj, (int, float)):
return from_string(str(obj)) return from_string(str(obj))
elif isinstance(obj, (StandardVersion, GitVersion, ClosedOpenRange, VersionList)):
return obj
else: else:
raise TypeError("ver() can't convert %s to version!" % type(obj)) raise TypeError("ver() can't convert %s to version!" % type(obj))

View File

@@ -41,9 +41,6 @@ class Fpm(Package):
depends_on("curl", type="build") depends_on("curl", type="build")
depends_on("git@1.8.5:", type="build") depends_on("git@1.8.5:", type="build")
depends_on("c", type="build")
depends_on("fortran", type="build")
def setup_build_environment(self, env): def setup_build_environment(self, env):
if self.spec.satisfies("@0.4.0"): if self.spec.satisfies("@0.4.0"):
env.set("FPM_C_COMPILER", self.compiler.cc) env.set("FPM_C_COMPILER", self.compiler.cc)

View File

@@ -406,71 +406,44 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage, CompilerPackage):
when="@11.2.0", when="@11.2.0",
) )
# aarch64-darwin support from Iain Sandoe's branch # Apple M1 support, created from branch of Darwin maintainer for GCC:
# https://github.com/iains/gcc-11-branch
patch( patch(
"https://github.com/iains/gcc-14-branch/compare/04696df09633baf97cdbbdd6e9929b9d472161d3..gcc-14.2-darwin-r2.patch?full_index=1", "https://raw.githubusercontent.com/Homebrew/formula-patches/22dec3fc/gcc/gcc-11.3.0-arm.diff",
sha256="01ea668489f3f0fb2439060f6c333c4c17ef4c19c4c4e6e6aa4b8ea493e97685", sha256="e02006b7ec917cc1390645d95735a6a866caed0dfe506d5bef742f7862cab218",
when="@14.2.0 target=aarch64:", when="@11.3.0 target=aarch64:",
)
# https://github.com/iains/gcc-12-branch
patch(
"https://raw.githubusercontent.com/Homebrew/formula-patches/76677f2b/gcc/gcc-12.1.0-arm.diff",
sha256="a000f1d9cb1dd98c7c4ef00df31435cd5d712d2f9d037ddc044f8bf82a16cf35",
when="@12.1.0 target=aarch64:",
) )
patch( patch(
"https://github.com/iains/gcc-14-branch/compare/cd0059a1976303638cea95f216de129334fc04d1..gcc-14.1-darwin-r1.patch?full_index=1", "https://raw.githubusercontent.com/Homebrew/formula-patches/1d184289/gcc/gcc-12.2.0-arm.diff",
sha256="159cc2a1077ad5d9a3cca87880cd977b8202d8fb464a6ec7b53804475d21a682", sha256="a7843b5c6bf1401e40c20c72af69c8f6fc9754ae980bb4a5f0540220b3dcb62d",
when="@14.1.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-13-branch/compare/b71f1de6e9cf7181a288c0f39f9b1ef6580cf5c8..gcc-13.3-darwin-r1.patch?full_index=1",
sha256="d957520afc286ac46aa3c4bf9b64618d02ca0bf1466f32321b5d6beec6a396eb",
when="@13.3.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-13-branch/compare/c891d8dc23e1a46ad9f3e757d09e57b500d40044..gcc-13.2-darwin-r0.patch?full_index=1",
sha256="6a49d1074d7dd2e3b76e61613a0f143c668ed648fb8d9d48ed76a6b127815c88",
when="@13.2.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-13-branch/compare/cc035c5d8672f87dc8c2756d9f8367903aa72d93..gcc-13.1-darwin-r0.patch?full_index=1",
sha256="36d2c04d487edb6792b48dedae6936f8b864b6f969bd3fd03763e072d471c022",
when="@13.1.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-12-branch/compare/2bada4bc59bed4be34fab463bdb3c3ebfd2b41bb..gcc-12.4-darwin-r0.patch?full_index=1",
sha256="e242adf240a62ed3005da75a9e304bda980b84ce497f124b4bddc819ee821e2a",
when="@12.4.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-12-branch/compare/8fc1a49c9312b05d925b7d21f1d2145d70818151..gcc-12.3-darwin-r0.patch?full_index=1",
sha256="1ebac2010eb9ced33cf46a8d8378193671ed6830f262219aa3428de5bc9fd668",
when="@12.3.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-12-branch/compare/2ee5e4300186a92ad73f1a1a64cb918dc76c8d67..gcc-12.2-darwin-r0.patch?full_index=1",
sha256="16d5203ddb97cd43d6c1e9c34e0f681154aed1d127f2324b2a50006b92960cfd",
when="@12.2.0 target=aarch64:", when="@12.2.0 target=aarch64:",
) )
patch( patch(
"https://github.com/iains/gcc-12-branch/compare/1ea978e3066ac565a1ec28a96a4d61eaf38e2726..gcc-12.1-darwin-r1.patch?full_index=1", "https://raw.githubusercontent.com/Homebrew/formula-patches/5c206c47/gcc/gcc-13.1.0.diff",
sha256="b0a811e33c3451ebd1882eac4e2b4b32ce0b60cfa0b8ccf8c5fda7b24327c820", sha256="cb4e8a89387f748a744da0273025d0dc2e3c76780cc390b18ada704676afea11",
when="@12.1.0 target=aarch64:", when="@13.1.0 target=aarch64:",
)
patch(
"https://github.com/iains/gcc-11-branch/compare/5cc4c42a0d4de08715c2eef8715ad5b2e92a23b6..gcc-11.5-darwin-r0.patch?full_index=1",
sha256="6c92190a9acabd6be13bd42ca675f59f44be050a7121214abeaea99d898db30c",
when="@11.5.0 target=aarch64:",
) )
patch( patch(
"https://github.com/iains/gcc-11-branch/compare/ff4bf326d03e750a8d4905ea49425fe7d15a04b8..gcc-11.4-darwin-r0.patch?full_index=1", "https://raw.githubusercontent.com/Homebrew/formula-patches/3c5cbc8e9cf444a1967786af48e430588e1eb481/gcc/gcc-13.2.0.diff",
sha256="05810e5cdb052c06490f7d987c66a13d47ae7bd2eb285a3a881ad4aa6dd0d13f", sha256="2df7ef067871a30b2531a2013b3db661ec9e61037341977bfc451e30bf2c1035",
when="@11.4.0 target=aarch64:", when="@13.2.0 target=aarch64:",
) )
patch( patch(
"https://github.com/iains/gcc-11-branch/compare/2d280e7eafc086e9df85f50ed1a6526d6a3a204d..gcc-11.3-darwin-r2.patch?full_index=1", "https://raw.githubusercontent.com/Homebrew/formula-patches/82b5c1cd38826ab67ac7fc498a8fe74376a40f4a/gcc/gcc-14.1.0.diff",
sha256="a8097c232dfb21b0e02f3d99e3c3e47443db3982dafbb584938ac1a9a4afd33d", sha256="1529cff128792fe197ede301a81b02036c8168cb0338df21e4bc7aafe755305a",
when="@11.3.0 target=aarch64:", when="@14.1.0 target=aarch64:",
)
patch(
"https://raw.githubusercontent.com/Homebrew/formula-patches/f30c309442a60cfb926e780eae5d70571f8ab2cb/gcc/gcc-14.2.0-r2.diff",
sha256="6c0a4708f35ccf2275e6401197a491e3ad77f9f0f9ef5761860768fa6da14d3d",
when="@14.2.0 target=aarch64:",
) )
conflicts("+bootstrap", when="@11.3.0,13.1: target=aarch64:") conflicts("+bootstrap", when="@11.3.0,13.1: target=aarch64:")
# Use -headerpad_max_install_names in the build, # Use -headerpad_max_install_names in the build,

View File

@@ -46,8 +46,7 @@ class MiopenHip(CMakePackage):
conflicts("+asan", when="os=centos7") conflicts("+asan", when="os=centos7")
conflicts("+asan", when="os=centos8") conflicts("+asan", when="os=centos8")
depends_on("c", type="build") depends_on("cxx", type="build") # generated
depends_on("cxx", type="build")
depends_on("cmake@3.5:", type="build") depends_on("cmake@3.5:", type="build")
depends_on("pkgconfig", type="build") depends_on("pkgconfig", type="build")

View File

@@ -2,7 +2,6 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details. # Spack Project Developers. See the top-level COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
from spack.package import * from spack.package import *
@@ -51,35 +50,3 @@ def setup_build_environment(self, env):
def cythonize(self): def cythonize(self):
with working_dir(self.build_directory): with working_dir(self.build_directory):
python(join_path("conf", "cythonize.py")) python(join_path("conf", "cythonize.py"))
def create_mpi_config_file(self, cfg_fn):
"""
create mpi.cfg file introduced since version 4.0.0.
see https://mpi4py.readthedocs.io/en/stable/mpi4py.html#mpi4py.get_config
"""
mpi_spec = self.spec["mpi"]
include_dirs = mpi_spec.headers.directories
library_dirs = mpi_spec.libs.directories
with open(cfg_fn, "w") as cfg:
cfg.write("[mpi]\n")
cfg.write("mpi_dir = {}\n".format(mpi_spec.prefix))
cfg.write("mpicc = {}\n".format(mpi_spec.mpicc))
cfg.write("mpicxx = {}\n".format(mpi_spec.mpicxx))
cfg.write("\n")
cfg.write("## define_macros =\n")
cfg.write("## undef_macros =\n")
cfg.write("include_dirs = {}\n".format(include_dirs))
cfg.write("## libraries = mpi\n")
cfg.write("library_dirs = {}\n".format(library_dirs))
cfg.write("## runtime_library_dirs = %(mpi_dir)s/lib\n")
cfg.write("\n")
cfg.write("## extra_compile_args =\n")
cfg.write("## extra_link_args =\n")
cfg.write("## extra_objects =\n")
@run_after("install", when="@4:")
def install_cfg(self):
python_dir = join_path(self.prefix, python_platlib, "mpi4py")
cfg_fn = join_path(python_dir, "mpi.cfg")
if not os.path.isfile(cfg_fn):
self.create_mpi_config_file(cfg_fn)

View File

@@ -12,10 +12,7 @@ class PyNbdime(PythonPackage):
homepage = "https://nbdime.readthedocs.io/" homepage = "https://nbdime.readthedocs.io/"
pypi = "nbdime/nbdime-3.1.1.tar.gz" pypi = "nbdime/nbdime-3.1.1.tar.gz"
version("3.2.1", sha256="31409a30f848ffc6b32540697e82d5a0a1b84dcc32716ca74e78bcc4b457c453") version("3.1.1", sha256="67767320e971374f701a175aa59abd3a554723039d39fae908e72d16330d648b")
with default_args(deprecated=True):
# https://nvd.nist.gov/vuln/detail/CVE-2021-41134
version("3.1.1", sha256="67767320e971374f701a175aa59abd3a554723039d39fae908e72d16330d648b")
depends_on("python@3.6:", type=("build", "run")) depends_on("python@3.6:", type=("build", "run"))
depends_on("py-setuptools@40.8.0:", type="build") depends_on("py-setuptools@40.8.0:", type="build")

View File

@@ -25,12 +25,6 @@ class PyPip(Package, PythonExtension):
license("MIT") license("MIT")
version("24.3.1", sha256="3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed")
version("24.2", sha256="2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2")
version("24.1.2", sha256="7cd207eed4c60b0f411b444cd1464198fe186671c323b6cd6d433ed80fc9d247")
version("24.0", sha256="ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc")
version("23.3.2", sha256="5052d7889c1f9d05224cd41741acb7c5d6fa735ab34e339624a614eaaa7e7d76")
version("23.2.1", sha256="7ccf472345f20d35bdc9d1841ff5f313260c2c33fe417f48c30ac46cccabf5be")
version("23.1.2", sha256="3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18") version("23.1.2", sha256="3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18")
version("23.0", sha256="b5f88adff801f5ef052bcdef3daa31b55eb67b0fccd6d0106c206fa248e0463c") version("23.0", sha256="b5f88adff801f5ef052bcdef3daa31b55eb67b0fccd6d0106c206fa248e0463c")
version("22.2.2", sha256="b61a374b5bc40a6e982426aede40c9b5a08ff20e640f5b56977f4f91fed1e39a") version("22.2.2", sha256="b61a374b5bc40a6e982426aede40c9b5a08ff20e640f5b56977f4f91fed1e39a")
@@ -46,7 +40,6 @@ class PyPip(Package, PythonExtension):
version("9.0.1", sha256="690b762c0a8460c303c089d5d0be034fb15a5ea2b75bdf565f40421f542fefb0") version("9.0.1", sha256="690b762c0a8460c303c089d5d0be034fb15a5ea2b75bdf565f40421f542fefb0")
extends("python") extends("python")
depends_on("python@3.8:", when="@24.1:", type=("build", "run"))
depends_on("python@3.7:", when="@22:", type=("build", "run")) depends_on("python@3.7:", when="@22:", type=("build", "run"))
# Uses collections.MutableMapping # Uses collections.MutableMapping

View File

@@ -16,7 +16,6 @@ class PyRuff(PythonPackage):
license("MIT") license("MIT")
maintainers("adamjstewart") maintainers("adamjstewart")
version("0.8.1", sha256="3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f")
version("0.8.0", sha256="a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44") version("0.8.0", sha256="a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44")
version("0.6.5", sha256="4d32d87fab433c0cf285c3683dd4dae63be05fd7a1d65b3f5bf7cdd05a6b96fb") version("0.6.5", sha256="4d32d87fab433c0cf285c3683dd4dae63be05fd7a1d65b3f5bf7cdd05a6b96fb")
version("0.5.7", sha256="8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5") version("0.5.7", sha256="8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5")

View File

@@ -21,8 +21,7 @@ class PyTorchSparse(PythonPackage):
version("0.6.8", sha256="312fb5ae6e4e575fca4bbc0bd092af85e7679d5b8e53459f24492fc2a073c7b6") version("0.6.8", sha256="312fb5ae6e4e575fca4bbc0bd092af85e7679d5b8e53459f24492fc2a073c7b6")
version("0.6.7", sha256="f69b2ed35baf2a9853234756a2b19e6f7ce88d2c1f029d1c7ca166d91e1adbd0") version("0.6.7", sha256="f69b2ed35baf2a9853234756a2b19e6f7ce88d2c1f029d1c7ca166d91e1adbd0")
depends_on("c", type="build") depends_on("cxx", type="build") # generated
depends_on("cxx", type="build")
depends_on("py-setuptools", type="build") depends_on("py-setuptools", type="build")
depends_on("py-scipy", type=("build", "run")) depends_on("py-scipy", type=("build", "run"))

View File

@@ -87,15 +87,14 @@ class Vtk(CMakePackage):
conflicts("%gcc@13", when="@9.2") conflicts("%gcc@13", when="@9.2")
# Based on PyPI wheel availability with when("+python"):
with when("+python"), default_args(type=("build", "link", "run")): # Depend on any Python, add bounds below.
depends_on("python@:3.13") extends("python@2.7:", type=("build", "run"))
depends_on("python@:3.12", when="@:9.3") depends_on("python@:3.7", when="@:8.2.0", type=("build", "run"))
depends_on("python@:3.11", when="@:9.2") # Python 3.8 support from vtk 9 and patched 8.2
depends_on("python@:3.10", when="@:9.2.2") depends_on("python@:3.8", when="@:8.2.1a", type=("build", "run"))
depends_on("python@:3.9", when="@:9.1") # Python 3.10 support from vtk 9.2
depends_on("python@:3.8", when="@:9.0.1") depends_on("python@:3.9", when="@:9.1", type=("build", "run"))
depends_on("python@:3.7", when="@:8.2.0")
# We need mpi4py if buidling python wrappers and using MPI # We need mpi4py if buidling python wrappers and using MPI
depends_on("py-mpi4py", when="+python+mpi", type="run") depends_on("py-mpi4py", when="+python+mpi", type="run")