From 267da7855947933ffb360b6a7f003782c7df942b Mon Sep 17 00:00:00 2001 From: Peter Scheibel Date: Fri, 22 Apr 2022 11:02:17 -0700 Subject: Package-level submodule attribute: support explicit versions (#30085) --- lib/spack/spack/fetch_strategy.py | 4 ++++ lib/spack/spack/test/conftest.py | 6 ++++++ lib/spack/spack/test/git_fetch.py | 42 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index a8675550ff..378209308f 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -1575,6 +1575,10 @@ def _from_merged_attrs(fetcher, pkg, version): attrs['fetch_options'] = pkg.fetch_options attrs.update(pkg.versions[version]) + + if fetcher.url_attr == 'git' and hasattr(pkg, 'submodules'): + attrs.setdefault('submodules', pkg.submodules) + return fetcher(**attrs) diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index 420910b764..1a1b15f469 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -1364,6 +1364,12 @@ def mock_git_repository(tmpdir_factory): ), 'commit': Bunch( revision=r1, file=r1_file, args={'git': url, 'commit': r1} + ), + # In this case, the version() args do not include a 'git' key: + # this is the norm for packages, so this tests how the fetching logic + # would most-commonly assemble a Git fetcher + 'master-no-per-version-git': Bunch( + revision='master', file=r0_file, args={'branch': 'master'} ) } diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py index acefb98175..5313fd8c8f 100644 --- a/lib/spack/spack/test/git_fetch.py +++ b/lib/spack/spack/test/git_fetch.py @@ -82,7 +82,8 @@ def test_bad_git(tmpdir, mock_bad_git): fetcher.fetch() -@pytest.mark.parametrize("type_of_test", ['master', 'branch', 'tag', 'commit']) +@pytest.mark.parametrize("type_of_test", + ['master', 'branch', 'tag', 'commit']) @pytest.mark.parametrize("secure", [True, False]) def test_fetch(type_of_test, secure, @@ -104,6 +105,11 @@ def test_fetch(type_of_test, t = mock_git_repository.checks[type_of_test] h = mock_git_repository.hash + pkg_class = spack.repo.path.get_pkg_class('git-test') + # This would fail using the master-no-per-version-git check but that + # isn't included in this test + monkeypatch.delattr(pkg_class, 'git') + # Construct the package under test spec = Spec('git-test') spec.concretize() @@ -137,6 +143,40 @@ def test_fetch(type_of_test, assert h('HEAD') == h(t.revision) +@pytest.mark.disable_clean_stage_check +def test_fetch_pkg_attr_submodule_init( + mock_git_repository, + config, + mutable_mock_repo, + monkeypatch, + mock_stage): + """In this case the version() args do not contain a 'git' URL, so + the fetcher must be assembled using the Package-level 'git' attribute. + This test ensures that the submodules are properly initialized and the + expected branch file is present. + """ + + t = mock_git_repository.checks['master-no-per-version-git'] + pkg_class = spack.repo.path.get_pkg_class('git-test') + # For this test, the version args don't specify 'git' (which is + # the majority of version specifications) + monkeypatch.setattr(pkg_class, 'git', mock_git_repository.url) + + # Construct the package under test + spec = Spec('git-test') + spec.concretize() + pkg = spack.repo.get(spec) + monkeypatch.setitem(pkg.versions, ver('git'), t.args) + + spec.package.do_stage() + + collected_fnames = set() + for root, dirs, files in os.walk(spec.package.stage.source_path): + collected_fnames.update(files) + # The submodules generate files with the prefix "r0_file_" + assert set(['r0_file_0', 'r0_file_1', t.file]) < collected_fnames + + @pytest.mark.skipif(str(spack.platforms.host()) == 'windows', reason=('Git fails to clone because the src/dst paths' ' are too long: the name of the staging directory' -- cgit v1.2.3-60-g2f50