From c74cd63389eff149d8c0db4f7d68d173a72b48b3 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Tue, 16 Sep 2014 16:56:16 -0700 Subject: Callpath build works when a tag is fetched from git. --- var/spack/packages/callpath/package.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'var') diff --git a/var/spack/packages/callpath/package.py b/var/spack/packages/callpath/package.py index 84170d9c9e..6102458291 100644 --- a/var/spack/packages/callpath/package.py +++ b/var/spack/packages/callpath/package.py @@ -33,6 +33,8 @@ class Callpath(Package): version('1.0.1', '0047983d2a52c5c335f8ba7f5bab2325') + depends_on("libelf") + depends_on("libdwarf") depends_on("dyninst") depends_on("adept-utils") depends_on("mpi") -- cgit v1.2.3-70-g09d2 From da84764e97ead919bee7fb02d469c25a6b03ab63 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Wed, 1 Oct 2014 23:32:36 -0700 Subject: Add test case for git fetching. --- lib/spack/spack/fetch_strategy.py | 15 ++- lib/spack/spack/package.py | 21 +++- lib/spack/spack/packages.py | 21 +++- lib/spack/spack/test/__init__.py | 3 +- lib/spack/spack/test/git_fetch.py | 175 ++++++++++++++++++++++++++++ lib/spack/spack/test/install.py | 5 - var/spack/mock_packages/git-test/package.py | 10 ++ 7 files changed, 232 insertions(+), 18 deletions(-) create mode 100644 lib/spack/spack/test/git_fetch.py create mode 100644 var/spack/mock_packages/git-test/package.py (limited to 'var') 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: @@ -77,6 +81,17 @@ class PackageDB(object): return self.instances[spec] + @_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.""" 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) diff --git a/var/spack/mock_packages/git-test/package.py b/var/spack/mock_packages/git-test/package.py new file mode 100644 index 0000000000..689185463c --- /dev/null +++ b/var/spack/mock_packages/git-test/package.py @@ -0,0 +1,10 @@ +from spack import * + +class GitTest(Package): + """Mock package that uses git for fetching.""" + homepage = "http://www.git-fetch-example.com" + + version('git', git='to-be-filled-in-by-test') + + def install(self, spec, prefix): + pass -- cgit v1.2.3-70-g09d2 From faae720c3693733ac272c191b7c3ab4908b02b6b Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Thu, 2 Oct 2014 01:14:00 -0700 Subject: add tests for svn fetching. --- lib/spack/spack/fetch_strategy.py | 26 ++++- lib/spack/spack/package.py | 2 +- lib/spack/spack/stage.py | 2 +- lib/spack/spack/test/__init__.py | 3 +- lib/spack/spack/test/svn_fetch.py | 150 ++++++++++++++++++++++++++++ var/spack/mock_packages/svn-test/package.py | 10 ++ 6 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 lib/spack/spack/test/svn_fetch.py create mode 100644 var/spack/mock_packages/svn-test/package.py (limited to 'var') diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 328f45c3d6..411c8cc276 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -209,11 +209,18 @@ class URLFetchStrategy(FetchStrategy): self.expand() - def __str__(self): + def __repr__(self): url = self.url if self.url else "no url" return "URLFetchStrategy<%s>" % url + def __str__(self): + if self.url: + return self.url + else: + return "URLFetchStrategy" + + class VCSFetchStrategy(FetchStrategy): def __init__(self, name, *rev_types, **kwargs): super(VCSFetchStrategy, self).__init__() @@ -245,6 +252,10 @@ class VCSFetchStrategy(FetchStrategy): def __str__(self): + return self.url + + + def __repr__(self): return "%s<%s>" % (self.__class__, self.url) @@ -359,6 +370,8 @@ class SvnFetchStrategy(VCSFetchStrategy): super(SvnFetchStrategy, self).__init__( 'svn', 'revision', **kwargs) self._svn = None + if self.revision is not None: + self.revision = str(self.revision) @property @@ -381,6 +394,7 @@ class SvnFetchStrategy(VCSFetchStrategy): args = ['checkout', '--force'] if self.revision: args += ['-r', self.revision] + args.append(self.url) self.svn(*args) self.stage.chdir_to_source() @@ -388,12 +402,16 @@ class SvnFetchStrategy(VCSFetchStrategy): def _remove_untracked_files(self): """Removes untracked files in an svn repository.""" - status = self.svn('status', '--no-ignore', check_output=True) + status = self.svn('status', '--no-ignore', return_output=True) + self.svn('status', '--no-ignore') for line in status.split('\n'): - if not re.match('^[I?]'): + if not re.match('^[I?]', line): continue path = line[8:].strip() - shutil.rmtree(path, ignore_errors=True) + if os.path.isfile(path): + os.unlink(path) + elif os.path.isdir(path): + shutil.rmtree(path, ignore_errors=True) def reset(self): diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index c6e1fd90ef..59bfafa241 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -643,7 +643,7 @@ class Package(object): archive_dir = self.stage.source_path if not archive_dir: self.stage.expand_archive() - tty.msg("Created stage directory in %s." % self.stage.path) + tty.msg("Created stage in %s." % self.stage.path) else: tty.msg("Already staged %s in %s." % (self.name, self.stage.path)) self.stage.chdir_to_source() diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py index ed92fb17f7..0d684df92d 100644 --- a/lib/spack/spack/stage.py +++ b/lib/spack/spack/stage.py @@ -254,7 +254,7 @@ class Stage(object): fetcher.fetch() break except spack.error.SpackError, e: - tty.msg("Download from %s failed." % fetcher) + tty.msg("Fetching %s failed." % fetcher) continue diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index b00f9a31ce..61464293d2 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -48,7 +48,8 @@ test_names = ['versions', 'config', 'directory_layout', 'python_version', - 'git_fetch'] + 'git_fetch', + 'svn_fetch'] def list_tests(): diff --git a/lib/spack/spack/test/svn_fetch.py b/lib/spack/spack/test/svn_fetch.py new file mode 100644 index 0000000000..e253f21921 --- /dev/null +++ b/lib/spack/spack/test/svn_fetch.py @@ -0,0 +1,150 @@ +############################################################################## +# 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 re +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_import_path = 'test-import' +test_file_name = 'test-file.txt' +test_rev_file_name = 'test-rev-file' + +untracked = 'foobarbaz' + +svn = which('svn', required=True) +svnadmin = which('svnadmin', required=True) + + +class SvnFetchTest(MockPackagesTest): + """Tests fetching from a dummy git repository.""" + + def setUp(self): + """Create an svn repository with two revisions.""" + super(SvnFetchTest, self).setUp() + self.stage = Stage('fetch-test') + self.stage.chdir() + + repo_path = join_path(self.stage.path, test_repo_path) + svnadmin('create', repo_path) + self.repo_url = 'file://' + repo_path + + self.import_path = join_path(self.stage.path, test_import_path) + mkdirp(self.import_path) + with working_dir(self.import_path): + touch(test_file_name) + + svn('import', self.import_path, self.repo_url, '-m', 'Initial import') + + shutil.rmtree(self.import_path) + svn('checkout', self.repo_url, self.import_path) + with working_dir(self.import_path): + touch(test_rev_file_name) + svn('add', test_rev_file_name) + svn('ci', '-m', 'second revision') + + spec = Spec('svn-test') + spec.concretize() + self.pkg = spack.db.get(spec, new=True) + + + def tearDown(self): + """Destroy the stage space used by this test.""" + super(SvnFetchTest, 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 revision is equal to the supplied rev.""" + def get_rev(): + output = svn('info', return_output=True) + self.assertTrue("Revision" in output) + for line in output.split('\n'): + match = re.match(r'Revision: (\d+)', line) + if match: + return int(match.group(1)) + self.assertEqual(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('svn')] = 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 checkout and make sure it's on rev 1""" + self.try_fetch(2, test_rev_file_name, { + 'svn' : self.repo_url + }) + + + def test_fetch_r1(self): + """Test fetching an older revision (0).""" + self.try_fetch(1, test_file_name, { + 'svn' : self.repo_url, + 'revision' : 1 + }) diff --git a/var/spack/mock_packages/svn-test/package.py b/var/spack/mock_packages/svn-test/package.py new file mode 100644 index 0000000000..ba4d5522b4 --- /dev/null +++ b/var/spack/mock_packages/svn-test/package.py @@ -0,0 +1,10 @@ +from spack import * + +class SvnTest(Package): + """Mock package that uses svn for fetching.""" + url = "http://www.example.com/svn-test-1.0.tar.gz" + + version('svn', 'to-be-filled-in-by-test') + + def install(self, spec, prefix): + pass -- cgit v1.2.3-70-g09d2 From 0fa1c5b0a54c2b64dfc431449b1ba4491b9981c0 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sat, 27 Sep 2014 00:04:50 -0700 Subject: Add Mercurial fetch strategy and lwm2. --- lib/spack/spack/fetch_strategy.py | 70 ++++++++++++++++++++++++++++++++++++++ var/spack/packages/lwm2/package.py | 18 ++++++++++ 2 files changed, 88 insertions(+) create mode 100644 var/spack/packages/lwm2/package.py (limited to 'var') diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 411c8cc276..ad9af43c96 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -421,6 +421,76 @@ class SvnFetchStrategy(VCSFetchStrategy): self.svn('revert', '.', '-R') +class HgFetchStrategy(VCSFetchStrategy): + """Fetch strategy that gets source code from a Mercurial repository. + Use like this in a package: + + version('name', hg='https://jay.grs.rwth-aachen.de/hg/lwm2') + + Optionally, you can provide a branch, or revision to check out, e.g.: + + version('torus', hg='https://jay.grs.rwth-aachen.de/hg/lwm2', branch='torus') + + You can use these three optional attributes in addition to ``hg``: + + * ``branch``: Particular branch to build from (default is 'default') + * ``tag``: Particular tag to check out + * ``revision``: Particular revision hash in the repo + """ + enabled = True + required_attributes = ['hg'] + + def __init__(self, **kwargs): + super(HgFetchStrategy, self).__init__( + 'hg', 'tag', 'branch', '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): + if not self._hg: + self._hg = which('hg', required=True) + return self._hg + + + def fetch(self): + assert(self.stage) + self.stage.chdir() + + if self.stage.source_path: + tty.msg("Already fetched %s." % self.stage.source_path) + return + + tty.msg("Trying to clone Mercurial repository: %s" % self.url) + + args = ['clone', self.url] + if self.revision: + args += ['-r', self.revision] + + self.hg(*args) + + + def reset(self): + assert(self.stage) + self.stage.chdir() + + scrubbed = "scrubbed-source-tmp" + args = ['clone'] + if self.revision: + args += ['-r', self.revision] + args += [self.stage.source_path, scrubbed] + + self.hg(*args) + shutil.rmtree(self.stage.source_path, ignore_errors=True) + shutil.move(scrubbed, self.stage.source_path) + + def from_url(url): """Given a URL, find an appropriate fetch strategy for it. Currently just gives you a URLFetchStrategy that uses curl. diff --git a/var/spack/packages/lwm2/package.py b/var/spack/packages/lwm2/package.py new file mode 100644 index 0000000000..bf95c3fe12 --- /dev/null +++ b/var/spack/packages/lwm2/package.py @@ -0,0 +1,18 @@ +from spack import * + +class Lwm2(Package): + """LWM2: Light Weight Measurement Module. This is a PMPI module + that can collect a number of time-sliced MPI and POSIX I/O + measurements from a program. + """ + homepage = "https://jay.grs.rwth-aachen.de/redmine/projects/lwm2" + + version('torus', hg='https://jay.grs.rwth-aachen.de/hg/lwm2', branch='torus') + + depends_on("papi") + depends_on("mpi") + + def install(self, spec, prefix): + configure("--prefix=%s" % prefix) + make() + make("install") -- cgit v1.2.3-70-g09d2 From 37e96ff6e14e419fbc31a43a1de966a7221e8ac1 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sat, 4 Oct 2014 18:38:47 -0700 Subject: Added test for Mercurial fetching. --- lib/spack/spack/fetch_strategy.py | 35 +++---- lib/spack/spack/test/__init__.py | 3 +- lib/spack/spack/test/hg_fetch.py | 143 +++++++++++++++++++++++++++++ var/spack/mock_packages/hg-test/package.py | 10 ++ var/spack/packages/lwm2/package.py | 2 +- 5 files changed, 174 insertions(+), 19 deletions(-) create mode 100644 lib/spack/spack/test/hg_fetch.py create mode 100644 var/spack/mock_packages/hg-test/package.py (limited to 'var') 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 + }) diff --git a/var/spack/mock_packages/hg-test/package.py b/var/spack/mock_packages/hg-test/package.py new file mode 100644 index 0000000000..462f1e4c3a --- /dev/null +++ b/var/spack/mock_packages/hg-test/package.py @@ -0,0 +1,10 @@ +from spack import * + +class HgTest(Package): + """Test package that does fetching with mercurial.""" + homepage = "http://www.hg-fetch-example.com" + + version('hg', hg='to-be-filled-in-by-test') + + def install(self, spec, prefix): + pass diff --git a/var/spack/packages/lwm2/package.py b/var/spack/packages/lwm2/package.py index bf95c3fe12..31afff8816 100644 --- a/var/spack/packages/lwm2/package.py +++ b/var/spack/packages/lwm2/package.py @@ -7,7 +7,7 @@ class Lwm2(Package): """ homepage = "https://jay.grs.rwth-aachen.de/redmine/projects/lwm2" - version('torus', hg='https://jay.grs.rwth-aachen.de/hg/lwm2', branch='torus') + version('torus', hg='https://jay.grs.rwth-aachen.de/hg/lwm2', revision='torus') depends_on("papi") depends_on("mpi") -- cgit v1.2.3-70-g09d2 From fb3003f664d13f95c1d8c6e2c430924165bd576f Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Thu, 16 Oct 2014 06:56:00 -0700 Subject: Bug fixes for URLs and mirror fetching. --- lib/spack/spack/cmd/mirror.py | 9 ++++++++- lib/spack/spack/concretize.py | 1 + lib/spack/spack/fetch_strategy.py | 24 +++++++++++++++++------- lib/spack/spack/mirror.py | 2 +- lib/spack/spack/stage.py | 23 ++++++++++------------- var/spack/packages/libmonitor/package.py | 3 +-- var/spack/packages/paraver/package.py | 4 ++-- var/spack/packages/stat/package.py | 2 +- 8 files changed, 41 insertions(+), 27 deletions(-) (limited to 'var') diff --git a/lib/spack/spack/cmd/mirror.py b/lib/spack/spack/cmd/mirror.py index 6e2e4dfb24..22838e1344 100644 --- a/lib/spack/spack/cmd/mirror.py +++ b/lib/spack/spack/cmd/mirror.py @@ -71,8 +71,12 @@ def setup_parser(subparser): def mirror_add(args): """Add a mirror to Spack.""" + url = args.url + if url.startswith('/'): + url = 'file://' + url + config = spack.config.get_config('user') - config.set_value('mirror', args.name, 'url', args.url) + config.set_value('mirror', args.name, 'url', url) config.write() @@ -158,6 +162,9 @@ def mirror_create(args): " %-4d already present" % p, " %-4d added" % m, " %-4d failed to fetch." % e) + if error: + tty.error("Failed downloads:") + colify(s.format("$_$@") for s in error) def mirror(parser, args): diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py index e603806af9..eee8cb7fde 100644 --- a/lib/spack/spack/concretize.py +++ b/lib/spack/spack/concretize.py @@ -70,6 +70,7 @@ class DefaultConcretizer(object): pkg = spec.package valid_versions = [v for v in pkg.available_versions if any(v.satisfies(sv) for sv in spec.versions)] + if valid_versions: spec.versions = ver([valid_versions[-1]]) else: diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 2b574eaba7..5a508b130c 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -559,7 +559,7 @@ def for_package_version(pkg, version): url = pkg.url_for_verison(version) if not url: raise InvalidArgsError(pkg, version) - return URLFetchStrategy() + return URLFetchStrategy(url) # Grab a dict of args out of the package version dict args = pkg.versions[version] @@ -574,6 +574,8 @@ def for_package_version(pkg, version): for fetcher in all_strategies: attrs = dict((attr, getattr(pkg, attr, None)) for attr in fetcher.required_attributes) + if 'url' in attrs: + attrs['url'] = pkg.url_for_version(version) attrs.update(args) if fetcher.matches(attrs): return fetcher(**attrs) @@ -581,12 +583,12 @@ def for_package_version(pkg, version): raise InvalidArgsError(pkg, version) -class FetchStrategyError(spack.error.SpackError): +class FetchError(spack.error.SpackError): def __init__(self, msg, long_msg): - super(FetchStrategyError, self).__init__(msg, long_msg) + super(FetchError, self).__init__(msg, long_msg) -class FailedDownloadError(FetchStrategyError): +class FailedDownloadError(FetchError): """Raised wen a download fails.""" def __init__(self, url, msg=""): super(FailedDownloadError, self).__init__( @@ -594,18 +596,26 @@ class FailedDownloadError(FetchStrategyError): self.url = url -class NoArchiveFileError(FetchStrategyError): +class NoArchiveFileError(FetchError): def __init__(self, msg, long_msg): super(NoArchiveFileError, self).__init__(msg, long_msg) -class NoDigestError(FetchStrategyError): +class NoDigestError(FetchError): def __init__(self, msg, long_msg): super(NoDigestError, self).__init__(msg, long_msg) -class InvalidArgsError(FetchStrategyError): +class InvalidArgsError(FetchError): def __init__(self, pkg, version): msg = "Could not construct a fetch strategy for package %s at version %s" msg %= (pkg.name, version) super(InvalidArgsError, self).__init__(msg) + + +class ChecksumError(FetchError): + """Raised when archive fails to checksum.""" + def __init__(self, message, long_msg=None): + super(ChecksumError, self).__init__(message, long_msg) + + diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py index f7bbb3f840..2f822b13ab 100644 --- a/lib/spack/spack/mirror.py +++ b/lib/spack/spack/mirror.py @@ -146,7 +146,7 @@ def create(path, specs, **kwargs): archive_file = mirror_archive_filename(spec) archive_path = join_path(subdir, archive_file) - if os.path.exists(archive_file): + if os.path.exists(archive_path): tty.msg("%s is already present. Skipping." % spec.format("$_$@")) present.append(spec) continue diff --git a/lib/spack/spack/stage.py b/lib/spack/spack/stage.py index 0d684df92d..b371761785 100644 --- a/lib/spack/spack/stage.py +++ b/lib/spack/spack/stage.py @@ -32,7 +32,7 @@ from llnl.util.filesystem import * import spack import spack.config -import spack.fetch_strategy as fetch_strategy +import spack.fetch_strategy as fs import spack.error @@ -83,8 +83,8 @@ class Stage(object): stage will be given a unique name automatically. """ if isinstance(url_or_fetch_strategy, basestring): - self.fetcher = fetch_strategy.from_url(url_or_fetch_strategy) - elif isinstance(url_or_fetch_strategy, fetch_strategy.FetchStrategy): + self.fetcher = fs.from_url(url_or_fetch_strategy) + elif isinstance(url_or_fetch_strategy, fs.FetchStrategy): self.fetcher = url_or_fetch_strategy else: raise ValueError("Can't construct Stage without url or fetch strategy") @@ -198,7 +198,10 @@ class Stage(object): @property def archive_file(self): """Path to the source archive within this stage directory.""" - paths = [os.path.join(self.path, os.path.basename(self.url))] + if not isinstance(self.fetcher, fs.URLFetchStrategy): + return None + + paths = [os.path.join(self.path, os.path.basename(self.fetcher.url))] if self.mirror_path: paths.append(os.path.join(self.path, os.path.basename(self.mirror_path))) @@ -242,9 +245,9 @@ class Stage(object): urls = ["%s/%s" % (m, self.mirror_path) for m in _get_mirrors()] digest = None - if isinstance(self.fetcher, fetch_strategy.URLFetchStrategy): + if isinstance(self.fetcher, fs.URLFetchStrategy): digest = self.fetcher.digest - fetchers = [fetch_strategy.URLFetchStrategy(url, digest) + fetchers = [fs.URLFetchStrategy(url, digest) for url in urls] + fetchers for f in fetchers: f.set_stage(self) @@ -365,12 +368,6 @@ class StageError(spack.error.SpackError): super(self, StageError).__init__(message, long_message) -class ChecksumError(StageError): - """Raised when archive fails to checksum.""" - def __init__(self, message, long_msg=None): - super(ChecksumError, self).__init__(message, long_msg) - - class RestageError(StageError): def __init__(self, message, long_msg=None): super(RestageError, self).__init__(message, long_msg) @@ -382,4 +379,4 @@ class ChdirError(StageError): # Keep this in namespace for convenience -FailedDownloadError = spack.fetch_strategy.FailedDownloadError +FailedDownloadError = fs.FailedDownloadError diff --git a/var/spack/packages/libmonitor/package.py b/var/spack/packages/libmonitor/package.py index 210712436a..ed619e4cce 100644 --- a/var/spack/packages/libmonitor/package.py +++ b/var/spack/packages/libmonitor/package.py @@ -27,9 +27,8 @@ from spack import * class Libmonitor(Package): """Libmonitor is a library for process and thread control.""" homepage = "http://hpctoolkit.org" - url = "file:///g/g0/legendre/tools/oss/openspeedshop-release-2.1/SOURCES/libmonitor-20130218.tar.gz" - version('20130218', 'aa85c2c580e2dafb823cc47b09374279') + version('20130218', svn='https://outreach.scidac.gov/svn/libmonitor/trunk', revision=146) def install(self, spec, prefix): configure("--prefix=" + prefix) diff --git a/var/spack/packages/paraver/package.py b/var/spack/packages/paraver/package.py index 45bac95b28..5f8a153d4c 100644 --- a/var/spack/packages/paraver/package.py +++ b/var/spack/packages/paraver/package.py @@ -7,9 +7,9 @@ class Paraver(Package): is expressed on its input trace format. Traces for parallel MPI, OpenMP and other programs can be genereated with Extrae.""" homepage = "http://www.bsc.es/computer-sciences/performance-tools/paraver" - url = "http://www.bsc.es/ssl/apps/performanceTools/files/paraver-sources-4.5.2.tar.gz" + url = "http://www.bsc.es/ssl/apps/performanceTools/files/paraver-sources-4.5.3.tar.gz" - version('4.5.2', 'ea463dd494519395c99ebae294edee17') + version('4.5.3', '625de9ec0d639acd18d1aaa644b38f72') depends_on("boost") #depends_on("extrae") diff --git a/var/spack/packages/stat/package.py b/var/spack/packages/stat/package.py index 956b0dcc8c..fbd1418d41 100644 --- a/var/spack/packages/stat/package.py +++ b/var/spack/packages/stat/package.py @@ -5,8 +5,8 @@ class Stat(Package): homepage = "http://paradyn.org/STAT/STAT.html" url = "https://github.com/lee218llnl/stat/archive/v2.0.0.tar.gz" - version('2.0.0', 'c7494210b0ba26b577171b92838e1a9b') version('2.1.0', 'ece26beaf057aa9134d62adcdda1ba91') + version('2.0.0', 'c7494210b0ba26b577171b92838e1a9b') depends_on('libdwarf') depends_on('dyninst') -- cgit v1.2.3-70-g09d2 From e4c2891d4ba5cc57a39f24c68affec8ee1eeca2c Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Wed, 22 Oct 2014 00:49:16 -0700 Subject: Test for URL extrapolation. --- lib/spack/spack/package.py | 7 ++- lib/spack/spack/test/__init__.py | 3 +- lib/spack/spack/test/url_extrapolate.py | 90 ++++++++++++++++++++++++++++++ lib/spack/spack/test/url_parse.py | 7 ++- var/spack/mock_packages/dyninst/package.py | 11 ++-- 5 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 lib/spack/spack/test/url_extrapolate.py (limited to 'var') diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index e462562e85..f1a16fdea1 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -440,9 +440,10 @@ class Package(object): version_urls = self.version_urls() if version in version_urls: return version_urls[version] - else: - return url.substitute_version(self.nearest_url(version), - self.url_version(version)) + + # If we have no idea, try to substitute the version. + return url.substitute_version(self.nearest_url(version), + self.url_version(version)) @property diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index be9ac5a560..aa986662bf 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -51,7 +51,8 @@ test_names = ['versions', 'git_fetch', 'svn_fetch', 'hg_fetch', - 'mirror'] + 'mirror', + 'url_extrapolate'] def list_tests(): diff --git a/lib/spack/spack/test/url_extrapolate.py b/lib/spack/spack/test/url_extrapolate.py new file mode 100644 index 0000000000..514d119deb --- /dev/null +++ b/lib/spack/spack/test/url_extrapolate.py @@ -0,0 +1,90 @@ +############################################################################## +# 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 +############################################################################## +"""\ +Tests ability of spack to extrapolate URL versions from existing versions. +""" +import spack +import spack.url as url +from spack.spec import Spec +from spack.version import ver +from spack.test.mock_packages_test import * + + +class UrlExtrapolateTest(MockPackagesTest): + + def test_known_version(self): + d = spack.db.get('dyninst') + + self.assertEqual( + d.url_for_version('8.2'), 'http://www.paradyn.org/release8.2/DyninstAPI-8.2.tgz') + self.assertEqual( + d.url_for_version('8.1.2'), 'http://www.paradyn.org/release8.1.2/DyninstAPI-8.1.2.tgz') + self.assertEqual( + d.url_for_version('8.1.1'), 'http://www.paradyn.org/release8.1/DyninstAPI-8.1.1.tgz') + + + def test_extrapolate_version(self): + d = spack.db.get('dyninst') + + # Nearest URL for 8.1.1.5 is 8.1.1, and the URL there is + # release8.1/DyninstAPI-8.1.1.tgz. Only the last part matches + # the version, so only extrapolate the last part. Obviously + # dyninst has ambiguous URL versions, but we want to make sure + # extrapolation works in a well-defined way. + self.assertEqual( + d.url_for_version('8.1.1.5'), 'http://www.paradyn.org/release8.1/DyninstAPI-8.1.1.5.tgz') + + # 8.2 matches both the release8.2 component and the DyninstAPI-8.2 component. + # Extrapolation should replace both with the new version. + self.assertEqual( + d.url_for_version('8.2.3'), 'http://www.paradyn.org/release8.2.3/DyninstAPI-8.2.3.tgz') + + + def test_with_package(self): + d = spack.db.get('dyninst@8.2') + self.assertEqual(d.fetcher.url, 'http://www.paradyn.org/release8.2/DyninstAPI-8.2.tgz') + + d = spack.db.get('dyninst@8.1.2') + self.assertEqual(d.fetcher.url, 'http://www.paradyn.org/release8.1.2/DyninstAPI-8.1.2.tgz') + + d = spack.db.get('dyninst@8.1.1') + self.assertEqual(d.fetcher.url, 'http://www.paradyn.org/release8.1/DyninstAPI-8.1.1.tgz') + + + def test_concrete_package(self): + s = Spec('dyninst@8.2') + s.concretize() + d = spack.db.get(s) + self.assertEqual(d.fetcher.url, 'http://www.paradyn.org/release8.2/DyninstAPI-8.2.tgz') + + s = Spec('dyninst@8.1.2') + s.concretize() + d = spack.db.get(s) + self.assertEqual(d.fetcher.url, 'http://www.paradyn.org/release8.1.2/DyninstAPI-8.1.2.tgz') + + s = Spec('dyninst@8.1.1') + s.concretize() + d = spack.db.get(s) + self.assertEqual(d.fetcher.url, 'http://www.paradyn.org/release8.1/DyninstAPI-8.1.1.tgz') diff --git a/lib/spack/spack/test/url_parse.py b/lib/spack/spack/test/url_parse.py index a03d6098f1..7a4d201d90 100644 --- a/lib/spack/spack/test/url_parse.py +++ b/lib/spack/spack/test/url_parse.py @@ -281,11 +281,16 @@ class UrlParseTest(unittest.TestCase): 'synergy', '1.3.6p2', 'http://synergy.googlecode.com/files/synergy-1.3.6p2-MacOSX-Universal.zip') - def test_mvapich2_version(self): + def test_mvapich2_19_version(self): self.check( 'mvapich2', '1.9', 'http://mvapich.cse.ohio-state.edu/download/mvapich2/mv2/mvapich2-1.9.tgz') + def test_mvapich2_19_version(self): + self.check( + 'mvapich2', '2.0', + 'http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.0.tar.gz') + def test_hdf5_version(self): self.check( 'hdf5', '1.8.13', diff --git a/var/spack/mock_packages/dyninst/package.py b/var/spack/mock_packages/dyninst/package.py index 7657e2c33f..7998578da1 100644 --- a/var/spack/mock_packages/dyninst/package.py +++ b/var/spack/mock_packages/dyninst/package.py @@ -26,11 +26,14 @@ from spack import * class Dyninst(Package): homepage = "https://paradyn.org" - url = "http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1.2/DyninstAPI-8.1.2.tgz" - list_url = "http://www.dyninst.org/downloads/dyninst-8.x" + url = "http://www.paradyn.org/release8.1/DyninstAPI-8.1.1.tgz" - version('8.1.2', 'bf03b33375afa66fe0efa46ce3f4b17a') - version('8.1.1', '1f8743e3a5662b25ce64a7edf647e77d') + version('8.2', 'cxyzab', + url='http://www.paradyn.org/release8.2/DyninstAPI-8.2.tgz') + version('8.1.2', 'bcxyza', + url='http://www.paradyn.org/release8.1.2/DyninstAPI-8.1.2.tgz') + version('8.1.1', 'abcxyz', + url='http://www.paradyn.org/release8.1/DyninstAPI-8.1.1.tgz') depends_on("libelf") depends_on("libdwarf") -- cgit v1.2.3-70-g09d2