diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/fetch_strategy.py | 35 | ||||
-rw-r--r-- | lib/spack/spack/test/__init__.py | 3 | ||||
-rw-r--r-- | lib/spack/spack/test/hg_fetch.py | 143 |
3 files changed, 163 insertions, 18 deletions
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index ad9af43c96..321c7fbd54 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -315,7 +315,7 @@ class GitFetchStrategy(VCSFetchStrategy): if self.commit: args.append('at commit %s' % self.commit) elif self.tag: - args.append('at tag %s' % self.branch) + args.append('at tag %s' % self.tag) elif self.branch: args.append('on branch %s' % self.branch) tty.msg("Trying to clone git repository:", self.url, *args) @@ -431,26 +431,21 @@ class HgFetchStrategy(VCSFetchStrategy): version('torus', hg='https://jay.grs.rwth-aachen.de/hg/lwm2', branch='torus') - You can use these three optional attributes in addition to ``hg``: + You can use the optional 'revision' attribute to check out a + branch, tag, or particular revision in hg. To prevent + non-reproducible builds, using a moving target like a branch is + discouraged. - * ``branch``: Particular branch to build from (default is 'default') - * ``tag``: Particular tag to check out - * ``revision``: Particular revision hash in the repo + * ``revision``: Particular revision, branch, or tag. """ enabled = True required_attributes = ['hg'] def __init__(self, **kwargs): super(HgFetchStrategy, self).__init__( - 'hg', 'tag', 'branch', 'revision', **kwargs) + 'hg', 'revision', **kwargs) self._hg = None - # For git fetch branches and tags the same way. - if not self.revision: - self.revision = self.branch - if not self.revision: - self.revision = self.tag - @property def hg(self): @@ -467,7 +462,10 @@ class HgFetchStrategy(VCSFetchStrategy): tty.msg("Already fetched %s." % self.stage.source_path) return - tty.msg("Trying to clone Mercurial repository: %s" % self.url) + args = [] + if self.revision: + args.append('at revision %s' % self.revision) + tty.msg("Trying to clone Mercurial repository:", self.url, *args) args = ['clone', self.url] if self.revision: @@ -480,15 +478,18 @@ class HgFetchStrategy(VCSFetchStrategy): assert(self.stage) self.stage.chdir() + source_path = self.stage.source_path scrubbed = "scrubbed-source-tmp" + args = ['clone'] if self.revision: args += ['-r', self.revision] - args += [self.stage.source_path, scrubbed] - + args += [source_path, scrubbed] self.hg(*args) - shutil.rmtree(self.stage.source_path, ignore_errors=True) - shutil.move(scrubbed, self.stage.source_path) + + shutil.rmtree(source_path, ignore_errors=True) + shutil.move(scrubbed, source_path) + self.stage.chdir_to_source() def from_url(url): diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index 61464293d2..ca4c869e42 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -49,7 +49,8 @@ test_names = ['versions', 'directory_layout', 'python_version', 'git_fetch', - 'svn_fetch'] + 'svn_fetch', + 'hg_fetch'] def list_tests(): diff --git a/lib/spack/spack/test/hg_fetch.py b/lib/spack/spack/test/hg_fetch.py new file mode 100644 index 0000000000..4b9a2f8bc9 --- /dev/null +++ b/lib/spack/spack/test/hg_fetch.py @@ -0,0 +1,143 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://scalability-llnl.github.io/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +import os +import unittest +import shutil +import tempfile +from contextlib import closing + +from llnl.util.filesystem import * + +import spack +from spack.version import ver +from spack.stage import Stage +from spack.util.executable import which +from spack.test.mock_packages_test import * + +test_repo_path = 'test-repo' +test_file_name = 'test-file.txt' +test_rev1_file_name = 'test-file2.txt' +untracked = 'foobarbaz' + +hg = which('hg', required=True) + +class HgFetchTest(MockPackagesTest): + """Tests fetching from a dummy hg repository.""" + + def get_rev(self): + """Get current mercurial revision.""" + return hg('id', '-i', return_output=True).strip() + + + def setUp(self): + """Create a hg repository with master and two other branches, + and one tag, so that we can experiment on it.""" + super(HgFetchTest, self).setUp() + self.stage = Stage('fetch-test') + + self.repo_path = join_path(self.stage.path, test_repo_path) + mkdirp(self.repo_path) + + test_file = join_path(self.repo_path, test_file_name) + test_file_rev1 = join_path(self.repo_path, test_rev1_file_name) + + with working_dir(self.repo_path): + hg('init') + + touch(test_file) + hg('add', test_file) + hg('commit', '-m', 'revision 0', '-u', 'test') + self.rev0 = self.get_rev() + + touch(test_file_rev1) + hg('add', test_file_rev1) + hg('commit', '-m' 'revision 1', '-u', 'test') + self.rev1 = self.get_rev() + + spec = Spec('hg-test') + spec.concretize() + self.pkg = spack.db.get(spec, new=True) + + + def tearDown(self): + """Destroy the stage space used by this test.""" + super(HgFetchTest, self).tearDown() + + if self.stage is not None: + self.stage.destroy() + + self.pkg.do_clean_dist() + + + def assert_rev(self, rev): + """Check that the current hg revision is equal to the supplied rev.""" + self.assertEqual(self.get_rev(), rev) + + + def try_fetch(self, rev, test_file, args): + """Tries to: + 1. Fetch the repo using a fetch strategy constructed with + supplied args. + 2. Check if the test_file is in the checked out repository. + 3. Assert that the repository is at the revision supplied. + 4. Add and remove some files, then reset the repo, and + ensure it's all there again. + """ + self.pkg.versions[ver('hg')] = args + + self.pkg.do_stage() + self.assert_rev(rev) + + file_path = join_path(self.pkg.stage.source_path, test_file) + self.assertTrue(os.path.isdir(self.pkg.stage.source_path)) + self.assertTrue(os.path.isfile(file_path)) + + os.unlink(file_path) + self.assertFalse(os.path.isfile(file_path)) + + touch(untracked) + self.assertTrue(os.path.isfile(untracked)) + self.pkg.do_clean_work() + self.assertFalse(os.path.isfile(untracked)) + + self.assertTrue(os.path.isdir(self.pkg.stage.source_path)) + self.assertTrue(os.path.isfile(file_path)) + + self.assert_rev(rev) + + + def test_fetch_default(self): + """Test a default hg checkout with no commit or tag specified.""" + self.try_fetch(self.rev1, test_rev1_file_name, { + 'hg' : self.repo_path + }) + + + def test_fetch_rev0(self): + """Test fetching a branch.""" + self.try_fetch(self.rev0, test_file_name, { + 'hg' : self.repo_path, + 'revision' : self.rev0 + }) |