diff options
author | Tim Fuller <tjfulle@sandia.gov> | 2022-06-08 23:45:49 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-09 07:45:49 +0200 |
commit | 01f8236bf5faca20859ed3c4bb7dd179a4178e18 (patch) | |
tree | cc08df0c87915ddbf5453dfc8aeb952d057ab767 /lib | |
parent | 57822d3014f05d595bc7d6b71c048e4034f5247f (diff) | |
download | spack-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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/docs/packaging_guide.rst | 23 | ||||
-rw-r--r-- | lib/spack/spack/fetch_strategy.py | 26 | ||||
-rw-r--r-- | lib/spack/spack/package.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/package_base.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/test/git_fetch.py | 31 |
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 ): |