4747import ramble .util .web as web_util
4848from ramble .util .logger import logger
4949
50- import spack .error
5150import spack .util .crypto as crypto
5251import spack .util .pattern as pattern
5352import spack .util .url as url_util
53+ import spack .version
5454from spack .util .compression import decompressor_for , extension
5555from spack .util .executable import CommandNotFoundError , which
56- from spack .util .string import comma_and , quote
5756from spack .version import Version , ver
5857
5958#: List of all fetch strategies, created by FetchStrategy metaclass.
@@ -1512,138 +1511,6 @@ def from_kwargs(**kwargs):
15121511 raise InvalidArgsError (** kwargs )
15131512
15141513
1515- def check_pkg_attributes (pkg ):
1516- """Find ambiguous top-level fetch attributes in a package.
1517-
1518- Currently this only ensures that two or more VCS fetch strategies are
1519- not specified at once.
1520- """
1521- # a single package cannot have URL attributes for multiple VCS fetch
1522- # strategies *unless* they are the same attribute.
1523- conflicts = {s .url_attr for s in all_strategies if hasattr (pkg , s .url_attr )}
1524-
1525- # URL isn't a VCS fetch method. We can use it with a VCS method.
1526- conflicts -= {"url" }
1527-
1528- if len (conflicts ) > 1 :
1529- raise FetcherConflict (
1530- "Package %s cannot specify %s together. Pick at most one."
1531- % (pkg .name , comma_and (quote (conflicts )))
1532- )
1533-
1534-
1535- def _check_version_attributes (fetcher , pkg , version ):
1536- """Ensure that the fetcher for a version is not ambiguous.
1537-
1538- This assumes that we have already determined the fetcher for the
1539- specific version using ``for_package_version()``
1540- """
1541- all_optionals = {a for s in all_strategies for a in s .optional_attrs }
1542-
1543- args = pkg .versions [version ]
1544- extra = set (args ) - set (fetcher .optional_attrs ) - {fetcher .url_attr , "no_cache" }
1545- extra .intersection_update (all_optionals )
1546-
1547- if extra :
1548- legal_attrs = [fetcher .url_attr ] + list (fetcher .optional_attrs )
1549- raise FetcherConflict (
1550- "%s version '%s' has extra arguments: %s"
1551- % (pkg .name , version , comma_and (quote (extra ))),
1552- "Valid arguments for a %s fetcher are: \n %s"
1553- % (fetcher .url_attr , comma_and (quote (legal_attrs ))),
1554- )
1555-
1556-
1557- def _extrapolate (pkg , version ):
1558- """Create a fetcher from an extrapolated URL for this version."""
1559- try :
1560- return URLFetchStrategy (pkg .url_for_version (version ), fetch_options = pkg .fetch_options )
1561- except spack .package .NoURLError :
1562- msg = "Can't extrapolate a URL for version %s " "because package %s defines no URLs"
1563- raise ExtrapolationError (msg % (version , pkg .name ))
1564-
1565-
1566- def _from_merged_attrs (fetcher , pkg , version ):
1567- """Create a fetcher from merged package and version attributes."""
1568- if fetcher .url_attr == "url" :
1569- url = pkg .url_for_version (version )
1570- # TODO: refactor this logic into its own method or function
1571- # TODO: to avoid duplication
1572- mirrors = [spack .url .substitute_version (u , version ) for u in getattr (pkg , "urls" , [])[1 :]]
1573- attrs = {fetcher .url_attr : url , "mirrors" : mirrors }
1574- else :
1575- url = getattr (pkg , fetcher .url_attr )
1576- attrs = {fetcher .url_attr : url }
1577-
1578- attrs ["fetch_options" ] = pkg .fetch_options
1579- attrs .update (pkg .versions [version ])
1580-
1581- if fetcher .url_attr == "git" and hasattr (pkg , "submodules" ):
1582- attrs .setdefault ("submodules" , pkg .submodules )
1583-
1584- return fetcher (** attrs )
1585-
1586-
1587- def for_package_version (pkg , version ):
1588- """Determine a fetch strategy based on the arguments supplied to
1589- version() in the package description."""
1590-
1591- # No-code packages have a custom fetch strategy to work around issues
1592- # with resource staging.
1593- if not pkg .has_code :
1594- return BundleFetchStrategy ()
1595-
1596- check_pkg_attributes (pkg )
1597-
1598- if not isinstance (version , spack .version .Version ):
1599- version = spack .version .Version (version )
1600-
1601- # if it's a commit, we must use a GitFetchStrategy
1602- if version .is_commit and hasattr (pkg , "git" ):
1603- # Populate the version with comparisons to other commits
1604- version .generate_commit_lookup (pkg .name )
1605- kwargs = {"git" : pkg .git , "commit" : str (version )}
1606- kwargs ["submodules" ] = getattr (pkg , "submodules" , False )
1607- fetcher = GitFetchStrategy (** kwargs )
1608- return fetcher
1609-
1610- # If it's not a known version, try to extrapolate one by URL
1611- if version not in pkg .versions :
1612- return _extrapolate (pkg , version )
1613-
1614- # Set package args first so version args can override them
1615- args = {"fetch_options" : pkg .fetch_options }
1616- # Grab a dict of args out of the package version dict
1617- args .update (pkg .versions [version ])
1618-
1619- # If the version specifies a `url_attr` directly, use that.
1620- for fetcher in all_strategies :
1621- if fetcher .url_attr in args :
1622- _check_version_attributes (fetcher , pkg , version )
1623- if fetcher .url_attr == "git" and hasattr (pkg , "submodules" ):
1624- args .setdefault ("submodules" , pkg .submodules )
1625- return fetcher (** args )
1626-
1627- # if a version's optional attributes imply a particular fetch
1628- # strategy, and we have the `url_attr`, then use that strategy.
1629- for fetcher in all_strategies :
1630- if hasattr (pkg , fetcher .url_attr ) or fetcher .url_attr == "url" :
1631- optionals = fetcher .optional_attrs
1632- if optionals and any (a in args for a in optionals ):
1633- _check_version_attributes (fetcher , pkg , version )
1634- return _from_merged_attrs (fetcher , pkg , version )
1635-
1636- # if the optional attributes tell us nothing, then use any `url_attr`
1637- # on the package. This prefers URL vs. VCS, b/c URLFetchStrategy is
1638- # defined first in this file.
1639- for fetcher in all_strategies :
1640- if hasattr (pkg , fetcher .url_attr ):
1641- _check_version_attributes (fetcher , pkg , version )
1642- return _from_merged_attrs (fetcher , pkg , version )
1643-
1644- raise InvalidArgsError (pkg , version , ** args )
1645-
1646-
16471514def from_url_scheme (url , * args , ** kwargs ):
16481515 """Finds a suitable FetchStrategy by matching its url_attr with the scheme
16491516 in the given url."""
@@ -1670,39 +1537,6 @@ def from_url_scheme(url, *args, **kwargs):
16701537 raise ValueError (f'No FetchStrategy found for url with scheme: "{ parsed_url .scheme } "' )
16711538
16721539
1673- def from_list_url (pkg ):
1674- """If a package provides a URL which lists URLs for resources by
1675- version, this can can create a fetcher for a URL discovered for
1676- the specified package's version."""
1677-
1678- if pkg .list_url :
1679- try :
1680- versions = pkg .fetch_remote_versions ()
1681- try :
1682- # get a URL, and a checksum if we have it
1683- url_from_list = versions [pkg .version ]
1684- checksum = None
1685-
1686- # try to find a known checksum for version, from the package
1687- version = pkg .version
1688- if version in pkg .versions :
1689- args = pkg .versions [version ]
1690- checksum = next (
1691- (v for k , v in args .items () if k in crypto .hashes ), args .get ("checksum" )
1692- )
1693-
1694- # construct a fetcher
1695- return URLFetchStrategy (url_from_list , checksum , fetch_options = pkg .fetch_options )
1696- except KeyError as e :
1697- logger .debug (e )
1698- logger .msg (f"Cannot find version { pkg .version } in url_list" )
1699-
1700- except BaseException as e :
1701- # TODO: Don't catch BaseException here! Be more specific.
1702- logger .debug (e )
1703- logger .msg ("Could not determine url from list_url." )
1704-
1705-
17061540class FsCache :
17071541
17081542 def __init__ (self , root ):
0 commit comments