summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Fuller <tjfulle@sandia.gov>2022-06-08 23:45:49 -0600
committerGitHub <noreply@github.com>2022-06-09 07:45:49 +0200
commit01f8236bf5faca20859ed3c4bb7dd179a4178e18 (patch)
treecc08df0c87915ddbf5453dfc8aeb952d057ab767
parent57822d3014f05d595bc7d6b71c048e4034f5247f (diff)
downloadspack-01f8236bf5faca20859ed3c4bb7dd179a4178e18.tar.gz
spack-01f8236bf5faca20859ed3c4bb7dd179a4178e18.tar.bz2
spack-01f8236bf5faca20859ed3c4bb7dd179a4178e18.tar.xz
spack-01f8236bf5faca20859ed3c4bb7dd179a4178e18.zip
Allow more fine-grained control over what submodules are updated (#27293)
The "submodules" argument of the "version" directive can now accept a callable that returns a list of submodules, in addition to the usual Boolean values
-rw-r--r--lib/spack/docs/packaging_guide.rst23
-rw-r--r--lib/spack/spack/fetch_strategy.py26
-rw-r--r--lib/spack/spack/package.py2
-rw-r--r--lib/spack/spack/package_base.py2
-rw-r--r--lib/spack/spack/test/git_fetch.py31
5 files changed, 78 insertions, 6 deletions
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index d0aab3b3a9..dcc8f73b5d 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -1070,13 +1070,32 @@ Commits
Submodules
You can supply ``submodules=True`` to cause Spack to fetch submodules
- recursively along with the repository at fetch time. For more information
- about git submodules see the manpage of git: ``man git-submodule``.
+ recursively along with the repository at fetch time.
.. code-block:: python
version('1.0.1', tag='v1.0.1', submodules=True)
+ If a package has needs more fine-grained control over submodules, define
+ ``submodules`` to be a callable function that takes the package instance as
+ its only argument. The function should return a list of submodules to be fetched.
+
+ .. code-block:: python
+
+ def submodules(package):
+ submodules = []
+ if "+variant-1" in package.spec:
+ submodules.append("submodule_for_variant_1")
+ if "+variant-2" in package.spec:
+ submodules.append("submodule_for_variant_2")
+ return submodules
+
+
+ class MyPackage(Package):
+ version("0.1.0", submodules=submodules)
+
+ For more information about git submodules see the manpage of git: ``man
+ git-submodule``.
.. _github-fetch:
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index bd7331e1a1..9f907c5da6 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -120,6 +120,11 @@ class FetchStrategy(object):
# 'no_cache' option from version directive.
self.cache_enabled = not kwargs.pop('no_cache', False)
+ self.package = None
+
+ def set_package(self, package):
+ self.package = package
+
# Subclasses need to implement these methods
def fetch(self):
"""Fetch source code archive or repo.
@@ -243,6 +248,10 @@ class FetchStrategyComposite(pattern.Composite):
if all(component_ids):
return component_ids
+ def set_package(self, package):
+ for item in self:
+ item.package = package
+
@fetcher
class URLFetchStrategy(FetchStrategy):
@@ -976,9 +985,20 @@ class GitFetchStrategy(VCSFetchStrategy):
git(*args)
# Init submodules if the user asked for them.
- if self.submodules:
- with working_dir(dest):
- args = ['submodule', 'update', '--init', '--recursive']
+ git_commands = []
+ submodules = self.submodules
+ if callable(submodules):
+ submodules = list(submodules(self.package))
+ git_commands.append(["submodule", "init", "--"] + submodules)
+ git_commands.append(['submodule', 'update', '--recursive'])
+ elif submodules:
+ git_commands.append(["submodule", "update", "--init", "--recursive"])
+
+ if not git_commands:
+ return
+
+ with working_dir(dest):
+ for args in git_commands:
if not spack.config.get('config:debug'):
args.insert(1, '--quiet')
git(*args)
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 84053d1cea..65e699bda4 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -82,4 +82,4 @@ from spack.variant import (
conditional,
disjoint_sets,
)
-from spack.version import Version, ver \ No newline at end of file
+from spack.version import Version, ver
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
index b4763bfab9..0760f832f7 100644
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -1312,6 +1312,7 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
resources = self._get_needed_resources()
for resource in resources:
fetcher.append(resource.fetcher)
+ fetcher.set_package(self)
return fetcher
@property
@@ -1326,6 +1327,7 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
@fetcher.setter
def fetcher(self, f):
self._fetcher = f
+ self._fetcher.set_package(self)
def dependencies_of_type(self, *deptypes):
"""Get dependencies that can possibly have these deptypes.
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
index 8d5b0d9f48..0bf3447f83 100644
--- a/lib/spack/spack/test/git_fetch.py
+++ b/lib/spack/spack/test/git_fetch.py
@@ -327,6 +327,37 @@ def test_gitsubmodule(submodules, mock_git_repository, config,
@pytest.mark.disable_clean_stage_check
+def test_gitsubmodules_callable(
+ mock_git_repository, config, mutable_mock_repo, monkeypatch
+):
+ """
+ Test GitFetchStrategy behavior with submodules selected after concretization
+ """
+ def submodules_callback(package):
+ name = 'third_party/submodule0'
+ return [name]
+
+ type_of_test = 'tag-branch'
+ t = mock_git_repository.checks[type_of_test]
+
+ # Construct the package under test
+ spec = Spec('git-test')
+ spec.concretize()
+ pkg = spack.repo.get(spec)
+ args = copy.copy(t.args)
+ args['submodules'] = submodules_callback
+ monkeypatch.setitem(pkg.versions, ver('git'), args)
+ pkg.do_stage()
+ with working_dir(pkg.stage.source_path):
+ file_path = os.path.join(pkg.stage.source_path,
+ 'third_party/submodule0/r0_file_0')
+ assert os.path.isfile(file_path)
+ file_path = os.path.join(pkg.stage.source_path,
+ 'third_party/submodule1/r0_file_1')
+ assert not os.path.isfile(file_path)
+
+
+@pytest.mark.disable_clean_stage_check
def test_gitsubmodules_delete(
mock_git_repository, config, mutable_mock_repo, monkeypatch
):