summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2014-10-01 23:32:36 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2014-10-03 16:55:53 -0700
commitda84764e97ead919bee7fb02d469c25a6b03ab63 (patch)
tree748059d635e1f55162cdafc94e9100b573f88fa7 /lib
parentc74cd63389eff149d8c0db4f7d68d173a72b48b3 (diff)
downloadspack-da84764e97ead919bee7fb02d469c25a6b03ab63.tar.gz
spack-da84764e97ead919bee7fb02d469c25a6b03ab63.tar.bz2
spack-da84764e97ead919bee7fb02d469c25a6b03ab63.tar.xz
spack-da84764e97ead919bee7fb02d469c25a6b03ab63.zip
Add test case for git fetching.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/fetch_strategy.py15
-rw-r--r--lib/spack/spack/package.py21
-rw-r--r--lib/spack/spack/packages.py21
-rw-r--r--lib/spack/spack/test/__init__.py3
-rw-r--r--lib/spack/spack/test/git_fetch.py175
-rw-r--r--lib/spack/spack/test/install.py5
6 files changed, 222 insertions, 18 deletions
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index cba0ace6d3..328f45c3d6 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -225,15 +225,14 @@ class VCSFetchStrategy(FetchStrategy):
"%s requires %s argument." % (self.__class__, name))
# Ensure that there's only one of the rev_types
- if sum((k in kwargs for k in rev_types)) > 1:
+ if sum(k in kwargs for k in rev_types) > 1:
raise FetchStrategyError(
"Supply only one of %s to fetch with %s." % (
comma_or(rev_types), name))
# Set attributes for each rev type.
for rt in rev_types:
- setattr(self, rt, getattr(kwargs, rt, None))
-
+ setattr(self, rt, kwargs.get(rt, None))
def check(self):
assert(self.stage)
@@ -301,7 +300,14 @@ class GitFetchStrategy(VCSFetchStrategy):
tty.msg("Already fetched %s." % self.stage.source_path)
return
- tty.msg("Trying to clone git repository: %s" % self.url)
+ args = []
+ if self.commit:
+ args.append('at commit %s' % self.commit)
+ elif self.tag:
+ args.append('at tag %s' % self.branch)
+ elif self.branch:
+ args.append('on branch %s' % self.branch)
+ tty.msg("Trying to clone git repository:", self.url, *args)
if self.commit:
# Need to do a regular clone and check out everything if
@@ -460,4 +466,3 @@ class NoDigestError(FetchStrategyError):
class InvalidArgsError(FetchStrategyError):
def __init__(self, msg, long_msg):
super(InvalidArgsError, self).__init__(msg, long_msg)
-
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index e9fca9ec49..c6e1fd90ef 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -372,10 +372,8 @@ class Package(object):
if not hasattr(self, 'url'):
self.url = None
- # Set up a fetch strategy for this package.
- self.fetcher = None
- if self.spec.concrete:
- self.fetcher = fs.from_args(self.versions[self.version], self)
+ # Init fetch strategy to None
+ self._fetcher = None
# Set a default list URL (place to find available versions)
if not hasattr(self, 'list_url'):
@@ -458,6 +456,21 @@ class Package(object):
return self._stage
+ @property
+ def fetcher(self):
+ if not self.spec.concrete:
+ raise ValueError("Can only get a fetcher for a concrete package.")
+
+ if not self._fetcher:
+ self._fetcher = fs.from_args(self.versions[self.version], self)
+ return self._fetcher
+
+
+ @fetcher.setter
+ def fetcher(self, f):
+ self._fetcher = f
+
+
def mirror_path(self):
"""Get path to this package's archive in a mirror."""
filename = "%s-%s." % (self.name, self.version)
diff --git a/lib/spack/spack/packages.py b/lib/spack/spack/packages.py
index 72f9403a64..047d82a93a 100644
--- a/lib/spack/spack/packages.py
+++ b/lib/spack/spack/packages.py
@@ -47,10 +47,10 @@ _package_file_name = 'package.py'
def _autospec(function):
"""Decorator that automatically converts the argument of a single-arg
function to a Spec."""
- def converter(self, spec_like):
+ def converter(self, spec_like, **kwargs):
if not isinstance(spec_like, spack.spec.Spec):
spec_like = spack.spec.Spec(spec_like)
- return function(self, spec_like)
+ return function(self, spec_like, **kwargs)
return converter
@@ -63,10 +63,14 @@ class PackageDB(object):
@_autospec
- def get(self, spec):
+ def get(self, spec, **kwargs):
if spec.virtual:
raise UnknownPackageError(spec.name)
+ if kwargs.get('new', False):
+ if spec in self.instances:
+ del self.instances[spec]
+
if not spec in self.instances:
package_class = self.get_class_for_package_name(spec.name)
try:
@@ -78,6 +82,17 @@ class PackageDB(object):
@_autospec
+ def delete(self, spec):
+ """Force a package to be recreated."""
+ del self.instances[spec]
+
+
+ def purge(self):
+ """Clear entire package instance cache."""
+ self.instances.clear()
+
+
+ @_autospec
def get_installed(self, spec):
"""Get all the installed specs that satisfy the provided spec constraint."""
return [s for s in self.installed_package_specs() if s.satisfies(spec)]
diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py
index 8ddc7f227d..b00f9a31ce 100644
--- a/lib/spack/spack/test/__init__.py
+++ b/lib/spack/spack/test/__init__.py
@@ -47,7 +47,8 @@ test_names = ['versions',
'package_sanity',
'config',
'directory_layout',
- 'python_version']
+ 'python_version',
+ 'git_fetch']
def list_tests():
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
new file mode 100644
index 0000000000..c7c11621f9
--- /dev/null
+++ b/lib/spack/spack/test/git_fetch.py
@@ -0,0 +1,175 @@
+##############################################################################
+# 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_branch = 'test-branch'
+test_branch_file_name = 'branch-test-file'
+
+test_tag_branch = 'test-tag-branch'
+test_tag = 'test-tag'
+test_tag_file_name = 'tag-test-file'
+
+untracked = 'foobarbaz'
+
+git = which('git', required=True)
+
+def rev_hash(rev):
+ return git('rev-parse', rev, return_output=True).strip()
+
+
+class GitFetchTest(MockPackagesTest):
+ """Tests fetching from a dummy git repository."""
+
+ def setUp(self):
+ """Create a git repository with master and two other branches,
+ and one tag, so that we can experiment on it."""
+ super(GitFetchTest, self).setUp()
+ self.stage = Stage('fetch-test')
+
+ self.repo_path = join_path(self.stage.path, test_repo_path)
+ mkdirp(self.repo_path)
+
+ self.test_file = join_path(self.repo_path, test_file_name)
+ touch(self.test_file)
+
+ with working_dir(self.repo_path):
+ git('init')
+ git('add', self.test_file)
+ git('commit', '-m', 'testing')
+
+ git('branch', test_branch)
+ git('branch', test_tag_branch)
+
+ git('checkout', test_branch)
+ touch(test_branch_file_name)
+ git('add', test_branch_file_name)
+ git('commit', '-m' 'branch test')
+
+ git('checkout', test_tag_branch)
+ touch(test_tag_file_name)
+ git('add', test_tag_file_name)
+ git('commit', '-m' 'tag test')
+ git('tag', test_tag)
+
+ git('checkout', 'master')
+
+ self.commit = rev_hash(test_tag)
+
+ spec = Spec('git-test')
+ spec.concretize()
+ self.pkg = spack.db.get(spec, new=True)
+
+
+ def tearDown(self):
+ """Destroy the stage space used by this test."""
+ super(GitFetchTest, 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 git revision is equal to the supplied rev."""
+ self.assertEqual(rev_hash('HEAD'), rev_hash(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('git')] = 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_master(self):
+ """Test a default git checkout with no commit or tag specified."""
+ self.try_fetch('master', test_file_name, {
+ 'git' : self.repo_path
+ })
+
+
+ def test_fetch_branch(self):
+ """Test fetching a branch."""
+ self.try_fetch(test_branch, test_branch_file_name, {
+ 'git' : self.repo_path,
+ 'branch' : test_branch
+ })
+
+
+ def test_fetch_tag(self):
+ """Test fetching a tag."""
+ self.try_fetch(test_tag, test_tag_file_name, {
+ 'git' : self.repo_path,
+ 'tag' : test_tag
+ })
+
+
+ def test_fetch_commit(self):
+ """Test fetching a particular commit."""
+ self.try_fetch(self.commit, test_tag_file_name, {
+ 'git' : self.repo_path,
+ 'commit' : self.commit
+ })
diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py
index 896f19ac01..0d53bb45c7 100644
--- a/lib/spack/spack/test/install.py
+++ b/lib/spack/spack/test/install.py
@@ -101,13 +101,8 @@ class InstallTest(MockPackagesTest):
self.assertTrue(spec.concrete)
# Get the package
- print
- print "======== GETTING PACKAGE ========"
pkg = spack.db.get(spec)
- print "======== GOT PACKAGE ========"
- print
-
# Fake the URL for the package so it downloads from a file.
archive_path = join_path(self.stage.path, archive_name)
pkg.fetcher = URLFetchStrategy('file://' + archive_path)