Overhaul Spack's URL parsing (#2972)

* Remove fake URLs from Spack

* Ignore long lines for URLs that start with ftp:

* Preliminary changes to version regexes

* New redesign of version regexes

* Allow letters in version-only

* Fix detection of versions that end in Final

* Rearrange a few regexes and add examples

* Add tests for common download repositories

* Add test cases for common tarball naming schemes

* Finalize version regexes

* spack url test -> spack url summary

* Clean up comments

* Rearrange suffix checks

* Use query strings for name detection

* Remove no longer necessary url_for_version functions

* Strip off extraneous information after package name

* Add one more test

* Dot in square brackets does not need to be escaped

* Move renaming outside of parse_name_offset

* Fix versions for a couple more packages

* Fix flake8 and doc tests

* Correctly parse Python, Lua, and Bio++ package names

* Use effective URLs for mfem

* Add checksummed version to mitos

* Remove url_for_version from STAR-CCM+ package

* Revert changes to version numbers with underscores and dashes

* Fix name detection for tbb

* Correctly parse Ruby gems

* Reverted mfem back to shortened URLs.

* Updated instructions for better security

* Remove preferred=True from newest version

* Add tests for new `spack url list` flags

* Add tests for strip_name_suffixes

* Add unit tests for version separators

* Fix bugs related to parseable name but in parseable version

* Remove dead code, update docstring

* Ignore 'binary' at end of version string

* Remove platform from version

* Flip libedit version numbers

* Re-support weird NCO alpha/beta versions

* Rebase and remove one new fake URL

* Add / to beginning of regex to avoid picking up similarly named packages

* Ignore weird tar versions

* Fix bug in url parse --spider when no versions found

* Less strict version matching for spack versions

* Don't rename Python packages

* Be a little more selective, version must begin with a digit

* Re-add fake URLs

* Fix up several other packages

* Ignore more file endings

* Add parsing support for Miniconda

* Update tab completion

* XFAILS are now PASSES for 2 web tests
This commit is contained in:
Adam J. Stewart 2017-04-03 17:34:16 -05:00 committed by Todd Gamblin
parent 7e9777f294
commit 50df071ad9
80 changed files with 1357 additions and 839 deletions

View file

@ -447,16 +447,16 @@ the string that it detected to be the name and version. The
``--incorrect-name`` and ``--incorrect-version`` flags can be used to ``--incorrect-name`` and ``--incorrect-version`` flags can be used to
print URLs that were not being parsed correctly. print URLs that were not being parsed correctly.
"""""""""""""""""" """""""""""""""""""""
``spack url test`` ``spack url summary``
"""""""""""""""""" """""""""""""""""""""
This command attempts to parse every URL for every package in Spack This command attempts to parse every URL for every package in Spack
and prints a summary of how many of them are being correctly parsed. and prints a summary of how many of them are being correctly parsed.
It also prints a histogram showing which regular expressions are being It also prints a histogram showing which regular expressions are being
matched and how frequently: matched and how frequently:
.. command-output:: spack url test .. command-output:: spack url summary
This command is essential for anyone adding or changing the regular This command is essential for anyone adding or changing the regular
expressions that parse names and versions. By running this command expressions that parse names and versions. By running this command

View file

@ -31,13 +31,13 @@
import spack import spack
import spack.cmd import spack.cmd
import spack.cmd.checksum import spack.cmd.checksum
import spack.url
import spack.util.web import spack.util.web
from llnl.util.filesystem import mkdirp from llnl.util.filesystem import mkdirp
from spack.repository import Repo from spack.repository import Repo
from spack.spec import Spec from spack.spec import Spec
from spack.util.executable import which from spack.util.executable import which
from spack.util.naming import * from spack.util.naming import *
from spack.url import *
description = "create a new package file" description = "create a new package file"
@ -382,6 +382,10 @@ class BuildSystemGuesser:
can take a peek at the fetched tarball and discern the build system it uses can take a peek at the fetched tarball and discern the build system it uses
""" """
def __init__(self):
"""Sets the default build system."""
self.build_system = 'generic'
def __call__(self, stage, url): def __call__(self, stage, url):
"""Try to guess the type of build system used by a project based on """Try to guess the type of build system used by a project based on
the contents of its archive or the URL it was downloaded from.""" the contents of its archive or the URL it was downloaded from."""
@ -427,14 +431,11 @@ def __call__(self, stage, url):
# Determine the build system based on the files contained # Determine the build system based on the files contained
# in the archive. # in the archive.
build_system = 'generic'
for pattern, bs in clues: for pattern, bs in clues:
if any(re.search(pattern, l) for l in lines): if any(re.search(pattern, l) for l in lines):
build_system = bs self.build_system = bs
break break
self.build_system = build_system
def get_name(args): def get_name(args):
"""Get the name of the package based on the supplied arguments. """Get the name of the package based on the supplied arguments.
@ -458,9 +459,9 @@ def get_name(args):
elif args.url: elif args.url:
# Try to guess the package name based on the URL # Try to guess the package name based on the URL
try: try:
name = spack.url.parse_name(args.url) name = parse_name(args.url)
tty.msg("This looks like a URL for {0}".format(name)) tty.msg("This looks like a URL for {0}".format(name))
except spack.url.UndetectableNameError: except UndetectableNameError:
tty.die("Couldn't guess a name for this package.", tty.die("Couldn't guess a name for this package.",
" Please report this bug. In the meantime, try running:", " Please report this bug. In the meantime, try running:",
" `spack create --name <name> <url>`") " `spack create --name <name> <url>`")
@ -515,11 +516,16 @@ def get_versions(args, name):
if args.url: if args.url:
# Find available versions # Find available versions
url_dict = spack.util.web.find_versions_of_archive(args.url) try:
url_dict = spack.util.web.find_versions_of_archive(args.url)
except UndetectableVersionError:
# Use fake versions
tty.warn("Couldn't detect version in: {0}".format(args.url))
return versions, guesser
if not url_dict: if not url_dict:
# If no versions were found, revert to what the user provided # If no versions were found, revert to what the user provided
version = spack.url.parse_version(args.url) version = parse_version(args.url)
url_dict = {version: args.url} url_dict = {version: args.url}
versions = spack.cmd.checksum.get_checksums( versions = spack.cmd.checksum.get_checksums(
@ -611,6 +617,7 @@ def create(parser, args):
url = get_url(args) url = get_url(args)
versions, guesser = get_versions(args, name) versions, guesser = get_versions(args, name)
build_system = get_build_system(args, guesser) build_system = get_build_system(args, guesser)
name = simplify_name(name)
# Create the package template object # Create the package template object
PackageClass = templates[build_system] PackageClass = templates[build_system]

View file

@ -70,7 +70,7 @@
# exemptions applied to all files. # exemptions applied to all files.
r'.py$': { r'.py$': {
# Exempt lines with URLs from overlong line errors. # Exempt lines with URLs from overlong line errors.
501: [r'(https?|file)\:'] 501: [r'(https?|ftp|file)\:']
}, },
} }

View file

@ -31,6 +31,7 @@
from llnl.util import tty from llnl.util import tty
from spack.url import * from spack.url import *
from spack.util.web import find_versions_of_archive from spack.util.web import find_versions_of_archive
from spack.util.naming import simplify_name
description = "debugging tool for url parsing" description = "debugging tool for url parsing"
@ -65,20 +66,27 @@ def setup_parser(subparser):
excl_args.add_argument( excl_args.add_argument(
'-n', '--incorrect-name', action='store_true', '-n', '--incorrect-name', action='store_true',
help='only list urls for which the name was incorrectly parsed') help='only list urls for which the name was incorrectly parsed')
excl_args.add_argument(
'-N', '--correct-name', action='store_true',
help='only list urls for which the name was correctly parsed')
excl_args.add_argument( excl_args.add_argument(
'-v', '--incorrect-version', action='store_true', '-v', '--incorrect-version', action='store_true',
help='only list urls for which the version was incorrectly parsed') help='only list urls for which the version was incorrectly parsed')
excl_args.add_argument(
'-V', '--correct-version', action='store_true',
help='only list urls for which the version was correctly parsed')
# Test # Summary
sp.add_parser( sp.add_parser(
'test', help='print a summary of how well we are parsing package urls') 'summary',
help='print a summary of how well we are parsing package urls')
def url(parser, args): def url(parser, args):
action = { action = {
'parse': url_parse, 'parse': url_parse,
'list': url_list, 'list': url_list,
'test': url_test 'summary': url_summary
} }
action[args.subcommand](args) action[args.subcommand](args)
@ -116,6 +124,10 @@ def url_parse(args):
tty.msg('Spidering for versions:') tty.msg('Spidering for versions:')
versions = find_versions_of_archive(url) versions = find_versions_of_archive(url)
if not versions:
print(' Found no versions for {0}'.format(name))
return
max_len = max(len(str(v)) for v in versions) max_len = max(len(str(v)) for v in versions)
for v in sorted(versions): for v in sorted(versions):
@ -145,7 +157,7 @@ def url_list(args):
return len(urls) return len(urls)
def url_test(args): def url_summary(args):
# Collect statistics on how many URLs were correctly parsed # Collect statistics on how many URLs were correctly parsed
total_urls = 0 total_urls = 0
correct_names = 0 correct_names = 0
@ -205,19 +217,19 @@ def url_test(args):
correct_versions, total_urls, correct_versions / total_urls)) correct_versions, total_urls, correct_versions / total_urls))
print() print()
tty.msg('Statistics on name regular expresions:') tty.msg('Statistics on name regular expressions:')
print() print()
print(' Index Count Regular Expresion') print(' Index Count Regular Expression')
for ni in name_regex_dict: for ni in name_regex_dict:
print(' {0:>3}: {1:>6} r{2!r}'.format( print(' {0:>3}: {1:>6} r{2!r}'.format(
ni, name_count_dict[ni], name_regex_dict[ni])) ni, name_count_dict[ni], name_regex_dict[ni]))
print() print()
tty.msg('Statistics on version regular expresions:') tty.msg('Statistics on version regular expressions:')
print() print()
print(' Index Count Regular Expresion') print(' Index Count Regular Expression')
for vi in version_regex_dict: for vi in version_regex_dict:
print(' {0:>3}: {1:>6} r{2!r}'.format( print(' {0:>3}: {1:>6} r{2!r}'.format(
vi, version_count_dict[vi], version_regex_dict[vi])) vi, version_count_dict[vi], version_regex_dict[vi]))
@ -257,22 +269,38 @@ def url_list_parsing(args, urls, url, pkg):
:rtype: set :rtype: set
""" """
if url: if url:
if args.incorrect_name: if args.correct_name or args.incorrect_name:
# Only add URLs whose name was incorrectly parsed # Attempt to parse the name
try: try:
name = parse_name(url) name = parse_name(url)
if not name_parsed_correctly(pkg, name): if (args.correct_name and
name_parsed_correctly(pkg, name)):
# Add correctly parsed URLs
urls.add(url)
elif (args.incorrect_name and
not name_parsed_correctly(pkg, name)):
# Add incorrectly parsed URLs
urls.add(url) urls.add(url)
except UndetectableNameError: except UndetectableNameError:
urls.add(url) if args.incorrect_name:
elif args.incorrect_version: # Add incorrectly parsed URLs
# Only add URLs whose version was incorrectly parsed urls.add(url)
elif args.correct_version or args.incorrect_version:
# Attempt to parse the version
try: try:
version = parse_version(url) version = parse_version(url)
if not version_parsed_correctly(pkg, version): if (args.correct_version and
version_parsed_correctly(pkg, version)):
# Add correctly parsed URLs
urls.add(url)
elif (args.incorrect_version and
not version_parsed_correctly(pkg, version)):
# Add incorrectly parsed URLs
urls.add(url) urls.add(url)
except UndetectableVersionError: except UndetectableVersionError:
urls.add(url) if args.incorrect_version:
# Add incorrectly parsed URLs
urls.add(url)
else: else:
urls.add(url) urls.add(url)
@ -289,6 +317,8 @@ def name_parsed_correctly(pkg, name):
""" """
pkg_name = pkg.name pkg_name = pkg.name
name = simplify_name(name)
# After determining a name, `spack create` determines a build system. # After determining a name, `spack create` determines a build system.
# Some build systems prepend a special string to the front of the name. # Some build systems prepend a special string to the front of the name.
# Since this can't be guessed from the URL, it would be unfair to say # Since this can't be guessed from the URL, it would be unfair to say
@ -311,9 +341,33 @@ def version_parsed_correctly(pkg, version):
:returns: True if the name was correctly parsed, else False :returns: True if the name was correctly parsed, else False
:rtype: bool :rtype: bool
""" """
version = remove_separators(version)
# If the version parsed from the URL is listed in a version() # If the version parsed from the URL is listed in a version()
# directive, we assume it was correctly parsed # directive, we assume it was correctly parsed
for pkg_version in pkg.versions: for pkg_version in pkg.versions:
if str(pkg_version) == str(version): pkg_version = remove_separators(pkg_version)
if pkg_version == version:
return True return True
return False return False
def remove_separators(version):
"""Removes separator characters ('.', '_', and '-') from a version.
A version like 1.2.3 may be displayed as 1_2_3 in the URL.
Make sure 1.2.3, 1-2-3, 1_2_3, and 123 are considered equal.
Unfortunately, this also means that 1.23 and 12.3 are equal.
:param version: A version
:type version: str or Version
:returns: The version with all separator characters removed
:rtype: str
"""
version = str(version)
version = version.replace('.', '')
version = version.replace('_', '')
version = version.replace('-', '')
return version

View file

@ -53,6 +53,6 @@ def versions(parser, args):
tty.debug("Check the list_url and list_depth attribute on the " tty.debug("Check the list_url and list_depth attribute on the "
"package to help Spack find versions.") "package to help Spack find versions.")
else: else:
print(" Found no unckecksummed versions for %s" % pkg.name) print(" Found no unchecksummed versions for %s" % pkg.name)
else: else:
colify(sorted(remote_versions, reverse=True), indent=2) colify(sorted(remote_versions, reverse=True), indent=2)

View file

@ -48,11 +48,12 @@ def test_name_parsed_correctly():
assert name_parsed_correctly(MyPackage('r-devtools', []), 'devtools') assert name_parsed_correctly(MyPackage('r-devtools', []), 'devtools')
assert name_parsed_correctly(MyPackage('py-numpy', []), 'numpy') assert name_parsed_correctly(MyPackage('py-numpy', []), 'numpy')
assert name_parsed_correctly(MyPackage('octave-splines', []), 'splines') assert name_parsed_correctly(MyPackage('octave-splines', []), 'splines')
assert name_parsed_correctly(MyPackage('imagemagick', []), 'ImageMagick') # noqa
assert name_parsed_correctly(MyPackage('th-data', []), 'TH.data')
# Expected False # Expected False
assert not name_parsed_correctly(MyPackage('', []), 'hdf5') assert not name_parsed_correctly(MyPackage('', []), 'hdf5')
assert not name_parsed_correctly(MyPackage('hdf5', []), '') assert not name_parsed_correctly(MyPackage('hdf5', []), '')
assert not name_parsed_correctly(MyPackage('imagemagick', []), 'ImageMagick') # noqa
assert not name_parsed_correctly(MyPackage('yaml-cpp', []), 'yamlcpp') assert not name_parsed_correctly(MyPackage('yaml-cpp', []), 'yamlcpp')
assert not name_parsed_correctly(MyPackage('yamlcpp', []), 'yaml-cpp') assert not name_parsed_correctly(MyPackage('yamlcpp', []), 'yaml-cpp')
assert not name_parsed_correctly(MyPackage('r-py-parser', []), 'parser') assert not name_parsed_correctly(MyPackage('r-py-parser', []), 'parser')
@ -64,6 +65,8 @@ def test_version_parsed_correctly():
assert version_parsed_correctly(MyPackage('', ['1.2.3']), '1.2.3') assert version_parsed_correctly(MyPackage('', ['1.2.3']), '1.2.3')
assert version_parsed_correctly(MyPackage('', ['5.4a', '5.4b']), '5.4a') assert version_parsed_correctly(MyPackage('', ['5.4a', '5.4b']), '5.4a')
assert version_parsed_correctly(MyPackage('', ['5.4a', '5.4b']), '5.4b') assert version_parsed_correctly(MyPackage('', ['5.4a', '5.4b']), '5.4b')
assert version_parsed_correctly(MyPackage('', ['1.63.0']), '1_63_0')
assert version_parsed_correctly(MyPackage('', ['0.94h']), '094h')
# Expected False # Expected False
assert not version_parsed_correctly(MyPackage('', []), '1.2.3') assert not version_parsed_correctly(MyPackage('', []), '1.2.3')
@ -95,7 +98,7 @@ def test_url_list(parser):
colored_urls = url_list(args) colored_urls = url_list(args)
assert colored_urls == total_urls assert colored_urls == total_urls
# The following two options should print fewer URLs than the default. # The following options should print fewer URLs than the default.
# If they print the same number of URLs, something is horribly broken. # If they print the same number of URLs, something is horribly broken.
# If they say we missed 0 URLs, something is probably broken too. # If they say we missed 0 URLs, something is probably broken too.
args = parser.parse_args(['list', '--incorrect-name']) args = parser.parse_args(['list', '--incorrect-name'])
@ -106,11 +109,19 @@ def test_url_list(parser):
incorrect_version_urls = url_list(args) incorrect_version_urls = url_list(args)
assert 0 < incorrect_version_urls < total_urls assert 0 < incorrect_version_urls < total_urls
args = parser.parse_args(['list', '--correct-name'])
correct_name_urls = url_list(args)
assert 0 < correct_name_urls < total_urls
def test_url_test(parser): args = parser.parse_args(['list', '--correct-version'])
args = parser.parse_args(['test']) correct_version_urls = url_list(args)
assert 0 < correct_version_urls < total_urls
def test_url_summary(parser):
args = parser.parse_args(['summary'])
(total_urls, correct_names, correct_versions, (total_urls, correct_names, correct_versions,
name_count_dict, version_count_dict) = url_test(args) name_count_dict, version_count_dict) = url_summary(args)
assert 0 < correct_names <= sum(name_count_dict.values()) <= total_urls # noqa assert 0 < correct_names <= sum(name_count_dict.values()) <= total_urls # noqa
assert 0 < correct_versions <= sum(version_count_dict.values()) <= total_urls # noqa assert 0 < correct_versions <= sum(version_count_dict.values()) <= total_urls # noqa

View file

@ -1,101 +0,0 @@
##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/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 Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, 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 Lesser 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 unittest
import spack.url as url
class UrlExtrapolateTest(unittest.TestCase):
def check_url(self, base, version, new_url):
self.assertEqual(url.substitute_version(base, version), new_url)
def test_libelf_version(self):
base = "http://www.mr511.de/software/libelf-0.8.13.tar.gz"
self.check_url(base, '0.8.13', base)
self.check_url(
base, '0.8.12', "http://www.mr511.de/software/libelf-0.8.12.tar.gz")
self.check_url(
base, '0.3.1', "http://www.mr511.de/software/libelf-0.3.1.tar.gz")
self.check_url(
base, '1.3.1b', "http://www.mr511.de/software/libelf-1.3.1b.tar.gz")
def test_libdwarf_version(self):
base = "http://www.prevanders.net/libdwarf-20130729.tar.gz"
self.check_url(base, '20130729', base)
self.check_url(
base, '8.12', "http://www.prevanders.net/libdwarf-8.12.tar.gz")
def test_dyninst_version(self):
# Dyninst has a version twice in the URL.
base = "http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1.2/DyninstAPI-8.1.2.tgz"
self.check_url(base, '8.1.2', base)
self.check_url(base, '8.2',
"http://www.dyninst.org/sites/default/files/downloads/dyninst/8.2/DyninstAPI-8.2.tgz")
self.check_url(base, '8.3.1',
"http://www.dyninst.org/sites/default/files/downloads/dyninst/8.3.1/DyninstAPI-8.3.1.tgz")
def test_partial_version_prefix(self):
# Test now with a partial prefix earlier in the URL -- this is
# hard to figure out so Spack only substitutes the last
# instance of the version.
base = "http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1/DyninstAPI-8.1.2.tgz"
self.check_url(base, '8.1.2', base)
self.check_url(base, '8.1.4',
"http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1/DyninstAPI-8.1.4.tgz")
self.check_url(base, '8.2',
"http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1/DyninstAPI-8.2.tgz")
self.check_url(base, '8.3.1',
"http://www.dyninst.org/sites/default/files/downloads/dyninst/8.1/DyninstAPI-8.3.1.tgz")
def test_scalasca_partial_version(self):
# Note that this probably doesn't actually work, but sites are
# inconsistent about their directory structure, so it's not
# clear what is right. This test is for consistency and to
# document behavior. If you figure out a good way to handle
# this case, fix the tests too.
self.check_url('http://apps.fz-juelich.de/scalasca/releases/cube/4.3/dist/cube-4.3-TP1.tar.gz', '8.3.1',
'http://apps.fz-juelich.de/scalasca/releases/cube/4.3/dist/cube-8.3.1.tar.gz')
self.check_url('http://apps.fz-juelich.de/scalasca/releases/cube/4.3/dist/cube-4.3-TP1.tar.gz', '8.3.1',
'http://apps.fz-juelich.de/scalasca/releases/cube/4.3/dist/cube-8.3.1.tar.gz')
def test_mpileaks_version(self):
self.check_url('https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz', '2.1.3',
'https://github.com/hpc/mpileaks/releases/download/v2.1.3/mpileaks-2.1.3.tar.gz')
def test_gcc(self):
self.check_url('http://open-source-box.org/gcc/gcc-4.9.2/gcc-4.9.2.tar.bz2', '4.7',
'http://open-source-box.org/gcc/gcc-4.7/gcc-4.7.tar.bz2')
self.check_url('http://open-source-box.org/gcc/gcc-4.4.7/gcc-4.4.7.tar.bz2', '4.4.7',
'http://open-source-box.org/gcc/gcc-4.4.7/gcc-4.4.7.tar.bz2')
def test_github_raw(self):
self.check_url('https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true', '2.0.7',
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true')
self.check_url('https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true', '4.7',
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v4.7.tgz?raw=true')

View file

@ -22,92 +22,633 @@
# License along with this program; if not, write to the Free Software # License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
"""\ """Tests Spack's ability to parse the name and version of a package
This file has a bunch of versions tests taken from the excellent version based on its URL."""
detection in Homebrew.
""" import os
import unittest import unittest
import spack.url as url from spack.url import *
class UrlParseTest(unittest.TestCase): class UrlStripVersionSuffixesTest(unittest.TestCase):
"""Tests for spack.url.strip_version_suffixes"""
def check(self, before, after):
stripped = strip_version_suffixes(before)
self.assertEqual(stripped, after)
def test_no_suffix(self):
self.check('rgb-1.0.6',
'rgb-1.0.6')
def test_misleading_prefix(self):
self.check('jpegsrc.v9b',
'jpegsrc.v9b')
self.check('turbolinux702',
'turbolinux702')
self.check('converge_install_2.3.16',
'converge_install_2.3.16')
# Download type
def test_src(self):
self.check('apache-ant-1.9.7-src',
'apache-ant-1.9.7')
self.check('go1.7.4.src',
'go1.7.4')
def test_source(self):
self.check('bowtie2-2.2.5-source',
'bowtie2-2.2.5')
self.check('grib_api-1.17.0-Source',
'grib_api-1.17.0')
def test_full(self):
self.check('julia-0.4.3-full',
'julia-0.4.3')
def test_bin(self):
self.check('apache-maven-3.3.9-bin',
'apache-maven-3.3.9')
def test_binary(self):
self.check('Jmol-14.8.0-binary',
'Jmol-14.8.0')
def test_gem(self):
self.check('rubysl-date-2.0.9.gem',
'rubysl-date-2.0.9')
def test_tar(self):
self.check('gromacs-4.6.1-tar',
'gromacs-4.6.1')
def test_sh(self):
self.check('Miniconda2-4.3.11-Linux-x86_64.sh',
'Miniconda2-4.3.11')
# Download version
def test_stable(self):
self.check('libevent-2.0.21-stable',
'libevent-2.0.21')
def test_final(self):
self.check('2.6.7-final',
'2.6.7')
def test_rel(self):
self.check('v1.9.5.1rel',
'v1.9.5.1')
def test_orig(self):
self.check('dash_0.5.5.1.orig',
'dash_0.5.5.1')
def test_plus(self):
self.check('ncbi-blast-2.6.0+-src',
'ncbi-blast-2.6.0')
# License
def test_gpl(self):
self.check('cppad-20170114.gpl',
'cppad-20170114')
# OS
def test_linux(self):
self.check('astyle_2.04_linux',
'astyle_2.04')
def test_unix(self):
self.check('install-tl-unx',
'install-tl')
def test_macos(self):
self.check('astyle_1.23_macosx',
'astyle_1.23')
self.check('haxe-2.08-osx',
'haxe-2.08')
# PyPI
def test_wheel(self):
self.check('entrypoints-0.2.2-py2.py3-none-any.whl',
'entrypoints-0.2.2')
self.check('numpy-1.12.0-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl', # noqa
'numpy-1.12.0')
def test_exe(self):
self.check('PyYAML-3.12.win-amd64-py3.5.exe',
'PyYAML-3.12')
# Combinations of multiple patterns
def test_complex_all(self):
self.check('p7zip_9.04_src_all',
'p7zip_9.04')
def test_complex_run(self):
self.check('cuda_8.0.44_linux.run',
'cuda_8.0.44')
def test_complex_file(self):
self.check('ack-2.14-single-file',
'ack-2.14')
def test_complex_jar(self):
self.check('antlr-3.4-complete.jar',
'antlr-3.4')
def test_complex_oss(self):
self.check('tbb44_20160128oss_src_0',
'tbb44_20160128')
def test_complex_darwin(self):
self.check('ghc-7.0.4-x86_64-apple-darwin',
'ghc-7.0.4')
self.check('ghc-7.0.4-i386-apple-darwin',
'ghc-7.0.4')
def test_complex_arch(self):
self.check('VizGlow_v2.2alpha17-R21November2016-Linux-x86_64-Install',
'VizGlow_v2.2alpha17-R21November2016')
self.check('jdk-8u92-linux-x64',
'jdk-8u92')
self.check('cuda_6.5.14_linux_64.run',
'cuda_6.5.14')
def test_complex_with(self):
self.check('mafft-7.221-with-extensions-src',
'mafft-7.221')
self.check('spark-2.0.0-bin-without-hadoop',
'spark-2.0.0')
def test_complex_public(self):
self.check('dakota-6.3-public.src',
'dakota-6.3')
def test_complex_universal(self):
self.check('synergy-1.3.6p2-MacOSX-Universal',
'synergy-1.3.6p2')
class UrlStripNameSuffixesTest(unittest.TestCase):
"""Tests for spack.url.strip_name_suffixes"""
def check(self, before, version, after):
stripped = strip_name_suffixes(before, version)
self.assertEqual(stripped, after)
def test_no_suffix(self):
self.check('rgb-1.0.6', '1.0.6',
'rgb')
self.check('nauty26r7', '26r7',
'nauty')
# Download type
def test_install(self):
self.check('converge_install_2.3.16', '2.3.16',
'converge')
def test_src(self):
self.check('jpegsrc.v9b', '9b',
'jpeg')
def test_std(self):
self.check('ghostscript-fonts-std-8.11', '8.11',
'ghostscript-fonts')
# Download version
def test_snapshot(self):
self.check('gts-snapshot-121130', '121130',
'gts')
def test_distrib(self):
self.check('zoltan_distrib_v3.83', '3.83',
'zoltan')
# VCS
def test_bazaar(self):
self.check('libvterm-0+bzr681', '681',
'libvterm')
# License
def test_gpl(self):
self.check('PyQt-x11-gpl-4.11.3', '4.11.3',
'PyQt-x11')
class UrlParseOffsetTest(unittest.TestCase):
def check(self, name, noffset, ver, voffset, path):
# Make sure parse_name_offset and parse_name_version are working
v, vstart, vlen, vi, vre = parse_version_offset(path)
n, nstart, nlen, ni, nre = parse_name_offset(path, v)
self.assertEqual(n, name)
self.assertEqual(v, ver)
self.assertEqual(nstart, noffset)
self.assertEqual(vstart, voffset)
def test_name_in_path(self):
self.check(
'antlr', 25, '2.7.7', 40,
'https://github.com/antlr/antlr/tarball/v2.7.7')
def test_name_in_stem(self):
self.check(
'gmp', 32, '6.0.0a', 36,
'https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2')
def test_name_in_suffix(self):
# Don't think I've ever seen one of these before
# We don't look for it, so it would probably fail anyway
pass
def test_version_in_path(self):
self.check(
'nextflow', 31, '0.20.1', 59,
'https://github.com/nextflow-io/nextflow/releases/download/v0.20.1/nextflow')
def test_version_in_stem(self):
self.check(
'zlib', 24, '1.2.10', 29,
'http://zlib.net/fossils/zlib-1.2.10.tar.gz')
self.check(
'slepc', 51, '3.6.2', 57,
'http://slepc.upv.es/download/download.php?filename=slepc-3.6.2.tar.gz')
self.check(
'cloog', 61, '0.18.1', 67,
'http://www.bastoul.net/cloog/pages/download/count.php3?url=./cloog-0.18.1.tar.gz')
self.check(
'libxc', 58, '2.2.2', 64,
'http://www.tddft.org/programs/octopus/down.php?file=libxc/libxc-2.2.2.tar.gz')
def test_version_in_suffix(self):
self.check(
'swiftsim', 36, '0.3.0', 76,
'http://gitlab.cosma.dur.ac.uk/swift/swiftsim/repository/archive.tar.gz?ref=v0.3.0')
self.check(
'sionlib', 30, '1.7.1', 59,
'http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1')
def test_regex_in_name(self):
self.check(
'voro++', 40, '0.4.6', 47,
'http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz')
class UrlParseNameAndVersionTest(unittest.TestCase):
def assert_not_detected(self, string): def assert_not_detected(self, string):
self.assertRaises( self.assertRaises(
url.UndetectableVersionError, url.parse_name_and_version, string) UndetectableVersionError, parse_name_and_version, string)
def check(self, name, v, string, **kwargs): def check(self, name, v, string, **kwargs):
# Make sure correct name and version are extracted. # Make sure correct name and version are extracted.
parsed_name, parsed_v = url.parse_name_and_version(string) parsed_name, parsed_v = parse_name_and_version(string)
self.assertEqual(parsed_name, name) self.assertEqual(parsed_name, name)
self.assertEqual(parsed_v, url.Version(v)) self.assertEqual(parsed_v, Version(v))
# Some URLs (like boost) are special and need to override the
# built-in functionality.
if kwargs.get('no_check_url', False):
return
# Make sure Spack formulates the right URL when we try to # Make sure Spack formulates the right URL when we try to
# build one with a specific version. # build one with a specific version.
self.assertEqual(string, url.substitute_version(string, v)) self.assertEqual(string, substitute_version(string, v))
def test_wwwoffle_version(self): # Common Repositories
self.check(
'wwwoffle', '2.9h',
'http://www.gedanken.demon.co.uk/download-wwwoffle/wwwoffle-2.9h.tgz')
def test_version_sourceforge_download(self): def test_github_downloads(self):
# name/archive/ver.ver
self.check( self.check(
'foo-bar', '1.21', 'nco', '4.6.2',
'http://sourceforge.net/foo_bar-1.21.tar.gz/download') 'https://github.com/nco/nco/archive/4.6.2.tar.gz')
# name/archive/vver.ver
self.check( self.check(
'foo-bar', '1.21', 'vim', '8.0.0134',
'http://sf.net/foo_bar-1.21.tar.gz/download') 'https://github.com/vim/vim/archive/v8.0.0134.tar.gz')
# name/archive/name-ver.ver
self.check(
'oce', '0.18',
'https://github.com/tpaviot/oce/archive/OCE-0.18.tar.gz')
# name/releases/download/vver/name-ver.ver
self.check(
'libmesh', '1.0.0',
'https://github.com/libMesh/libmesh/releases/download/v1.0.0/libmesh-1.0.0.tar.bz2')
# name/tarball/vver.ver
self.check(
'git', '2.7.1',
'https://github.com/git/git/tarball/v2.7.1')
# name/zipball/vver.ver
self.check(
'git', '2.7.1',
'https://github.com/git/git/zipball/v2.7.1')
def test_gitlab_downloads(self):
# name/repository/archive.ext?ref=vver.ver
self.check(
'swiftsim', '0.3.0',
'http://gitlab.cosma.dur.ac.uk/swift/swiftsim/repository/archive.tar.gz?ref=v0.3.0')
# name/repository/archive.ext?ref=name-ver.ver
self.check(
'icet', '1.2.3',
'https://gitlab.kitware.com/icet/icet/repository/archive.tar.gz?ref=IceT-1.2.3')
def test_bitbucket_downloads(self):
# name/get/ver.ver
self.check(
'eigen', '3.2.7',
'https://bitbucket.org/eigen/eigen/get/3.2.7.tar.bz2')
# name/get/vver.ver
self.check(
'hoomd-blue', '1.3.3',
'https://bitbucket.org/glotzer/hoomd-blue/get/v1.3.3.tar.bz2')
# name/downloads/name-ver.ver
self.check(
'dolfin', '2016.1.0',
'https://bitbucket.org/fenics-project/dolfin/downloads/dolfin-2016.1.0.tar.gz')
def test_sourceforge_downloads(self):
# name-ver.ver
self.check(
'libpng', '1.6.27',
'http://download.sourceforge.net/libpng/libpng-1.6.27.tar.gz')
self.check(
'lcms2', '2.6',
'http://downloads.sourceforge.net/project/lcms/lcms/2.6/lcms2-2.6.tar.gz')
self.check(
'modules', '3.2.10',
'http://prdownloads.sourceforge.net/modules/modules-3.2.10.tar.gz')
# name-ver.ver.ext/download
self.check(
'glew', '2.0.0',
'https://sourceforge.net/projects/glew/files/glew/2.0.0/glew-2.0.0.tgz/download')
def test_cran_downloads(self):
# name.name_ver.ver-ver.ver
self.check(
'TH.data', '1.0-8',
'https://cran.r-project.org/src/contrib/TH.data_1.0-8.tar.gz')
self.check(
'knitr', '1.14',
'https://cran.rstudio.com/src/contrib/knitr_1.14.tar.gz')
self.check(
'devtools', '1.12.0',
'https://cloud.r-project.org/src/contrib/devtools_1.12.0.tar.gz')
def test_pypi_downloads(self):
# name.name_name-ver.ver
self.check(
'3to2', '1.1.1',
'https://pypi.python.org/packages/source/3/3to2/3to2-1.1.1.zip')
self.check(
'mpmath', '0.19',
'https://pypi.python.org/packages/source/m/mpmath/mpmath-all-0.19.tar.gz')
self.check(
'pandas', '0.16.0',
'https://pypi.python.org/packages/source/p/pandas/pandas-0.16.0.tar.gz#md5=bfe311f05dc0c351f8955fbd1e296e73')
self.check(
'sphinx_rtd_theme', '0.1.10a0',
'https://pypi.python.org/packages/da/6b/1b75f13d8aa3333f19c6cdf1f0bc9f52ea739cae464fbee050307c121857/sphinx_rtd_theme-0.1.10a0.tar.gz')
self.check(
'backports.ssl_match_hostname', '3.5.0.1',
'https://pypi.io/packages/source/b/backports.ssl_match_hostname/backports.ssl_match_hostname-3.5.0.1.tar.gz')
def test_bazaar_downloads(self):
self.check(
'libvterm', '681',
'http://www.leonerd.org.uk/code/libvterm/libvterm-0+bzr681.tar.gz')
# Common Tarball Formats
def test_version_only(self):
# ver.ver
self.check(
'eigen', '3.2.7',
'https://bitbucket.org/eigen/eigen/get/3.2.7.tar.bz2')
# ver.ver-ver
self.check(
'ImageMagick', '7.0.2-7',
'https://github.com/ImageMagick/ImageMagick/archive/7.0.2-7.tar.gz')
# vver.ver
self.check(
'CGNS', '3.3.0',
'https://github.com/CGNS/CGNS/archive/v3.3.0.tar.gz')
# vver_ver
self.check(
'luafilesystem', '1_6_3',
'https://github.com/keplerproject/luafilesystem/archive/v1_6_3.tar.gz')
def test_no_separators(self):
# namever
self.check(
'turbolinux', '702',
'file://{0}/turbolinux702.tar.gz'.format(os.getcwd()))
self.check(
'nauty', '26r7',
'http://pallini.di.uniroma1.it/nauty26r7.tar.gz')
def test_dashes_only(self):
# name-name-ver-ver
self.check(
'Trilinos', '12-10-1',
'https://github.com/trilinos/Trilinos/archive/trilinos-release-12-10-1.tar.gz')
self.check(
'panda', '2016-03-07',
'http://comopt.ifi.uni-heidelberg.de/software/PANDA/downloads/panda-2016-03-07.tar')
self.check(
'gts', '121130',
'http://gts.sourceforge.net/tarballs/gts-snapshot-121130.tar.gz')
self.check(
'cdd', '061a',
'http://www.cs.mcgill.ca/~fukuda/download/cdd/cdd-061a.tar.gz')
def test_underscores_only(self):
# name_name_ver_ver
self.check(
'tinyxml', '2_6_2',
'https://sourceforge.net/projects/tinyxml/files/tinyxml/2.6.2/tinyxml_2_6_2.tar.gz')
self.check(
'boost', '1_55_0',
'http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.bz2')
self.check(
'yorick', '2_2_04',
'https://github.com/dhmunro/yorick/archive/y_2_2_04.tar.gz')
# name_namever_ver
self.check(
'tbb', '44_20160413',
'https://www.threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb44_20160413oss_src.tgz')
def test_dots_only(self):
# name.name.ver.ver
self.check(
'prank', '150803',
'http://wasabiapp.org/download/prank/prank.source.150803.tgz')
self.check(
'jpeg', '9b',
'http://www.ijg.org/files/jpegsrc.v9b.tar.gz')
self.check(
'openjpeg', '2.1',
'https://github.com/uclouvain/openjpeg/archive/version.2.1.tar.gz')
# name.namever.ver
self.check(
'atlas', '3.11.34',
'http://sourceforge.net/projects/math-atlas/files/Developer%20%28unstable%29/3.11.34/atlas3.11.34.tar.bz2')
self.check(
'visit', '2.10.1',
'http://portal.nersc.gov/project/visit/releases/2.10.1/visit2.10.1.tar.gz')
self.check(
'geant', '4.10.01.p03',
'http://geant4.cern.ch/support/source/geant4.10.01.p03.tar.gz')
self.check(
'tcl', '8.6.5',
'http://prdownloads.sourceforge.net/tcl/tcl8.6.5-src.tar.gz')
def test_dash_dot(self):
# name-name-ver.ver
# digit in name
self.check(
'm4', '1.4.17',
'https://ftp.gnu.org/gnu/m4/m4-1.4.17.tar.gz')
# letter in version
self.check(
'gmp', '6.0.0a',
'https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2')
# version starts with 'v'
self.check(
'LaunchMON', '1.0.2',
'https://github.com/LLNL/LaunchMON/releases/download/v1.0.2/launchmon-v1.0.2.tar.gz')
# name-ver-ver.ver
self.check(
'libedit', '20150325-3.1',
'http://thrysoee.dk/editline/libedit-20150325-3.1.tar.gz')
def test_dash_underscore(self):
# name-name-ver_ver
self.check(
'icu4c', '57_1',
'http://download.icu-project.org/files/icu4c/57.1/icu4c-57_1-src.tgz')
def test_underscore_dot(self):
# name_name_ver.ver
self.check(
'superlu_dist', '4.1',
'http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_dist_4.1.tar.gz')
self.check(
'pexsi', '0.9.0',
'https://math.berkeley.edu/~linlin/pexsi/download/pexsi_v0.9.0.tar.gz')
# name_name.ver.ver
self.check(
'fer', '696',
'ftp://ftp.pmel.noaa.gov/ferret/pub/source/fer_source.v696.tar.gz')
def test_dash_dot_dash_dot(self):
# name-name-ver.ver-ver.ver
self.check(
'sowing', '1.1.23-p1',
'http://ftp.mcs.anl.gov/pub/petsc/externalpackages/sowing-1.1.23-p1.tar.gz')
self.check(
'bib2xhtml', '3.0-15-gf506',
'http://www.spinellis.gr/sw/textproc/bib2xhtml/bib2xhtml-v3.0-15-gf506.tar.gz')
# namever.ver-ver.ver
self.check(
'go', '1.4-bootstrap-20161024',
'https://storage.googleapis.com/golang/go1.4-bootstrap-20161024.tar.gz')
def test_underscore_dash_dot(self):
# name_name-ver.ver
self.check(
'the_silver_searcher', '0.32.0',
'http://geoff.greer.fm/ag/releases/the_silver_searcher-0.32.0.tar.gz')
self.check(
'sphinx_rtd_theme', '0.1.10a0',
'https://pypi.python.org/packages/source/s/sphinx_rtd_theme/sphinx_rtd_theme-0.1.10a0.tar.gz')
def test_dot_underscore_dot_dash_dot(self):
# name.name_ver.ver-ver.ver
self.check(
'TH.data', '1.0-8',
'https://cran.r-project.org/src/contrib/TH.data_1.0-8.tar.gz')
self.check(
'XML', '3.98-1.4',
'https://cran.r-project.org/src/contrib/XML_3.98-1.4.tar.gz')
def test_dash_dot_underscore_dot(self):
# name-name-ver.ver_ver.ver
self.check(
'pypar', '2.1.5_108',
'https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/pypar/pypar-2.1.5_108.tgz')
# name-namever.ver_ver.ver
self.check(
'STAR-CCM+', '11.06.010_02',
'file://{0}/STAR-CCM+11.06.010_02_linux-x86_64.tar.gz'.format(os.getcwd()))
# Weird URLS
def test_version_in_path(self):
# github.com/repo/name/releases/download/name-vver/name
self.check(
'nextflow', '0.20.1',
'https://github.com/nextflow-io/nextflow/releases/download/v0.20.1/nextflow')
def test_suffix_queries(self):
self.check(
'swiftsim', '0.3.0',
'http://gitlab.cosma.dur.ac.uk/swift/swiftsim/repository/archive.tar.gz?ref=v0.3.0')
self.check(
'sionlib', '1.7.1',
'http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1')
def test_stem_queries(self):
self.check(
'slepc', '3.6.2',
'http://slepc.upv.es/download/download.php?filename=slepc-3.6.2.tar.gz')
self.check(
'otf', '1.12.5salmon',
'http://wwwpub.zih.tu-dresden.de/%7Emlieber/dcount/dcount.php?package=otf&get=OTF-1.12.5salmon.tar.gz')
def test_single_character_name(self):
self.check(
'R', '3.3.2',
'https://cloud.r-project.org/src/base/R-3/R-3.3.2.tar.gz')
def test_single_digit_version(self):
pass
def test_name_starts_with_digit(self):
self.check(
'3to2', '1.1.1',
'https://pypi.python.org/packages/source/3/3to2/3to2-1.1.1.zip')
def plus_in_name(self):
self.check(
'gtk+', '2.24.31',
'http://ftp.gnome.org/pub/gnome/sources/gtk+/2.24/gtk+-2.24.31.tar.xz')
self.check(
'voro++', '0.4.6',
'http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz')
def test_no_version(self): def test_no_version(self):
self.assert_not_detected('http://example.com/blah.tar') self.assert_not_detected('http://www.netlib.org/blas/blast-forum/cblas.tgz')
self.assert_not_detected('foo') self.assert_not_detected('http://www.netlib.org/voronoi/triangle.zip')
def test_version_all_dots(self): def test_download_php(self):
# Name comes before download.php
self.check( self.check(
'foo-bar-la', '1.14', 'http://example.com/foo.bar.la.1.14.zip') 'sionlib', '1.7.1',
'http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1')
def test_version_underscore_separator(self): # Ignore download.php
self.check( self.check(
'grc', '1.1', 'slepc', '3.6.2',
'http://example.com/grc_1.1.tar.gz') 'http://slepc.upv.es/download/download.php?filename=slepc-3.6.2.tar.gz')
def test_boost_version_style(self):
self.check( self.check(
'boost', '1.39.0', 'ScientificPython', '2.8.1',
'http://example.com/boost_1_39_0.tar.bz2', 'https://sourcesup.renater.fr/frs/download.php/file/4411/ScientificPython-2.8.1.tar.gz')
no_check_url=True)
def test_erlang_version_style(self):
self.check(
'otp', 'R13B',
'http://erlang.org/download/otp_src_R13B.tar.gz')
def test_another_erlang_version_style(self):
self.check(
'otp', 'R15B01',
'https://github.com/erlang/otp/tarball/OTP_R15B01')
def test_yet_another_erlang_version_style(self):
self.check(
'otp', 'R15B03-1',
'https://github.com/erlang/otp/tarball/OTP_R15B03-1')
def test_p7zip_version_style(self):
self.check(
'p7zip', '9.04',
'http://kent.dl.sourceforge.net/sourceforge/p7zip/p7zip_9.04_src_all.tar.bz2')
def test_new_github_style(self):
self.check(
'libnet', '1.1.4',
'https://github.com/sam-github/libnet/tarball/libnet-1.1.4')
def test_gloox_beta_style(self): def test_gloox_beta_style(self):
self.check( self.check(
@ -119,85 +660,11 @@ def test_sphinx_beta_style(self):
'sphinx', '1.10-beta', 'sphinx', '1.10-beta',
'http://sphinxsearch.com/downloads/sphinx-1.10-beta.tar.gz') 'http://sphinxsearch.com/downloads/sphinx-1.10-beta.tar.gz')
def test_astyle_verson_style(self):
self.check(
'astyle', '1.23',
'http://kent.dl.sourceforge.net/sourceforge/astyle/astyle_1.23_macosx.tar.gz')
def test_version_dos2unix(self):
self.check(
'dos2unix', '3.1',
'http://www.sfr-fresh.com/linux/misc/dos2unix-3.1.tar.gz')
def test_version_internal_dash(self):
self.check(
'foo-arse', '1.1-2',
'http://example.com/foo-arse-1.1-2.tar.gz')
def test_version_single_digit(self):
self.check(
'foo-bar', '45',
'http://example.com/foo_bar.45.tar.gz')
def test_noseparator_single_digit(self):
self.check(
'foo-bar', '45',
'http://example.com/foo_bar45.tar.gz')
def test_version_developer_that_hates_us_format(self):
self.check(
'foo-bar-la', '1.2.3',
'http://example.com/foo-bar-la.1.2.3.tar.gz')
def test_version_regular(self):
self.check(
'foo-bar', '1.21',
'http://example.com/foo_bar-1.21.tar.gz')
def test_version_gitlab(self):
self.check(
'vtk', '7.0.0',
'https://gitlab.kitware.com/vtk/vtk/repository/'
'archive.tar.bz2?ref=v7.0.0')
self.check(
'icet', '1.2.3',
'https://gitlab.kitware.com/icet/icet/repository/'
'archive.tar.gz?ref=IceT-1.2.3')
self.check(
'foo', '42.1337',
'http://example.com/org/foo/repository/'
'archive.zip?ref=42.1337bar')
def test_version_github(self):
self.check(
'yajl', '1.0.5',
'http://github.com/lloyd/yajl/tarball/1.0.5')
def test_version_github_with_high_patch_number(self):
self.check(
'yajl', '1.2.34',
'http://github.com/lloyd/yajl/tarball/v1.2.34')
def test_yet_another_version(self):
self.check(
'mad', '0.15.1b',
'http://example.com/mad-0.15.1b.tar.gz')
def test_lame_version_style(self):
self.check(
'lame', '398-2',
'http://kent.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz')
def test_ruby_version_style(self): def test_ruby_version_style(self):
self.check( self.check(
'ruby', '1.9.1-p243', 'ruby', '1.9.1-p243',
'ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p243.tar.gz') 'ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p243.tar.gz')
def test_omega_version_style(self):
self.check(
'omega', '0.80.2',
'http://www.alcyone.com/binaries/omega/omega-0.80.2-src.tar.gz')
def test_rc_style(self): def test_rc_style(self):
self.check( self.check(
'libvorbis', '1.2.2rc1', 'libvorbis', '1.2.2rc1',
@ -208,60 +675,14 @@ def test_dash_rc_style(self):
'js', '1.8.0-rc1', 'js', '1.8.0-rc1',
'http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz') 'http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz')
def test_angband_version_style(self):
self.check(
'angband', '3.0.9b',
'http://rephial.org/downloads/3.0/angband-3.0.9b-src.tar.gz')
def test_stable_suffix(self):
self.check(
'libevent', '1.4.14b',
'http://www.monkey.org/~provos/libevent-1.4.14b-stable.tar.gz')
def test_debian_style_1(self):
self.check(
'sl', '3.03',
'http://ftp.de.debian.org/debian/pool/main/s/sl/sl_3.03.orig.tar.gz')
def test_debian_style_2(self):
self.check(
'mmv', '1.01b',
'http://ftp.de.debian.org/debian/pool/main/m/mmv/mmv_1.01b.orig.tar.gz')
def test_imagemagick_style(self):
self.check(
'imagemagick', '6.7.5-7',
'http://downloads.sf.net/project/machomebrew/mirror/ImageMagick-6.7.5-7.tar.bz2')
def test_dash_version_dash_style(self):
self.check(
'antlr', '3.4',
'http://www.antlr.org/download/antlr-3.4-complete.jar')
def test_apache_version_style(self): def test_apache_version_style(self):
self.check( self.check(
'apache-cassandra', '1.2.0-rc2', 'apache-cassandra', '1.2.0-rc2',
'http://www.apache.org/dyn/closer.cgi?path=/cassandra/1.2.0/apache-cassandra-1.2.0-rc2-bin.tar.gz') 'http://www.apache.org/dyn/closer.cgi?path=/cassandra/1.2.0/apache-cassandra-1.2.0-rc2-bin.tar.gz')
def test_jpeg_style(self):
self.check(
'jpegsrc', '8d',
'http://www.ijg.org/files/jpegsrc.v8d.tar.gz')
def test_pypy_version(self):
self.check(
'pypy', '1.4.1',
'http://pypy.org/download/pypy-1.4.1-osx.tar.bz2')
def test_openssl_version(self):
self.check(
'openssl', '0.9.8s',
'http://www.openssl.org/source/openssl-0.9.8s.tar.gz')
def test_xaw3d_version(self): def test_xaw3d_version(self):
self.check( self.check(
'xaw3d', '1.5E', 'Xaw3d', '1.5E',
'ftp://ftp.visi.com/users/hawkeyd/X/Xaw3d-1.5E.tar.gz') 'ftp://ftp.visi.com/users/hawkeyd/X/Xaw3d-1.5E.tar.gz')
def test_fann_version(self): def test_fann_version(self):
@ -269,16 +690,6 @@ def test_fann_version(self):
'fann', '2.1.0beta', 'fann', '2.1.0beta',
'http://downloads.sourceforge.net/project/fann/fann/2.1.0beta/fann-2.1.0beta.zip') 'http://downloads.sourceforge.net/project/fann/fann/2.1.0beta/fann-2.1.0beta.zip')
def test_iges_version(self):
self.check(
'grads', '2.0.1',
'ftp://iges.org/grads/2.0/grads-2.0.1-bin-darwin9.8-intel.tar.gz')
def test_haxe_version(self):
self.check(
'haxe', '2.08',
'http://haxe.org/file/haxe-2.08-osx.tar.gz')
def test_imap_version(self): def test_imap_version(self):
self.check( self.check(
'imap', '2007f', 'imap', '2007f',
@ -289,26 +700,6 @@ def test_suite3270_version(self):
'suite3270', '3.3.12ga7', 'suite3270', '3.3.12ga7',
'http://sourceforge.net/projects/x3270/files/x3270/3.3.12ga7/suite3270-3.3.12ga7-src.tgz') 'http://sourceforge.net/projects/x3270/files/x3270/3.3.12ga7/suite3270-3.3.12ga7-src.tgz')
def test_synergy_version(self):
self.check(
'synergy', '1.3.6p2',
'http://synergy.googlecode.com/files/synergy-1.3.6p2-MacOSX-Universal.zip')
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_20_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',
'http://www.hdfgroup.org/ftp/HDF5/current/src/hdf5-1.8.13.tar.bz2')
def test_scalasca_version(self): def test_scalasca_version(self):
self.check( self.check(
'cube', '4.2.3', 'cube', '4.2.3',
@ -317,55 +708,20 @@ def test_scalasca_version(self):
'cube', '4.3-TP1', 'cube', '4.3-TP1',
'http://apps.fz-juelich.de/scalasca/releases/cube/4.3/dist/cube-4.3-TP1.tar.gz') 'http://apps.fz-juelich.de/scalasca/releases/cube/4.3/dist/cube-4.3-TP1.tar.gz')
def test_mpileaks_version(self):
self.check(
'mpileaks', '1.0',
'https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz')
self.check(
'mpileaks', '1.0',
'https://github.com/hpc/mpileaks/releases/download/1.0/mpileaks-1.0.tar.gz')
def test_gcc_version(self):
self.check(
'gcc', '4.4.7',
'http://open-source-box.org/gcc/gcc-4.4.7/gcc-4.4.7.tar.bz2')
def test_gcc_version_precedence(self):
# prefer the version in the tarball, not in the url prefix.
self.check(
'gcc', '4.4.7',
'http://open-source-box.org/gcc/gcc-4.9.2/gcc-4.4.7.tar.bz2')
def test_github_raw_url(self): def test_github_raw_url(self):
self.check( self.check(
'powerparser', '2.0.7', 'CLAMR', '2.0.7',
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true') 'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true')
def test_r_xml_version(self):
self.check(
'xml', '3.98-1.4',
'https://cran.r-project.org/src/contrib/XML_3.98-1.4.tar.gz')
def test_nco_version(self):
self.check(
'nco', '4.6.2-beta03',
'https://github.com/nco/nco/archive/4.6.2-beta03.tar.gz')
self.check(
'nco', '4.6.3-alpha04',
'https://github.com/nco/nco/archive/4.6.3-alpha04.tar.gz')
def test_yorick_version(self):
self.check(
'yorick', '2_2_04',
'https://github.com/dhmunro/yorick/archive/y_2_2_04.tar.gz')
def test_luaposix_version(self): def test_luaposix_version(self):
self.check( self.check(
'luaposix', '33.4.0', 'luaposix', '33.4.0',
'https://github.com/luaposix/luaposix/archive/release-v33.4.0.tar.gz') 'https://github.com/luaposix/luaposix/archive/release-v33.4.0.tar.gz')
def test_sionlib_version(self): def test_nco_version(self):
self.check( self.check(
'sionlib', '1.7.1', 'nco', '4.6.2-beta03',
'http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1') 'https://github.com/nco/nco/archive/4.6.2-beta03.tar.gz')
self.check(
'nco', '4.6.3-alpha04',
'https://github.com/nco/nco/archive/4.6.3-alpha04.tar.gz')

View file

@ -22,44 +22,64 @@
# License along with this program; if not, write to the Free Software # License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
"""\ """Tests Spack's ability to substitute a different version into a URL."""
This test does sanity checks on substituting new versions into URLs
""" import os
import unittest import unittest
import spack.url as url from spack.url import substitute_version
base = "https://comp.llnl.gov/linear_solvers/download/hypre-2.9.0b.tar.gz" class UrlSubstitutionTest(unittest.TestCase):
stem = "https://comp.llnl.gov/linear_solvers/download/hypre-"
def check(self, base, version, new_url):
self.assertEqual(substitute_version(base, version), new_url)
class PackageSanityTest(unittest.TestCase): def test_same_version(self):
# Ensures that substituting the same version results in the same URL
self.check(
'http://www.mr511.de/software/libelf-0.8.13.tar.gz', '0.8.13',
'http://www.mr511.de/software/libelf-0.8.13.tar.gz')
def test_hypre_url_substitution(self): def test_different_version(self):
self.assertEqual(url.substitute_version(base, '2.9.0b'), base) # Test a completely different version syntax
self.assertEqual( self.check(
url.substitute_version(base, '2.8.0b'), stem + "2.8.0b.tar.gz") 'http://www.prevanders.net/libdwarf-20130729.tar.gz', '8.12',
self.assertEqual( 'http://www.prevanders.net/libdwarf-8.12.tar.gz')
url.substitute_version(base, '2.7.0b'), stem + "2.7.0b.tar.gz")
self.assertEqual(
url.substitute_version(base, '2.6.0b'), stem + "2.6.0b.tar.gz")
self.assertEqual(
url.substitute_version(base, '1.14.0b'), stem + "1.14.0b.tar.gz")
self.assertEqual(
url.substitute_version(base, '1.13.0b'), stem + "1.13.0b.tar.gz")
self.assertEqual(
url.substitute_version(base, '2.0.0'), stem + "2.0.0.tar.gz")
self.assertEqual(
url.substitute_version(base, '1.6.0'), stem + "1.6.0.tar.gz")
def test_otf2_url_substitution(self): def test_double_version(self):
base = "http://www.vi-hps.org/upload/packages/otf2/otf2-1.4.tar.gz" # Test a URL where the version appears twice
# It should get substituted both times
self.check(
'https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz', '2.1.3',
'https://github.com/hpc/mpileaks/releases/download/v2.1.3/mpileaks-2.1.3.tar.gz')
self.assertEqual(url.substitute_version(base, '1.4'), base) def test_partial_version_prefix(self):
# Test now with a partial prefix earlier in the URL
# This is hard to figure out so Spack only substitutes
# the last instance of the version
self.check(
'https://www.open-mpi.org/software/ompi/v2.1/downloads/openmpi-2.1.0.tar.bz2', '2.2.0',
'https://www.open-mpi.org/software/ompi/v2.1/downloads/openmpi-2.2.0.tar.bz2')
self.check(
'https://www.open-mpi.org/software/ompi/v2.1/downloads/openmpi-2.1.0.tar.bz2', '2.2',
'https://www.open-mpi.org/software/ompi/v2.1/downloads/openmpi-2.2.tar.bz2')
self.assertEqual( def test_no_separator(self):
url.substitute_version(base, '1.3.1'), # No separator between the name and version of the package
"http://www.vi-hps.org/upload/packages/otf2/otf2-1.3.1.tar.gz") self.check(
self.assertEqual( 'file://{0}/turbolinux702.tar.gz'.format(os.getcwd()), '703',
url.substitute_version(base, '1.2.1'), 'file://{0}/turbolinux703.tar.gz'.format(os.getcwd()))
"http://www.vi-hps.org/upload/packages/otf2/otf2-1.2.1.tar.gz")
def test_github_raw(self):
self.check(
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true', '2.0.7',
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true')
self.check(
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v2.0.7.tgz?raw=true', '4.7',
'https://github.com/losalamos/CLAMR/blob/packages/PowerParser_v4.7.tgz?raw=true')
def test_regex(self):
# Package name contains regex characters
self.check(
'http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz', '1.2.3',
'http://math.lbl.gov/voro++/download/dir/voro++-1.2.3.tar.gz')

View file

@ -23,7 +23,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
"""Tests for web.py.""" """Tests for web.py."""
import pytest
import os import os
import spack import spack
@ -141,7 +140,6 @@ def test_find_versions_of_archive_2():
assert ver('2.0.0') in versions assert ver('2.0.0') in versions
@pytest.mark.xfail
def test_find_exotic_versions_of_archive_2(): def test_find_exotic_versions_of_archive_2():
versions = find_versions_of_archive(root_tarball, root, list_depth=2) versions = find_versions_of_archive(root_tarball, root, list_depth=2)
# up for grabs to make this better. # up for grabs to make this better.
@ -157,7 +155,6 @@ def test_find_versions_of_archive_3():
assert ver('4.5') in versions assert ver('4.5') in versions
@pytest.mark.xfail
def test_find_exotic_versions_of_archive_3(): def test_find_exotic_versions_of_archive_3():
versions = find_versions_of_archive(root_tarball, root, list_depth=3) versions = find_versions_of_archive(root_tarball, root, list_depth=3)
assert ver('2.0.0b2') in versions assert ver('2.0.0b2') in versions

View file

@ -71,7 +71,7 @@ def find_list_url(url):
url_types = [ url_types = [
# e.g. https://github.com/llnl/callpath/archive/v1.0.1.tar.gz # e.g. https://github.com/llnl/callpath/archive/v1.0.1.tar.gz
(r'^(https://github.com/[^/]+/[^/]+)/archive/', (r'(.*github\.com/[^/]+/[^/]+)/archive/',
lambda m: m.group(1) + '/releases')] lambda m: m.group(1) + '/releases')]
for pattern, fun in url_types: for pattern, fun in url_types:
@ -101,6 +101,177 @@ def strip_query_and_fragment(path):
return (path, '') # Ignore URL parse errors here return (path, '') # Ignore URL parse errors here
def strip_version_suffixes(path):
"""Some tarballs contain extraneous information after the version:
* ``bowtie2-2.2.5-source``
* ``libevent-2.0.21-stable``
* ``cuda_8.0.44_linux.run``
These strings are not part of the version number and should be ignored.
This function strips those suffixes off and returns the remaining string.
The goal is that the version is always the last thing in ``path``:
* ``bowtie2-2.2.5``
* ``libevent-2.0.21``
* ``cuda_8.0.44``
:param str path: The filename or URL for the package
:return: The ``path`` with any extraneous suffixes removed
:rtype: str
"""
# NOTE: This could be done with complicated regexes in parse_version_offset
# NOTE: The problem is that we would have to add these regexes to the end
# NOTE: of every single version regex. Easier to just strip them off
# NOTE: permanently
suffix_regexes = [
# Download type
'[Ii]nstall',
'all',
'src(_0)?',
'[Ss]ources?',
'file',
'full',
'single',
'public',
'with[a-zA-Z_-]+',
'bin',
'binary',
'run',
'[Uu]niversal',
'jar',
'complete',
'oss',
'gem',
'tar',
'sh',
# Download version
'stable',
'[Ff]inal',
'rel',
'orig',
'dist',
'\+',
# License
'gpl',
# Arch
# Needs to come before and after OS, appears in both orders
'ia32',
'intel',
'amd64',
'x64',
'x86_64',
'x86',
'i[36]86',
'ppc64(le)?',
'armv?(7l|6l|64)',
# OS
'[Ll]inux(_64)?',
'[Uu]ni?x',
'[Ss]un[Oo][Ss]',
'[Mm]ac[Oo][Ss][Xx]?',
'[Oo][Ss][Xx]',
'[Dd]arwin(64)?',
'[Aa]pple',
'[Ww]indows',
'[Ww]in(64|32)?',
'[Cc]ygwin(64|32)?',
'[Mm]ingw',
# Arch
# Needs to come before and after OS, appears in both orders
'ia32',
'intel',
'amd64',
'x64',
'x86_64',
'x86',
'i[36]86',
'ppc64(le)?',
'armv?(7l|6l|64)?',
# PyPI
'[._-]py[23].*\.whl',
'[._-]cp[23].*\.whl',
'[._-]win.*\.exe',
]
for regex in suffix_regexes:
# Remove the suffix from the end of the path
# This may be done multiple times
path = re.sub(r'[._-]?' + regex + '$', '', path)
return path
def strip_name_suffixes(path, version):
"""Most tarballs contain a package name followed by a version number.
However, some also contain extraneous information in-between the name
and version:
* ``rgb-1.0.6``
* ``converge_install_2.3.16``
* ``jpegsrc.v9b``
These strings are not part of the package name and should be ignored.
This function strips the version number and any extraneous suffixes
off and returns the remaining string. The goal is that the name is
always the last thing in ``path``:
* ``rgb``
* ``converge``
* ``jpeg``
:param str path: The filename or URL for the package
:param str version: The version detected for this URL
:return: The ``path`` with any extraneous suffixes removed
:rtype: str
"""
# NOTE: This could be done with complicated regexes in parse_name_offset
# NOTE: The problem is that we would have to add these regexes to every
# NOTE: single name regex. Easier to just strip them off permanently
suffix_regexes = [
# Strip off the version and anything after it
# name-ver
# name_ver
# name.ver
r'[._-]v?' + str(version) + '.*',
# namever
str(version) + '.*',
# Download type
'install',
'src',
'(open)?[Ss]ources?',
'[._-]std',
# Download version
'snapshot',
'distrib',
# VCS
'0\+bzr',
# License
'gpl',
]
for regex in suffix_regexes:
# Remove the suffix from the end of the path
# This may be done multiple times
path = re.sub('[._-]?' + regex + '$', '', path)
return path
def split_url_extension(path): def split_url_extension(path):
"""Some URLs have a query string, e.g.: """Some URLs have a query string, e.g.:
@ -125,7 +296,7 @@ def split_url_extension(path):
prefix, ext, suffix = path, '', '' prefix, ext, suffix = path, '', ''
# Strip off sourceforge download suffix. # Strip off sourceforge download suffix.
match = re.search(r'((?:sourceforge.net|sf.net)/.*)(/download)$', path) match = re.search(r'((?:sourceforge\.net|sf\.net)/.*)(/download)$', path)
if match: if match:
prefix, suffix = match.groups() prefix, suffix = match.groups()
@ -189,8 +360,20 @@ def parse_version_offset(path):
path, ext, suffix = split_url_extension(path) path, ext, suffix = split_url_extension(path)
# stem: Everything from path after the final '/' # stem: Everything from path after the final '/'
stem = os.path.basename(path) original_stem = os.path.basename(path)
offset = len(path) - len(stem)
# Try to strip off anything after the version number
stem = strip_version_suffixes(original_stem)
# Assumptions:
#
# 1. version always comes after the name
# 2. separators include '-', '_', and '.'
# 3. names can contain A-Z, a-z, 0-9, '+', separators
# 4. versions can contain A-Z, a-z, 0-9, separators
# 5. versions always start with a digit
# 6. versions are often prefixed by a 'v' character
# 7. separators are most reliable to determine name/version boundaries
# List of the following format: # List of the following format:
# #
@ -202,87 +385,118 @@ def parse_version_offset(path):
# The first regex that matches string will be used to determine # The first regex that matches string will be used to determine
# the version of the package. Thefore, hyperspecific regexes should # the version of the package. Thefore, hyperspecific regexes should
# come first while generic, catch-all regexes should come last. # come first while generic, catch-all regexes should come last.
# With that said, regular expressions are slow, so if possible, put
# ones that only catch one or two URLs at the bottom.
version_regexes = [ version_regexes = [
# GitHub tarballs, e.g. v1.2.3 # 1st Pass: Simplest case
(r'github.com/.+/(?:zip|tar)ball/v?((\d+\.)+\d+)$', path), # Assume name contains no digits and version contains no letters
# e.g. libpng-1.6.27
(r'^[a-zA-Z+._-]+[._-]v?(\d[\d._-]*)$', stem),
# e.g. https://github.com/sam-github/libnet/tarball/libnet-1.1.4 # 2nd Pass: Version only
(r'github.com/.+/(?:zip|tar)ball/.*-((\d+\.)+\d+)$', path), # Assume version contains no letters
# e.g. https://github.com/isaacs/npm/tarball/v0.2.5-1 # ver
(r'github.com/.+/(?:zip|tar)ball/v?((\d+\.)+\d+-(\d+))$', path), # e.g. 3.2.7, 7.0.2-7, v3.3.0, v1_6_3
(r'^v?(\d[\d._-]*)$', stem),
# e.g. https://github.com/petdance/ack/tarball/1.93_02 # 3rd Pass: No separator characters are used
(r'github.com/.+/(?:zip|tar)ball/v?((\d+\.)+\d+_(\d+))$', path), # Assume name contains no digits
# Yorick is very special. # namever
# e.g. https://github.com/dhmunro/yorick/archive/y_2_2_04.tar.gz # e.g. turbolinux702, nauty26r7
(r'github.com/[^/]+/yorick/archive/y_(\d+(?:_\d+)*)$', path), (r'^[a-zA-Z+]*(\d[\da-zA-Z]*)$', stem),
# e.g. https://github.com/hpc/lwgrp/archive/v1.0.1.tar.gz # 4th Pass: A single separator character is used
(r'github.com/[^/]+/[^/]+/archive/(?:release-)?v?(\w+(?:[.-]\w+)*)$', path), # noqa # Assume name contains no digits
# e.g. https://github.com/erlang/otp/tarball/OTP_R15B01 (erlang style) # name-name-ver-ver
(r'[-_](R\d+[AB]\d*(-\d+)?)', path), # e.g. panda-2016-03-07, gts-snapshot-121130, cdd-061a
(r'^[a-zA-Z+-]*(\d[\da-zA-Z-]*)$', stem),
# e.g., https://github.com/hpc/libcircle/releases/download/0.2.1-rc.1/libcircle-0.2.1-rc.1.tar.gz # name_name_ver_ver
# e.g., # e.g. tinyxml_2_6_2, boost_1_55_0, tbb2017_20161128, v1_6_3
# https://github.com/hpc/mpileaks/releases/download/v1.0/mpileaks-1.0.tar.gz (r'^[a-zA-Z+_]*(\d[\da-zA-Z_]*)$', stem),
(r'github.com/[^/]+/[^/]+/releases/download/v?([^/]+)/.*$', path),
# GitLab syntax: # name.name.ver.ver
# {baseUrl}{/organization}{/projectName}/repository/archive.{fileEnding}?ref={gitTag} # e.g. prank.source.150803, jpegsrc.v9b, atlas3.11.34, geant4.10.01.p03
# as with github releases, we hope a version can be found in the (r'^[a-zA-Z+.]*(\d[\da-zA-Z.]*)$', stem),
# git tag
# Search dotted versions:
# e.g., https://gitlab.kitware.com/vtk/vtk/repository/archive.tar.bz2?ref=v7.0.0
# e.g., https://example.com/org/repo/repository/archive.tar.bz2?ref=SomePrefix-2.1.1
# e.g., http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1
(r'\?ref=(?:.*-|v)*((\d+\.)+\d+).*$', suffix),
(r'\?version=((\d+\.)+\d+)', suffix),
# e.g. boost_1_39_0 # 5th Pass: Two separator characters are used
(r'((\d+_)+\d+)$', stem), # Name may contain digits, version may contain letters
# e.g. foobar-4.5.1-1 # name-name-ver.ver
# e.g. ruby-1.9.1-p243 # e.g. m4-1.4.17, gmp-6.0.0a, launchmon-v1.0.2
(r'-((\d+\.)*\d\.\d+-(p|rc|RC)?\d+)(?:[-._](?:bin|dist|stable|src|sources))?$', stem), # noqa (r'^[a-zA-Z\d+-]+-v?(\d[\da-zA-Z.]*)$', stem),
# e.g. lame-398-1 # name-name-ver_ver
(r'-((\d)+-\d)', stem), # e.g. icu4c-57_1
(r'^[a-zA-Z\d+-]+-v?(\d[\da-zA-Z_]*)$', stem),
# e.g. foobar_1.2-3 or 3.98-1.4 # name_name_ver.ver
(r'_((\d+\.)+\d+(-(\d+(\.\d+)?))?[a-z]?)', stem), # e.g. superlu_dist_4.1, pexsi_v0.9.0
(r'^[a-zA-Z\d+_]+_v?(\d[\da-zA-Z.]*)$', stem),
# e.g. foobar-4.5.1 # name_name.ver.ver
(r'-((\d+\.)*\d+)$', stem), # e.g. fer_source.v696
(r'^[a-zA-Z\d+_]+\.v?(\d[\da-zA-Z.]*)$', stem),
# e.g. foobar-4.5.1b, foobar4.5RC, foobar.v4.5.1b # name-name-ver.ver-ver.ver
(r'[-._]?v?((\d+\.)*\d+[-._]?([a-z]|rc|RC|tp|TP?)\d*)$', stem), # e.g. sowing-1.1.23-p1, bib2xhtml-v3.0-15-gf506, 4.6.3-alpha04
(r'^(?:[a-zA-Z\d+-]+-)?v?(\d[\da-zA-Z.-]*)$', stem),
# e.g. foobar-4.5.0-beta1, or foobar-4.50-beta # namever.ver-ver.ver
(r'-((\d+\.)*\d+-beta(\d+)?)$', stem), # e.g. go1.4-bootstrap-20161024
(r'^[a-zA-Z+]+v?(\d[\da-zA-Z.-]*)$', stem),
# e.g. foobar4.5.1 # 6th Pass: All three separator characters are used
(r'((\d+\.)*\d+)$', stem), # Name may contain digits, version may contain letters
# e.g. foobar-4.5.0-bin # name_name-ver.ver
(r'-((\d+\.)+\d+[a-z]?)[-._](bin|dist|stable|src|sources?)$', stem), # e.g. the_silver_searcher-0.32.0, sphinx_rtd_theme-0.1.10a0
(r'^[a-zA-Z\d+_]+-v?(\d[\da-zA-Z.]*)$', stem),
# e.g. dash_0.5.5.1.orig.tar.gz (Debian style) # name.name_ver.ver-ver.ver
(r'_((\d+\.)+\d+[a-z]?)[.]orig$', stem), # e.g. TH.data_1.0-8, XML_3.98-1.4
(r'^[a-zA-Z\d+.]+_v?(\d[\da-zA-Z.-]*)$', stem),
# e.g. http://www.openssl.org/source/openssl-0.9.8s.tar.gz # name-name-ver.ver_ver.ver
(r'-v?([^-]+(-alpha|-beta)?)', stem), # e.g. pypar-2.1.5_108
(r'^[a-zA-Z\d+-]+-v?(\d[\da-zA-Z._]*)$', stem),
# e.g. astyle_1.23_macosx.tar.gz # name.name_name-ver.ver
(r'_([^_]+(_alpha|_beta)?)', stem), # e.g. tap.py-1.6, backports.ssl_match_hostname-3.5.0.1
(r'^[a-zA-Z\d+._]+-v?(\d[\da-zA-Z.]*)$', stem),
# e.g. http://mirrors.jenkins-ci.org/war/1.486/jenkins.war # name-namever.ver_ver.ver
(r'\/(\d\.\d+)\/', path), # e.g. STAR-CCM+11.06.010_02
(r'^[a-zA-Z+-]+(\d[\da-zA-Z._]*)$', stem),
# e.g. http://www.ijg.org/files/jpegsrc.v8d.tar.gz # 7th Pass: Specific VCS
(r'\.v(\d+[a-z]?)', stem)
# bazaar
# e.g. libvterm-0+bzr681
(r'bzr(\d[\da-zA-Z._-]*)$', stem),
# 8th Pass: Version in path
# github.com/repo/name/releases/download/vver/name
# e.g. https://github.com/nextflow-io/nextflow/releases/download/v0.20.1/nextflow
(r'github\.com/[^/]+/[^/]+/releases/download/[a-zA-Z+._-]*v?(\d[\da-zA-Z._-]*)/', path), # noqa
# 9th Pass: Query strings
# e.g. http://gitlab.cosma.dur.ac.uk/swift/swiftsim/repository/archive.tar.gz?ref=v0.3.0
(r'\?ref=[a-zA-Z+._-]*v?(\d[\da-zA-Z._-]*)$', suffix),
# e.g. http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1
(r'\?version=v?(\d[\da-zA-Z._-]*)$', suffix),
# e.g. http://slepc.upv.es/download/download.php?filename=slepc-3.6.2.tar.gz
(r'\?filename=[a-zA-Z\d+-]+-v?(\d[\da-zA-Z.]*)$', stem),
# e.g. http://wwwpub.zih.tu-dresden.de/%7Emlieber/dcount/dcount.php?package=otf&get=OTF-1.12.5salmon.tar.gz
(r'\?package=[a-zA-Z\d+-]+&get=[a-zA-Z\d+-]+-v?(\d[\da-zA-Z.]*)$', stem), # noqa
] ]
for i, version_regex in enumerate(version_regexes): for i, version_regex in enumerate(version_regexes):
@ -292,9 +506,15 @@ def parse_version_offset(path):
version = match.group(1) version = match.group(1)
start = match.start(1) start = match.start(1)
# if we matched from the basename, then add offset in. # If we matched from the stem or suffix, we need to add offset
offset = 0
if match_string is stem: if match_string is stem:
start += offset offset = len(path) - len(original_stem)
elif match_string is suffix:
offset = len(path)
if ext:
offset += len(ext) + 1 # .tar.gz is converted to tar.gz
start += offset
return version, start, len(version), i, regex return version, start, len(version), i, regex
@ -342,7 +562,7 @@ def parse_name_offset(path, v=None):
except UndetectableVersionError: except UndetectableVersionError:
# Not all URLs contain a version. We still want to be able # Not all URLs contain a version. We still want to be able
# to determine a name if possible. # to determine a name if possible.
v = '' v = 'unknown'
# path: The prefix of the URL, everything before the ext and suffix # path: The prefix of the URL, everything before the ext and suffix
# ext: The file extension # ext: The file extension
@ -350,8 +570,10 @@ def parse_name_offset(path, v=None):
path, ext, suffix = split_url_extension(path) path, ext, suffix = split_url_extension(path)
# stem: Everything from path after the final '/' # stem: Everything from path after the final '/'
stem = os.path.basename(path) original_stem = os.path.basename(path)
offset = len(path) - len(stem)
# Try to strip off anything after the package name
stem = strip_name_suffixes(original_stem, v)
# List of the following format: # List of the following format:
# #
@ -363,26 +585,45 @@ def parse_name_offset(path, v=None):
# The first regex that matches string will be used to determine # The first regex that matches string will be used to determine
# the name of the package. Thefore, hyperspecific regexes should # the name of the package. Thefore, hyperspecific regexes should
# come first while generic, catch-all regexes should come last. # come first while generic, catch-all regexes should come last.
# With that said, regular expressions are slow, so if possible, put
# ones that only catch one or two URLs at the bottom.
name_regexes = [ name_regexes = [
(r'/sourceforge/([^/]+)/', path), # 1st Pass: Common repositories
(r'github.com/[^/]+/[^/]+/releases/download/%s/(.*)-%s$' %
(v, v), path),
(r'/([^/]+)/(tarball|zipball)/', path),
(r'/([^/]+)[_.-](bin|dist|stable|src|sources)[_.-]%s' % v, path),
(r'github.com/[^/]+/([^/]+)/archive', path),
(r'github.com/[^/]+/([^/]+)/releases', path),
(r'[^/]+/([^/]+)/repository/archive', path), # gitlab
(r'([^/]+)/download.php', path),
(r'([^/]+)[_.-]v?%s' % v, stem), # prefer the stem # GitHub: github.com/repo/name/
(r'([^/]+)%s' % v, stem), # e.g. https://github.com/nco/nco/archive/4.6.2.tar.gz
(r'github\.com/[^/]+/([^/]+)', path),
# accept the path if name is not in stem. # GitLab: gitlab.*/repo/name/
(r'/([^/]+)[_.-]v?%s' % v, path), # e.g. http://gitlab.cosma.dur.ac.uk/swift/swiftsim/repository/archive.tar.gz?ref=v0.3.0
(r'/([^/]+)%s' % v, path), (r'gitlab[^/]+/[^/]+/([^/]+)', path),
(r'^([^/]+)[_.-]v?%s' % v, path), # Bitbucket: bitbucket.org/repo/name/
(r'^([^/]+)%s' % v, path) # e.g. https://bitbucket.org/glotzer/hoomd-blue/get/v1.3.3.tar.bz2
(r'bitbucket\.org/[^/]+/([^/]+)', path),
# PyPI: pypi.(python.org|io)/packages/source/first-letter/name/
# e.g. https://pypi.python.org/packages/source/m/mpmath/mpmath-all-0.19.tar.gz
# e.g. https://pypi.io/packages/source/b/backports.ssl_match_hostname/backports.ssl_match_hostname-3.5.0.1.tar.gz
(r'pypi\.(?:python\.org|io)/packages/source/[A-Za-z\d]/([^/]+)', path),
# 2nd Pass: Query strings
# ?filename=name-ver.ver
# e.g. http://slepc.upv.es/download/download.php?filename=slepc-3.6.2.tar.gz
(r'\?filename=([A-Za-z\d+-]+)$', stem),
# ?package=name
# e.g. http://wwwpub.zih.tu-dresden.de/%7Emlieber/dcount/dcount.php?package=otf&get=OTF-1.12.5salmon.tar.gz
(r'\?package=([A-Za-z\d+-]+)', stem),
# download.php
# e.g. http://apps.fz-juelich.de/jsc/sionlib/download.php?version=1.7.1
(r'([^/]+)/download.php$', path),
# 3rd Pass: Name followed by version in archive
(r'^([A-Za-z\d+\._-]+)$', stem),
] ]
for i, name_regex in enumerate(name_regexes): for i, name_regex in enumerate(name_regexes):
@ -392,13 +633,15 @@ def parse_name_offset(path, v=None):
name = match.group(1) name = match.group(1)
start = match.start(1) start = match.start(1)
# if we matched from the basename, then add offset in. # If we matched from the stem or suffix, we need to add offset
offset = 0
if match_string is stem: if match_string is stem:
start += offset offset = len(path) - len(original_stem)
elif match_string is suffix:
# package names should be lowercase and separated by dashes. offset = len(path)
name = name.lower() if ext:
name = re.sub('[_.]', '-', name) offset += len(ext) + 1 # .tar.gz is converted to tar.gz
start += offset
return name, start, len(name), i, regex return name, start, len(name), i, regex
@ -431,6 +674,9 @@ def parse_name_and_version(path):
The version of the package The version of the package
:rtype: tuple :rtype: tuple
:raises UndetectableVersionError: If the URL does not match any regexes
:raises UndetectableNameError: If the URL does not match any regexes
""" """
ver = parse_version(path) ver = parse_version(path)
name = parse_name(path, ver) name = parse_name(path, ver)
@ -457,6 +703,22 @@ def cumsum(elts, init=0, fn=lambda x: x):
return sums return sums
def find_all(substring, string):
"""Returns a list containing the indices of
every occurrence of substring in string."""
occurrences = []
index = 0
while index < len(string):
index = string.find(substring, index)
if index == -1:
break
occurrences.append(index)
index += len(substring)
return occurrences
def substitution_offsets(path): def substitution_offsets(path):
"""This returns offsets for substituting versions and names in the """This returns offsets for substituting versions and names in the
provided path. It is a helper for :func:`substitute_version`. provided path. It is a helper for :func:`substitute_version`.
@ -468,65 +730,34 @@ def substitution_offsets(path):
except UndetectableNameError: except UndetectableNameError:
return (None, -1, -1, (), ver, vs, vl, (vs,)) return (None, -1, -1, (), ver, vs, vl, (vs,))
except UndetectableVersionError: except UndetectableVersionError:
return (None, -1, -1, (), None, -1, -1, ()) try:
name, ns, nl, ni, nregex = parse_name_offset(path)
return (name, ns, nl, (ns,), None, -1, -1, ())
except UndetectableNameError:
return (None, -1, -1, (), None, -1, -1, ())
# protect extensions like bz2 from getting inadvertently # Find the index of every occurrence of name and ver in path
# considered versions. name_offsets = find_all(name, path)
path = comp.strip_extension(path) ver_offsets = find_all(ver, path)
# Construct a case-insensitive regular expression for the package name. return (name, ns, nl, name_offsets,
name_re = '(%s)' % insensitize(name) ver, vs, vl, ver_offsets)
# Split the string apart by things that match the name so that if the
# name contains numbers or things that look like versions, we don't
# accidentally substitute them with a version.
name_parts = re.split(name_re, path)
offsets = cumsum(name_parts, 0, len)
name_offsets = offsets[1::2]
ver_offsets = []
for i in range(0, len(name_parts), 2):
vparts = re.split(ver, name_parts[i])
voffsets = cumsum(vparts, offsets[i], len)
ver_offsets.extend(voffsets[1::2])
return (name, ns, nl, tuple(name_offsets),
ver, vs, vl, tuple(ver_offsets))
def wildcard_version(path): def wildcard_version(path):
"""Find the version in the supplied path, and return a regular expression """Find the version in the supplied path, and return a regular expression
that will match this path with any version in its place. that will match this path with any version in its place.
""" """
# Get name and version, so we can treat them specially # Get version so we can replace it with a wildcard
name, v = parse_name_and_version(path) version = parse_version(path)
path, ext, suffix = split_url_extension(path) # Split path by versions
vparts = path.split(str(version))
# Construct a case-insensitive regular expression for the package name. # Replace each version with a generic capture group to find versions
name_re = '(%s)' % insensitize(name) # and escape everything else so it's not interpreted as a regex
result = '(\d.*)'.join(re.escape(vp) for vp in vparts)
# Split the string apart by things that match the name so that if the
# name contains numbers or things that look like versions, we don't
# catch them with the version wildcard.
name_parts = re.split(name_re, path)
# Even elements in the array did *not* match the name
for i in range(0, len(name_parts), 2):
# Split each part by things that look like versions.
vparts = re.split(v.wildcard(), name_parts[i])
# Replace each version with a generic capture group to find versions.
# And escape everything else so it's not interpreted as a regex
vgroup = '(%s)' % v.wildcard()
name_parts[i] = vgroup.join(re.escape(vp) for vp in vparts)
# Put it all back together with original name matches intact.
result = ''.join(name_parts)
if ext:
result += '.' + ext
result += suffix
return result return result

View file

@ -39,6 +39,7 @@
'validate_fully_qualified_module_name', 'validate_fully_qualified_module_name',
'validate_module_name', 'validate_module_name',
'possible_spack_module_names', 'possible_spack_module_names',
'simplify_name',
'NamespaceTrie'] 'NamespaceTrie']
# Valid module names can contain '-' but can't start with it. # Valid module names can contain '-' but can't start with it.
@ -108,6 +109,50 @@ def possible_spack_module_names(python_mod_name):
return results return results
def simplify_name(name):
"""Simplifies a name which may include uppercase letters, periods,
underscores, and pluses. In general, we want our package names to
only contain lowercase letters, digits, and dashes.
:param str name: The original name of the package
:return: The new name of the package
:rtype: str
"""
# Convert CamelCase to Dashed-Names
# e.g. ImageMagick -> Image-Magick
# e.g. SuiteSparse -> Suite-Sparse
# name = re.sub('([a-z])([A-Z])', r'\1-\2', name)
# Rename Intel downloads
# e.g. l_daal, l_ipp, l_mkl -> daal, ipp, mkl
if name.startswith('l_'):
name = name[2:]
# Convert UPPERCASE to lowercase
# e.g. SAMRAI -> samrai
name = name.lower()
# Replace '_' and '.' with '-'
# e.g. backports.ssl_match_hostname -> backports-ssl-match-hostname
name = name.replace('_', '-')
name = name.replace('.', '-')
# Replace "++" with "pp" and "+" with "-plus"
# e.g. gtk+ -> gtk-plus
# e.g. voro++ -> voropp
name = name.replace('++', 'pp')
name = name.replace('+', '-plus')
# Simplify Lua package names
# We don't want "lua" to occur multiple times in the name
name = re.sub('^(lua)([^-])', r'\1-\2', name)
# Simplify Bio++ package names
name = re.sub('^(bpp)([^-])', r'\1-\2', name)
return name
def valid_module_name(mod_name): def valid_module_name(mod_name):
"""Return whether mod_name is valid for use in Spack.""" """Return whether mod_name is valid for use in Spack."""
return bool(re.match(_valid_module_re, mod_name)) return bool(re.match(_valid_module_re, mod_name))

View file

@ -268,6 +268,14 @@ def find_versions_of_archive(archive_urls, list_url=None, list_depth=0):
# part, not the full path. # part, not the full path.
url_regex = os.path.basename(url_regex) url_regex = os.path.basename(url_regex)
# We need to add a / to the beginning of the regex to prevent
# Spack from picking up similarly named packages like:
# https://cran.r-project.org/src/contrib/pls_2.6-0.tar.gz
# https://cran.r-project.org/src/contrib/enpls_5.7.tar.gz
# https://cran.r-project.org/src/contrib/autopls_1.3.tar.gz
# https://cran.r-project.org/src/contrib/matrixpls_1.0.4.tar.gz
url_regex = '/' + url_regex
# We need to add a $ anchor to the end of the regex to prevent # We need to add a $ anchor to the end of the regex to prevent
# Spack from picking up signature files like: # Spack from picking up signature files like:
# .asc # .asc
@ -275,7 +283,9 @@ def find_versions_of_archive(archive_urls, list_url=None, list_depth=0):
# .sha256 # .sha256
# .sig # .sig
# However, SourceForge downloads still need to end in '/download'. # However, SourceForge downloads still need to end in '/download'.
regexes.append(url_regex + '(\/download)?$') url_regex += '(\/download)?$'
regexes.append(url_regex)
# Build a dict version -> URL from any links that match the wildcards. # Build a dict version -> URL from any links that match the wildcards.
versions = {} versions = {}

View file

@ -194,35 +194,6 @@ def satisfies(self, other):
nother = len(other.version) nother = len(other.version)
return nother <= nself and self.version[:nother] == other.version return nother <= nself and self.version[:nother] == other.version
def wildcard(self):
"""Create a regex that will match variants of this version string."""
def a_or_n(seg):
if type(seg) == int:
return r'[0-9]+'
else:
return r'[a-zA-Z]+'
version = self.version
# Use a wildcard for separators, in case a version is written
# two different ways (e.g., boost writes 1_55_0 and 1.55.0)
sep_re = '[_.-]'
separators = ('',) + (sep_re,) * len(self.separators)
version += (version[-1],) * 2
separators += (sep_re,) * 2
segments = [a_or_n(seg) for seg in version]
wc = segments[0]
for i in range(1, len(separators)):
wc += '(?:' + separators[i] + segments[i]
# Add possible alpha or beta indicator at the end of each segemnt
# We treat these specially b/c they're so common.
wc += '(?:[a-z]|alpha|beta)?)?' * (len(segments) - 1)
return wc
def __iter__(self): def __iter__(self):
return iter(self.version) return iter(self.version)

View file

@ -732,20 +732,21 @@ function _spack_url {
then then
compgen -W "-h --help" -- "$cur" compgen -W "-h --help" -- "$cur"
else else
compgen -W "list parse test" -- "$cur" compgen -W "list parse summary" -- "$cur"
fi fi
} }
function _spack_url_list { function _spack_url_list {
compgen -W "-h --help -c --color -e --extrapolation -n --incorrect-name compgen -W "-h --help -c --color -e --extrapolation
-v --incorrect-version" -- "$cur" -n --incorrect-name -N --correct-name
-v --incorrect-version -V --correct-version" -- "$cur"
} }
function _spack_url_parse { function _spack_url_parse {
compgen -W "-h --help -s --spider" -- "$cur" compgen -W "-h --help -s --spider" -- "$cur"
} }
function _spack_url_test { function _spack_url_summary {
compgen -W "-h --help" -- "$cur" compgen -W "-h --help" -- "$cur"
} }

View file

@ -29,7 +29,7 @@ class Automake(AutotoolsPackage):
"""Automake -- make file builder part of autotools""" """Automake -- make file builder part of autotools"""
homepage = 'http://www.gnu.org/software/automake/' homepage = 'http://www.gnu.org/software/automake/'
url = 'http://ftp.gnu.org/gnu/automake/automake-1.14.tar.gz' url = 'http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz'
version('1.15', '716946a105ca228ab545fc37a70df3a3') version('1.15', '716946a105ca228ab545fc37a70df3a3')
version('1.14.1', 'd052a3e884631b9c7892f2efce542d75') version('1.14.1', 'd052a3e884631b9c7892f2efce542d75')

View file

@ -33,9 +33,6 @@ class Bib2xhtml(Package):
version('3.0-15-gf506', 'a26ba02fe0053bbbf2277bdf0acf8645') version('3.0-15-gf506', 'a26ba02fe0053bbbf2277bdf0acf8645')
def url_for_version(self, v):
return ('http://www.spinellis.gr/sw/textproc/bib2xhtml/bib2xhtml-v%s.tar.gz' % v)
def install(self, spec, prefix): def install(self, spec, prefix):
# Add the bst include files to the install directory # Add the bst include files to the install directory
bst_include = join_path(prefix.share, 'bib2xhtml') bst_include = join_path(prefix.share, 'bib2xhtml')

View file

@ -31,7 +31,7 @@ class Bison(AutotoolsPackage):
generalized LR (GLR) parser employing LALR(1) parser tables.""" generalized LR (GLR) parser employing LALR(1) parser tables."""
homepage = "http://www.gnu.org/software/bison/" homepage = "http://www.gnu.org/software/bison/"
url = "http://ftp.gnu.org/gnu/bison/bison-3.0.tar.gz" url = "http://ftp.gnu.org/gnu/bison/bison-3.0.4.tar.gz"
version('3.0.4', 'a586e11cd4aff49c3ff6d3b6a4c9ccf8') version('3.0.4', 'a586e11cd4aff49c3ff6d3b6a4c9ccf8')
version('2.7', 'ded660799e76fb1667d594de1f7a0da9') version('2.7', 'ded660799e76fb1667d594de1f7a0da9')

View file

@ -39,14 +39,9 @@
class BlastPlus(AutotoolsPackage): class BlastPlus(AutotoolsPackage):
"""Basic Local Alignment Search Tool.""" """Basic Local Alignment Search Tool."""
homepage = "http://blast.ncbi.nlm.nih.gov/" homepage = "http://blast.ncbi.nlm.nih.gov/"
url = "https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/2.6.0/ncbi-blast-2.6.0+-src.tar.gz" url = "https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/2.6.0/ncbi-blast-2.6.0+-src.tar.gz"
def url_for_version(self, version):
url = "https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/{0}/ncbi-blast-{0}+-src.tar.gz"
return url.format(version)
version('2.6.0', 'c8ce8055b10c4d774d995f88c7cc6225') version('2.6.0', 'c8ce8055b10c4d774d995f88c7cc6225')
version('2.2.30', 'f8e9a5eb368173142fe6867208b73715') version('2.2.30', 'f8e9a5eb368173142fe6867208b73715')

View file

@ -141,14 +141,8 @@ class Boost(Package):
patch('xl_1_62_0_le.patch', when='@1.62.0%xl') patch('xl_1_62_0_le.patch', when='@1.62.0%xl')
def url_for_version(self, version): def url_for_version(self, version):
""" url = "http://downloads.sourceforge.net/project/boost/boost/{0}/boost_{1}.tar.bz2"
Handle Boost's weird URLs, return url.format(version.dotted, version.underscored)
which write the version two different ways.
"""
parts = [str(p) for p in Version(version)]
dots = ".".join(parts)
underscores = "_".join(parts)
return "http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (dots, underscores)
def determine_toolset(self, spec): def determine_toolset(self, spec):
if spec.satisfies("platform=darwin"): if spec.satisfies("platform=darwin"):

View file

@ -29,7 +29,10 @@
class Bowtie2(Package): class Bowtie2(Package):
"""Bowtie 2 is an ultrafast and memory-efficient tool for aligning """Bowtie 2 is an ultrafast and memory-efficient tool for aligning
sequencing reads to long reference sequences""" sequencing reads to long reference sequences"""
homepage = "bowtie-bio.sourceforge.net/bowtie2/index.shtml" homepage = "bowtie-bio.sourceforge.net/bowtie2/index.shtml"
url = "http://downloads.sourceforge.net/project/bowtie-bio/bowtie2/2.3.1/bowtie2-2.3.1-source.zip"
version('2.3.1', 'b4efa22612e98e0c23de3d2c9f2f2478') version('2.3.1', 'b4efa22612e98e0c23de3d2c9f2f2478')
version('2.2.5', '51fa97a862d248d7ee660efc1147c75f') version('2.2.5', '51fa97a862d248d7ee660efc1147c75f')
@ -38,10 +41,6 @@ class Bowtie2(Package):
patch('bowtie2-2.2.5.patch', when='@2.2.5', level=0) patch('bowtie2-2.2.5.patch', when='@2.2.5', level=0)
patch('bowtie2-2.3.1.patch', when='@2.3.1', level=0) patch('bowtie2-2.3.1.patch', when='@2.3.1', level=0)
def url_for_version(self, version):
url="http://downloads.sourceforge.net/project/bowtie-bio/bowtie2/{0}/bowtie2-{0}-source.zip"
return url.format(version)
def install(self, spec, prefix): def install(self, spec, prefix):
make() make()
mkdirp(prefix.bin) mkdirp(prefix.bin)

View file

@ -31,19 +31,9 @@ class Cddlib(AutotoolsPackage):
Method of Motzkin et al. for generating all vertices (i.e. extreme points) Method of Motzkin et al. for generating all vertices (i.e. extreme points)
and extreme rays of a general convex polyhedron in R^d given by a system and extreme rays of a general convex polyhedron in R^d given by a system
of linear inequalities""" of linear inequalities"""
homepage = "https://www.inf.ethz.ch/personal/fukudak/cdd_home/"
# This is the original download url. It is currently down [2016-08-23],
# but should be reinstated or updated once the issue is resolved.
# url = "ftp://ftp.ifor.math.ethz.ch/pub/fukuda/cdd/cddlib-094h.tar.gz"
url = "http://pkgs.fedoraproject.org/lookaside/pkgs/cddlib/cddlib-094h.tar.gz/1467d270860bbcb26d3ebae424690e7c/cddlib-094h.tar.gz"
def url_for_version(self, version): homepage = "https://www.inf.ethz.ch/personal/fukudak/cdd_home/"
# Since the commit id is part of the version, we can't url = "ftp://ftp.math.ethz.ch/users/fukudak/cdd/cddlib-094h.tar.gz"
# auto-generate the string, and we need to explicitly list all
# known versions here. Currently, there is only one version.
if str(version) == '0.94h':
return "http://pkgs.fedoraproject.org/lookaside/pkgs/cddlib/cddlib-094h.tar.gz/1467d270860bbcb26d3ebae424690e7c/cddlib-094h.tar.gz"
raise InstallError("Unsupported version %s" % str(version))
version('0.94h', '1467d270860bbcb26d3ebae424690e7c') version('0.94h', '1467d270860bbcb26d3ebae424690e7c')
@ -51,3 +41,7 @@ def url_for_version(self, version):
depends_on("gmp") depends_on("gmp")
depends_on("libtool", type="build") depends_on("libtool", type="build")
def url_for_version(self, version):
url = "ftp://ftp.math.ethz.ch/users/fukudak/cdd/cddlib-{0}.tar.gz"
return url.format(version.joined)

View file

@ -30,9 +30,13 @@ class Cdo(Package):
Climate and NWP model Data. """ Climate and NWP model Data. """
homepage = "https://code.zmaw.de/projects/cdo" homepage = "https://code.zmaw.de/projects/cdo"
url = "https://code.zmaw.de/attachments/download/12760/cdo-1.7.2.tar.gz"
list_url = "https://code.zmaw.de/projects/cdo/files"
version('1.7.2', 'f08e4ce8739a4f2b63fc81a24db3ee31', url='https://code.zmaw.de/attachments/download/12760/cdo-1.7.2.tar.gz') version('1.7.2', 'f08e4ce8739a4f2b63fc81a24db3ee31',
version('1.6.9', 'bf0997bf20e812f35e10188a930e24e2', url='https://code.zmaw.de/attachments/download/10198/cdo-1.6.9.tar.gz') url='https://code.zmaw.de/attachments/download/12760/cdo-1.7.2.tar.gz')
version('1.6.9', 'bf0997bf20e812f35e10188a930e24e2',
url='https://code.zmaw.de/attachments/download/10198/cdo-1.6.9.tar.gz')
variant('szip', default=True, description='Enable szip compression for GRIB1') variant('szip', default=True, description='Enable szip compression for GRIB1')
variant('hdf5', default=False, description='Enable HDF5 support') variant('hdf5', default=False, description='Enable HDF5 support')
@ -54,7 +58,7 @@ class Cdo(Package):
depends_on('proj', when='+proj') depends_on('proj', when='+proj')
depends_on('curl', when='+curl') depends_on('curl', when='+curl')
depends_on('fftw', when='+fftw') depends_on('fftw', when='+fftw')
depends_on('magics', when='+magics') depends_on('magics', when='+magics')
def install(self, spec, prefix): def install(self, spec, prefix):
config_args = ["--prefix=" + prefix, config_args = ["--prefix=" + prefix,

View file

@ -31,6 +31,7 @@ class Cfitsio(AutotoolsPackage):
""" """
homepage = 'http://heasarc.gsfc.nasa.gov/fitsio/' homepage = 'http://heasarc.gsfc.nasa.gov/fitsio/'
url = 'http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio3410.tar.gz'
version('3.410', '8a4a66fcdd816aae41768baa0b025552') version('3.410', '8a4a66fcdd816aae41768baa0b025552')
version('3.370', 'abebd2d02ba5b0503c633581e3bfa116') version('3.370', 'abebd2d02ba5b0503c633581e3bfa116')

View file

@ -29,16 +29,13 @@ class Cppad(CMakePackage):
"""A Package for Differentiation of C++ Algorithms.""" """A Package for Differentiation of C++ Algorithms."""
homepage = "https://www.coin-or.org/CppAD/" homepage = "https://www.coin-or.org/CppAD/"
url = "http://www.coin-or.org/download/source/CppAD/cppad-20170114.gpl.tgz"
version('20170114', '565a534dc813fa1289764222cd8c11ea') version('20170114', '565a534dc813fa1289764222cd8c11ea')
version('develop', git='https://github.com/coin-or/CppAD.git') version('develop', git='https://github.com/coin-or/CppAD.git')
depends_on('cmake', type='build') depends_on('cmake', type='build')
def url_for_version(self, version):
"""Handle version-based custom URLs."""
return "http://www.coin-or.org/download/source/CppAD/cppad-%s.gpl.tgz" % (version)
def cmake_args(self): def cmake_args(self):
# This package does not obey CMAKE_INSTALL_PREFIX # This package does not obey CMAKE_INSTALL_PREFIX
args = [ args = [

View file

@ -36,6 +36,7 @@ class Cryptopp(Package):
""" """
homepage = "http://www.cryptopp.com" homepage = "http://www.cryptopp.com"
url = "http://www.cryptopp.com/cryptopp563.zip"
version('5.6.3', '3c5b70e2ec98b7a24988734446242d07') version('5.6.3', '3c5b70e2ec98b7a24988734446242d07')
version('5.6.2', '7ed022585698df48e65ce9218f6c6a67') version('5.6.2', '7ed022585698df48e65ce9218f6c6a67')

View file

@ -46,7 +46,6 @@ class Dakota(Package):
homepage = 'https://dakota.sandia.gov/' homepage = 'https://dakota.sandia.gov/'
url = 'https://dakota.sandia.gov/sites/default/files/distributions/public/dakota-6.3-public.src.tar.gz' url = 'https://dakota.sandia.gov/sites/default/files/distributions/public/dakota-6.3-public.src.tar.gz'
_url_str = 'https://dakota.sandia.gov/sites/default/files/distributions/public/dakota-{version}-public.src.tar.gz'
version('6.3', '05a58d209fae604af234c894c3f73f6d') version('6.3', '05a58d209fae604af234c894c3f73f6d')
@ -64,9 +63,6 @@ class Dakota(Package):
depends_on('boost') depends_on('boost')
depends_on('cmake', type='build') depends_on('cmake', type='build')
def url_for_version(self, version):
return Dakota._url_str.format(version=version)
def install(self, spec, prefix): def install(self, spec, prefix):
options = [] options = []
options.extend(std_cmake_args) options.extend(std_cmake_args)

View file

@ -29,7 +29,7 @@ class Exonerate(Package):
"""Pairwise sequence alignment of DNA and proteins""" """Pairwise sequence alignment of DNA and proteins"""
homepage = "http://www.ebi.ac.uk/about/vertebrate-genomics/software/exonerate" homepage = "http://www.ebi.ac.uk/about/vertebrate-genomics/software/exonerate"
url = "http://ftp.ebi.ac.uk/pub/software/vertebrategenomics/exonerate/exonerate-2.2.0.tar.gz" url = "http://ftp.ebi.ac.uk/pub/software/vertebrategenomics/exonerate/exonerate-2.4.0.tar.gz"
version('2.4.0', '126fbade003b80b663a1d530c56f1904') version('2.4.0', '126fbade003b80b663a1d530c56f1904')

View file

@ -31,11 +31,10 @@ class Ferret(Package):
"""Ferret is an interactive computer visualization and analysis environment """Ferret is an interactive computer visualization and analysis environment
designed to meet the needs of oceanographers and meteorologists designed to meet the needs of oceanographers and meteorologists
analyzing large and complex gridded data sets.""" analyzing large and complex gridded data sets."""
homepage = "http://ferret.noaa.gov/Ferret/" homepage = "http://ferret.pmel.noaa.gov/Ferret/home"
url = "ftp://ftp.pmel.noaa.gov/ferret/pub/source/fer_source.tar.gz" url = "ftp://ftp.pmel.noaa.gov/ferret/pub/source/fer_source.v696.tar.gz"
version('6.96', '51722027c864369f41bab5751dfff8cc', version('6.96', '51722027c864369f41bab5751dfff8cc')
url="ftp://ftp.pmel.noaa.gov/ferret/pub/source/fer_source.tar.gz")
depends_on("hdf5~mpi~fortran") depends_on("hdf5~mpi~fortran")
depends_on("netcdf~mpi") depends_on("netcdf~mpi")
@ -43,6 +42,10 @@ class Ferret(Package):
depends_on("readline") depends_on("readline")
depends_on("zlib") depends_on("zlib")
def url_for_version(self, version):
return "ftp://ftp.pmel.noaa.gov/ferret/pub/source/fer_source.v{0}.tar.gz".format(
version.joined)
def patch(self): def patch(self):
hdf5_prefix = self.spec['hdf5'].prefix hdf5_prefix = self.spec['hdf5'].prefix
netcdff_prefix = self.spec['netcdf-fortran'].prefix netcdff_prefix = self.spec['netcdf-fortran'].prefix

View file

@ -32,7 +32,9 @@ class GdkPixbuf(AutotoolsPackage):
GTK+ 2 but it was split off into a separate package in GTK+ 2 but it was split off into a separate package in
preparation for the change to GTK+ 3.""" preparation for the change to GTK+ 3."""
homepage = "https://developer.gnome.org/gdk-pixbuf/" homepage = "https://developer.gnome.org/gdk-pixbuf/"
url = "http://ftp.gnome.org/pub/gnome/sources/gdk-pixbuf/2.31/gdk-pixbuf-2.31.1.tar.xz" url = "http://ftp.gnome.org/pub/gnome/sources/gdk-pixbuf/2.31/gdk-pixbuf-2.31.2.tar.xz"
list_url = "http://ftp.acc.umu.se/pub/gnome/sources/gdk-pixbuf/"
list_depth = 2
version('2.31.2', '6be6bbc4f356d4b79ab4226860ab8523') version('2.31.2', '6be6bbc4f356d4b79ab4226860ab8523')

View file

@ -89,13 +89,6 @@ def patch(self):
r'# \1\2\3', r'# \1\2\3',
) )
@when('@1.5.0:')
def patch(self):
pass
def url_for_version(self, version):
return "https://storage.googleapis.com/golang/go{0}.src.tar.gz".format(version)
def install(self, spec, prefix): def install(self, spec, prefix):
bash = which('bash') bash = which('bash')
with working_dir('src'): with working_dir('src'):

View file

@ -52,10 +52,6 @@ class Gource(AutotoolsPackage):
parallel = False parallel = False
force_autoreconf = True force_autoreconf = True
def url_for_version(self, version):
tmp = 'https://github.com/acaudwell/Gource/releases/download/gource-{0}/gource-{0}.tar.gz' # NOQA: ignore=E501
return tmp.format(version.dotted)
def configure_args(self): def configure_args(self):
spec = self.spec spec = self.spec
return [ return [

View file

@ -29,9 +29,9 @@ class Ibmisc(CMakePackage):
"""Misc. reusable utilities used by IceBin.""" """Misc. reusable utilities used by IceBin."""
homepage = "https://github.com/citibeth/ibmisc" homepage = "https://github.com/citibeth/ibmisc"
url = "https://github.com/citibeth/ibmisc/tarball/123" url = "https://github.com/citibeth/ibmisc/archive/v0.1.0.tar.gz"
version('0.1.0', '12f2a32432a11db48e00217df18e59fa') version('0.1.0', '18c63db3e466c5a6fc2db3f903d06ecb')
variant('everytrace', default=False, variant('everytrace', default=False,
description='Report errors through Everytrace') description='Report errors through Everytrace')

View file

@ -30,7 +30,7 @@ class Icet(CMakePackage):
sort-last parallel rendering library.""" sort-last parallel rendering library."""
homepage = "http://icet.sandia.gov" homepage = "http://icet.sandia.gov"
url = "https://example.com/icet-1.2.3.tar.gz" url = "https://gitlab.kitware.com/icet/icet/repository/archive.tar.bz2?ref=IceT-2.1.1"
version('develop', branch='master', version('develop', branch='master',
git='https://gitlab.kitware.com/icet/icet.git') git='https://gitlab.kitware.com/icet/icet.git')
@ -38,9 +38,5 @@ class Icet(CMakePackage):
depends_on('mpi') depends_on('mpi')
def url_for_version(self, version):
return ("https://gitlab.kitware.com/icet/icet/repository/"
"archive.tar.bz2?ref=IceT-{0}".format(version.dotted))
def cmake_args(self): def cmake_args(self):
return ['-DICET_USE_OPENGL:BOOL=OFF'] return ['-DICET_USE_OPENGL:BOOL=OFF']

View file

@ -45,9 +45,6 @@ class ImageMagick(Package):
depends_on('ghostscript') depends_on('ghostscript')
depends_on('ghostscript-fonts') depends_on('ghostscript-fonts')
def url_for_version(self, version):
return "https://github.com/ImageMagick/ImageMagick/archive/{0}.tar.gz".format(version)
def install(self, spec, prefix): def install(self, spec, prefix):
gs_font_dir = join_path(spec['ghostscript-fonts'].prefix.share, "font") gs_font_dir = join_path(spec['ghostscript-fonts'].prefix.share, "font")
configure('--prefix={0}'.format(prefix), configure('--prefix={0}'.format(prefix),

View file

@ -45,10 +45,10 @@ class Jdk(Package):
'-H', # specify required License Agreement cookie '-H', # specify required License Agreement cookie
'Cookie: oraclelicense=accept-securebackup-cookie'] 'Cookie: oraclelicense=accept-securebackup-cookie']
version('8u66-linux-x64', '88f31f3d642c3287134297b8c10e61bf', version('8u66', '88f31f3d642c3287134297b8c10e61bf',
url="http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.tar.gz", url="http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.tar.gz",
curl_options=curl_options) curl_options=curl_options)
version('8u92-linux-x64', '65a1cc17ea362453a6e0eb4f13be76e4', version('8u92', '65a1cc17ea362453a6e0eb4f13be76e4',
url="http://download.oracle.com/otn-pub/java/jdk/8u92-b14/jdk-8u92-linux-x64.tar.gz", url="http://download.oracle.com/otn-pub/java/jdk/8u92-b14/jdk-8u92-linux-x64.tar.gz",
curl_options=curl_options) curl_options=curl_options)

View file

@ -30,7 +30,11 @@ class Libedit(AutotoolsPackage):
homepage = "http://thrysoee.dk/editline/" homepage = "http://thrysoee.dk/editline/"
url = "http://thrysoee.dk/editline/libedit-20150325-3.1.tar.gz" url = "http://thrysoee.dk/editline/libedit-20150325-3.1.tar.gz"
version('3.1', '43cdb5df3061d78b5e9d59109871b4f6', version('3.1-20160903', '0467d27684c453a351fbcefebbcb16a3')
url="http://thrysoee.dk/editline/libedit-20150325-3.1.tar.gz") version('3.1-20150325', '43cdb5df3061d78b5e9d59109871b4f6')
depends_on('ncurses') depends_on('ncurses')
def url_for_version(self, version):
url = "http://thrysoee.dk/editline/libedit-{0}-{1}.tar.gz"
return url.format(version[-1], version.up_to(-1))

View file

@ -56,7 +56,3 @@ class Libgd(AutotoolsPackage):
depends_on('libpng') depends_on('libpng')
depends_on('libtiff') depends_on('libtiff')
depends_on('fontconfig') depends_on('fontconfig')
def url_for_version(self, version):
url = "https://github.com/libgd/libgd/releases/download/gd-{0}/libgd-{0}.tar.gz"
return url.format(version)

View file

@ -30,6 +30,7 @@ class Libsodium(AutotoolsPackage):
decryption, signatures, password hashing and more.""" decryption, signatures, password hashing and more."""
homepage = "https://download.libsodium.org/doc/" homepage = "https://download.libsodium.org/doc/"
url = "https://download.libsodium.org/libsodium/releases/libsodium-1.0.11.tar.gz" url = "https://download.libsodium.org/libsodium/releases/libsodium-1.0.11.tar.gz"
list_url = "https://download.libsodium.org/libsodium/releases/old"
version('1.0.11', 'b58928d035064b2a46fb564937b83540') version('1.0.11', 'b58928d035064b2a46fb564937b83540')
version('1.0.10', 'ea89dcbbda0b2b6ff6a1c476231870dd') version('1.0.10', 'ea89dcbbda0b2b6ff6a1c476231870dd')

View file

@ -31,9 +31,9 @@ class Libxstream(Package):
conditions.''' conditions.'''
homepage = 'https://github.com/hfp/libxstream' homepage = 'https://github.com/hfp/libxstream'
url = 'https://github.com/hfp/libxstream.git' url = 'https://github.com/hfp/libxstream/archive/0.9.0.tar.gz'
version('0.9.0', git='https://github.com/hfp/libxstream.git') version('0.9.0', 'fd74b7cf5f145ff4925d91be2809571c')
def patch(self): def patch(self):
kwargs = {'ignore_absent': False, 'backup': True, 'string': True} kwargs = {'ignore_absent': False, 'backup': True, 'string': True}

View file

@ -30,6 +30,8 @@ class Meep(Package):
software package developed at MIT to model electromagnetic systems.""" software package developed at MIT to model electromagnetic systems."""
homepage = "http://ab-initio.mit.edu/wiki/index.php/Meep" homepage = "http://ab-initio.mit.edu/wiki/index.php/Meep"
url = "http://ab-initio.mit.edu/meep/meep-1.3.tar.gz"
list_url = "http://ab-initio.mit.edu/meep/old"
version('1.3', '18a5b9e18008627a0411087e0bb60db5') version('1.3', '18a5b9e18008627a0411087e0bb60db5')
version('1.2.1', '9be2e743c3a832ae922de9d955d016c5') version('1.2.1', '9be2e743c3a832ae922de9d955d016c5')

View file

@ -37,7 +37,8 @@ class Metis(Package):
partitioning schemes.""" partitioning schemes."""
homepage = "http://glaros.dtc.umn.edu/gkhome/metis/metis/overview" homepage = "http://glaros.dtc.umn.edu/gkhome/metis/metis/overview"
base_url = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis" url = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.1.0.tar.gz"
list_url = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD"
version('5.1.0', '5465e67079419a69e0116de24fce58fe') version('5.1.0', '5465e67079419a69e0116de24fce58fe')
version('5.0.2', 'acb521a4e8c2e6dd559a7f9abd0468c5') version('5.0.2', 'acb521a4e8c2e6dd559a7f9abd0468c5')
@ -55,12 +56,11 @@ class Metis(Package):
patch('install_gklib_defs_rename.patch', when='@5:') patch('install_gklib_defs_rename.patch', when='@5:')
def url_for_version(self, version): def url_for_version(self, version):
verdir = 'OLD/' if version < Version('4.0.3') else '' url = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis"
return '%s/%smetis-%s.tar.gz' % (Metis.base_url, verdir, version) if version < Version('4.0.3'):
url += "/OLD"
@when('@:4') url += "/metis-{0}.tar.gz".format(version)
def patch(self): return url
pass
@when('@5:') @when('@5:')
def patch(self): def patch(self):
@ -84,7 +84,7 @@ def patch(self):
filter_file('#define MAX_JBUFS 128', '#define MAX_JBUFS 24', filter_file('#define MAX_JBUFS 128', '#define MAX_JBUFS 24',
join_path(source_path, 'GKlib', 'error.c')) join_path(source_path, 'GKlib', 'error.c'))
@when('@:4') @when('@:4') # noqa: F811
def install(self, spec, prefix): def install(self, spec, prefix):
# Process library spec and options # Process library spec and options
if any('+{0}'.format(v) in spec for v in ['gdb', 'int64', 'real64']): if any('+{0}'.format(v) in spec for v in ['gdb', 'int64', 'real64']):
@ -175,7 +175,7 @@ def install(self, spec, prefix):
Executable(test_bin('mesh2dual'))(test_graph('metis.mesh')) Executable(test_bin('mesh2dual'))(test_graph('metis.mesh'))
""" """
@when('@5:') @when('@5:') # noqa: F811
def install(self, spec, prefix): def install(self, spec, prefix):
source_directory = self.stage.source_path source_directory = self.stage.source_path
build_directory = join_path(source_directory, 'build') build_directory = join_path(source_directory, 'build')
@ -187,7 +187,7 @@ def install(self, spec, prefix):
if '+shared' in spec: if '+shared' in spec:
options.append('-DSHARED:BOOL=ON') options.append('-DSHARED:BOOL=ON')
else: else:
# Remove all RPATH options # Remove all RPATH options
# (RPATHxxx options somehow trigger cmake to link dynamically) # (RPATHxxx options somehow trigger cmake to link dynamically)
rpath_options = [] rpath_options = []
for o in options: for o in options:

View file

@ -31,15 +31,32 @@ class Mfem(Package):
homepage = 'http://www.mfem.org' homepage = 'http://www.mfem.org'
url = 'https://github.com/mfem/mfem' url = 'https://github.com/mfem/mfem'
# mfem is downloaded from a URL shortener at request of upstream
# author Tzanio Kolev <tzanio@llnl.gov>. See here:
# https://github.com/mfem/mfem/issues/53
#
# The following procedure should be used to verify security when a
# new verison is added:
#
# 1. Verify that no checksums on old versions have changed.
#
# 2. Verify that the shortened URL for the new version is listed at:
# http://mfem.org/download/
#
# 3. Use http://getlinkinfo.com or similar to verify that the
# underling download link for the latest version comes has the
# prefix: http://mfem.github.io/releases
#
# If this quick verification procedure fails, additional discussion
# will be required to verify the new version.
version('3.2', version('3.2',
'2938c3deed4ec4f7fd5b5f5cfe656845282e86e2dcd477d292390058b7b94340', '2938c3deed4ec4f7fd5b5f5cfe656845282e86e2dcd477d292390058b7b94340',
url='http://goo.gl/Y9T75B', preferred=True, extension='.tar.gz') url='http://goo.gl/Y9T75B', extension='.tar.gz')
version('3.1', version('3.1',
'841ea5cf58de6fae4de0f553b0e01ebaab9cd9c67fa821e8a715666ecf18fc57', '841ea5cf58de6fae4de0f553b0e01ebaab9cd9c67fa821e8a715666ecf18fc57',
url='http://goo.gl/xrScXn', extension='.tar.gz') url='http://goo.gl/xrScXn', extension='.tar.gz')
# version('3.1', git='https://github.com/mfem/mfem.git',
# commit='dbae60fe32e071989b52efaaf59d7d0eb2a3b574')
variant('metis', default=False, description='Activate support for metis') variant('metis', default=False, description='Activate support for metis')
variant('hypre', default=False, description='Activate support for hypre') variant('hypre', default=False, description='Activate support for hypre')

View file

@ -30,13 +30,12 @@ class Mitos(Package):
performance data to view with MemAxes""" performance data to view with MemAxes"""
homepage = "https://github.com/llnl/Mitos" homepage = "https://github.com/llnl/Mitos"
url = "https://github.com/llnl/Mitos" url = "https://github.com/LLNL/Mitos/archive/v0.9.1.tar.gz"
version('0.9.2', version('0.9.2',
git='https://github.com/llnl/Mitos.git', git='https://github.com/llnl/Mitos.git',
commit='8cb143a2e8c00353ff531a781a9ca0992b0aaa3d') commit='8cb143a2e8c00353ff531a781a9ca0992b0aaa3d')
version('0.9.1', 'c6cb57f3cae54f5157affd97ef7ef79e')
version('0.9.1', git='https://github.com/llnl/Mitos.git', tag='v0.9.1')
depends_on('dyninst@8.2.1:') depends_on('dyninst@8.2.1:')
depends_on('hwloc') depends_on('hwloc')

View file

@ -35,7 +35,7 @@ class Moab(Package):
mesh in chunks rather than through individual entities, while also mesh in chunks rather than through individual entities, while also
versatile enough to support individual entity access.""" versatile enough to support individual entity access."""
homepage = "https://bitbucket.org/fathomteam/moab" homepage = "https://bitbucket.org/fathomteam/moab"
url = "http://ftp.mcs.anl.gov/pub/fathom/moab-4.6.3.tar.gz" url = "http://ftp.mcs.anl.gov/pub/fathom/moab-4.9.1.tar.gz"
version('4.9.1', '19cc2189fa266181ad9109b18d0b2ab8') version('4.9.1', '19cc2189fa266181ad9109b18d0b2ab8')
version('4.9.0', '40695d0a159040683cfa05586ad4a7c2') version('4.9.0', '40695d0a159040683cfa05586ad4a7c2')

View file

@ -41,9 +41,6 @@ class Mxml(AutotoolsPackage):
version('2.6', '68977789ae64985dddbd1a1a1652642e') version('2.6', '68977789ae64985dddbd1a1a1652642e')
version('2.5', 'f706377fba630b39fa02fd63642b17e5') version('2.5', 'f706377fba630b39fa02fd63642b17e5')
def url_for_version(self, version):
return "https://github.com/michaelrsweet/mxml/releases/download/release-{0}/mxml-{0}.tar.gz".format(version)
# module swap PrgEnv-intel PrgEnv-$COMP # module swap PrgEnv-intel PrgEnv-$COMP
# (Can use whatever compiler you want to use) # (Can use whatever compiler you want to use)
# Case statement to change CC and CXX flags # Case statement to change CC and CXX flags

View file

@ -30,7 +30,7 @@ class Nettle(AutotoolsPackage):
that is designed to fit easily in many contexts.""" that is designed to fit easily in many contexts."""
homepage = "https://www.lysator.liu.se/~nisse/nettle/" homepage = "https://www.lysator.liu.se/~nisse/nettle/"
url = "http://ftp.gnu.org/gnu/nettle/nettle-2.7.1.tar.gz" url = "http://ftp.gnu.org/gnu/nettle/nettle-3.2.tar.gz"
version('3.2', 'afb15b4764ebf1b4e6d06c62bd4d29e4') version('3.2', 'afb15b4764ebf1b4e6d06c62bd4d29e4')
version('2.7.1', '003d5147911317931dd453520eb234a5') version('2.7.1', '003d5147911317931dd453520eb234a5')

View file

@ -29,6 +29,7 @@ class Nextflow(Package):
"""Data-driven computational pipelines""" """Data-driven computational pipelines"""
homepage = "http://www.nextflow.io" homepage = "http://www.nextflow.io"
url = "https://github.com/nextflow-io/nextflow/releases/download/v0.24.1/nextflow"
version('0.24.1', '80ec8c4fe8e766e0bdd1371a50410d1d', version('0.24.1', '80ec8c4fe8e766e0bdd1371a50410d1d',
expand=False) expand=False)
@ -39,10 +40,6 @@ class Nextflow(Package):
depends_on('jdk') depends_on('jdk')
def url_for_version(self, version):
base_url = 'https://github.com/nextflow-io/nextflow/releases/download/v{0}/nextflow'
return base_url.format(version)
def install(self, spec, prefix): def install(self, spec, prefix):
mkdirp(prefix.bin) mkdirp(prefix.bin)
install("nextflow", join_path(prefix.bin, "nextflow")) install("nextflow", join_path(prefix.bin, "nextflow"))

View file

@ -32,6 +32,7 @@ class Oce(Package):
Open CASCADE library. Open CASCADE library.
""" """
homepage = "https://github.com/tpaviot/oce" homepage = "https://github.com/tpaviot/oce"
url = "https://github.com/tpaviot/oce/archive/OCE-0.18.tar.gz"
version('0.18', '226e45e77c16a4a6e127c71fefcd171410703960ae75c7ecc7eb68895446a993') version('0.18', '226e45e77c16a4a6e127c71fefcd171410703960ae75c7ecc7eb68895446a993')
version('0.17.2', 'bf2226be4cd192606af677cf178088e5') version('0.17.2', 'bf2226be4cd192606af677cf178088e5')
@ -46,10 +47,6 @@ class Oce(Package):
depends_on('cmake@2.8:', type='build') depends_on('cmake@2.8:', type='build')
depends_on('tbb', when='+tbb') depends_on('tbb', when='+tbb')
def url_for_version(self, version):
return 'https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz' % (
version.dotted)
# There is a bug in OCE which appears with Clang (version?) or GCC 6.0 # There is a bug in OCE which appears with Clang (version?) or GCC 6.0
# and has to do with compiler optimization, see # and has to do with compiler optimization, see
# https://github.com/tpaviot/oce/issues/576 # https://github.com/tpaviot/oce/issues/576

View file

@ -30,17 +30,11 @@ class Octopus(Package):
theory code.""" theory code."""
homepage = "http://www.tddft.org/programs/octopus/" homepage = "http://www.tddft.org/programs/octopus/"
base_url = "http://www.tddft.org/programs/octopus/down.php?file=" url = "http://www.tddft.org/programs/octopus/down.php?file=6.0/octopus-6.0.tar.gz"
version('6.0', '5d1168c2a8d7fd9cb9492eaebaa7182e') version('6.0', '5d1168c2a8d7fd9cb9492eaebaa7182e')
version('5.0.1', '2b6392ab67b843f9d4ca7413fc07e822') version('5.0.1', '2b6392ab67b843f9d4ca7413fc07e822')
# Sample url is:
# "http://www.tddft.org/programs/octopus/down.php?file=5.0.1/octopus-5.0.1.tar.gz"
def url_for_version(self, version):
return '{0}/{1}/octopus-{1}.tar.gz'.format(Octopus.base_url,
version.dotted)
variant('scalapack', default=False, variant('scalapack', default=False,
description='Compile with Scalapack') description='Compile with Scalapack')
variant('metis', default=True, variant('metis', default=True,

View file

@ -43,7 +43,3 @@ class Openjpeg(CMakePackage):
version('2.0', 'cdf266530fee8af87454f15feb619609') version('2.0', 'cdf266530fee8af87454f15feb619609')
version('1.5.2', '545f98923430369a6b046ef3632ef95c') version('1.5.2', '545f98923430369a6b046ef3632ef95c')
version('1.5.1', 'd774e4b5a0db5f0f171c4fc0aabfa14e') version('1.5.1', 'd774e4b5a0db5f0f171c4fc0aabfa14e')
def url_for_version(self, version):
fmt = 'https://github.com/uclouvain/openjpeg/archive/version.{0}.tar.gz'
return fmt.format(version.dotted)

View file

@ -29,9 +29,9 @@
class Panda(Package): class Panda(Package):
"""PANDA: Parallel AdjaceNcy Decomposition Algorithm""" """PANDA: Parallel AdjaceNcy Decomposition Algorithm"""
homepage = "http://comopt.ifi.uni-heidelberg.de/software/PANDA/index.html" homepage = "http://comopt.ifi.uni-heidelberg.de/software/PANDA/index.html"
url = "http://comopt.ifi.uni-heidelberg.de/software/PANDA/downloads/current_panda.tar" url = "http://comopt.ifi.uni-heidelberg.de/software/PANDA/downloads/panda-2016-03-07.tar"
version('current', 'b06dc312ee56e13eefea9c915b70fcef') version('2016-03-07', 'b06dc312ee56e13eefea9c915b70fcef')
# Note: Panda can also be built without MPI support # Note: Panda can also be built without MPI support

View file

@ -33,7 +33,8 @@ class Parmetis(Package):
computing fill-reducing orderings of sparse matrices.""" computing fill-reducing orderings of sparse matrices."""
homepage = 'http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview' homepage = 'http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview'
base_url = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis' url = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/parmetis-4.0.3.tar.gz'
list_url = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/OLD'
version('4.0.3', 'f69c479586bf6bb7aff6a9bc0c739628') version('4.0.3', 'f69c479586bf6bb7aff6a9bc0c739628')
version('4.0.2', '0912a953da5bb9b5e5e10542298ffdce') version('4.0.2', '0912a953da5bb9b5e5e10542298ffdce')
@ -54,8 +55,11 @@ class Parmetis(Package):
patch('pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch') patch('pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch')
def url_for_version(self, version): def url_for_version(self, version):
verdir = 'OLD/' if version < Version('3.2.0') else '' url = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis'
return '%s/%sparmetis-%s.tar.gz' % (Parmetis.base_url, verdir, version) if version < Version('3.2.0'):
url += '/OLD'
url += '/parmetis-{0}.tar.gz'.format(version)
return url
def install(self, spec, prefix): def install(self, spec, prefix):
source_directory = self.stage.source_path source_directory = self.stage.source_path
@ -72,7 +76,7 @@ def install(self, spec, prefix):
if '+shared' in spec: if '+shared' in spec:
options.append('-DSHARED:BOOL=ON') options.append('-DSHARED:BOOL=ON')
else: else:
# Remove all RPATH options # Remove all RPATH options
# (RPATHxxx options somehow trigger cmake to link dynamically) # (RPATHxxx options somehow trigger cmake to link dynamically)
rpath_options = [] rpath_options = []
for o in options: for o in options:

View file

@ -29,7 +29,7 @@ class Prank(Package):
"""A powerful multiple sequence alignment browser.""" """A powerful multiple sequence alignment browser."""
homepage = "http://wasabiapp.org/software/prank/" homepage = "http://wasabiapp.org/software/prank/"
url = "http://wasabiapp.org/download/prank/prank.source.140603.tgz" url = "http://wasabiapp.org/download/prank/prank.source.150803.tgz"
version('150803', '71ac2659e91c385c96473712c0a23e8a') version('150803', '71ac2659e91c385c96473712c0a23e8a')

View file

@ -30,10 +30,10 @@ class PyAutopep8(PythonPackage):
PEP 8 style guide.""" PEP 8 style guide."""
homepage = "https://github.com/hhatto/autopep8" homepage = "https://github.com/hhatto/autopep8"
url = "https://github.com/hhatto/autopep8/archive/v1.2.4.tar.gz" url = "https://pypi.io/packages/source/a/autopep8/autopep8-1.2.4.tar.gz"
version('1.2.4', '0458db85159a9e1b45f3e71ce6c158da') version('1.2.4', 'fcea19c0c5e505b425e2a78afb771f5c')
version('1.2.2', 'def3d023fc9dfd1b7113602e965ad8e1') version('1.2.2', '3d97f9c89d14a0975bffd32a2c61c36c')
extends('python', ignore='bin/pep8') extends('python', ignore='bin/pep8')
depends_on('python@2.6:2.7,3.2:') depends_on('python@2.6:2.7,3.2:')
@ -41,10 +41,3 @@ class PyAutopep8(PythonPackage):
depends_on('py-pycodestyle@1.5.7:1.7.0', type=('build', 'run')) depends_on('py-pycodestyle@1.5.7:1.7.0', type=('build', 'run'))
depends_on('py-setuptools', type='build') depends_on('py-setuptools', type='build')
def url_for_version(self, version):
url = "https://github.com/hhatto/autopep8/archive/{0}{1}.tar.gz"
if version >= Version('1.2.3'):
return url.format('v', version)
else:
return url.format('ver', version)

View file

@ -30,10 +30,9 @@ class PyCdo(PythonPackage):
Operators from Python.""" Operators from Python."""
homepage = "https://pypi.python.org/pypi/cdo" homepage = "https://pypi.python.org/pypi/cdo"
url = "https://pypi.python.org/packages/sources/c/cdo/cdo-1.3.2.tar.gz" url = "https://pypi.io/packages/source/c/cdo/cdo-1.3.2.tar.gz"
version('1.3.2', '4b3686ec1b9b891f166c1c466c6db745', version('1.3.2', '4b3686ec1b9b891f166c1c466c6db745')
url="https://pypi.python.org/packages/d6/13/908e7c1451e1f5fb68405f341cdcb3196a16952ebfe1f172cb788f864aa9/cdo-1.3.2.tar.gz")
depends_on('cdo') depends_on('cdo')

View file

@ -50,7 +50,3 @@ class PyMarkdown(PythonPackage):
depends_on('py-setuptools', type='build') depends_on('py-setuptools', type='build')
depends_on('python@2.7:2.8,3.2:3.4') depends_on('python@2.7:2.8,3.2:3.4')
def url_for_version(self, version):
base_url = "https://github.com/waylan/Python-Markdown/archive"
return "{0}/{1}-final.tar.gz".format(base_url, version)

View file

@ -32,9 +32,8 @@ class PyProj(PythonPackage):
# This is not a tagged release of pyproj. # This is not a tagged release of pyproj.
# The changes in this "version" fix some bugs, especially with Python3 use. # The changes in this "version" fix some bugs, especially with Python3 use.
version('1.9.5.1.1', 'd035e4bc704d136db79b43ab371b27d2', version('1.9.5.1.1', git='https://www.github.com/jswhit/pyproj.git',
url='https://www.github.com/jswhit/pyproj/tarball/0be612cc9f972e38b50a90c946a9b353e2ab140f') commit='0be612cc9f972e38b50a90c946a9b353e2ab140f')
version('1.9.5.1', 'a4b80d7170fc82aee363d7f980279835') version('1.9.5.1', 'a4b80d7170fc82aee363d7f980279835')
depends_on('py-cython', type='build') depends_on('py-cython', type='build')

View file

@ -38,6 +38,3 @@ class PyPypar(PythonPackage):
depends_on('py-numpy', type=('build', 'run')) depends_on('py-numpy', type=('build', 'run'))
build_directory = 'source' build_directory = 'source'
def url_for_version(self, version):
return "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/pypar/pypar-%s.tgz" % version

View file

@ -28,22 +28,9 @@
class PyRtree(PythonPackage): class PyRtree(PythonPackage):
"""Python interface to the RTREE.4 Library.""" """Python interface to the RTREE.4 Library."""
homepage = "http://toblerity.org/rtree/" homepage = "http://toblerity.org/rtree/"
url = "https://github.com/Toblerity/rtree/tarball/0.8.2" url = "https://pypi.io/packages/source/R/Rtree/Rtree-0.8.3.tar.gz"
# Not an official release yet. But changes in here are required version('0.8.3', 'a27cb05a85eed0a3605c45ebccc432f8')
# to work with Spack. As it does with all packages, Spack
# installs libspatialindex in a non-system location. Without the
# changes in this fork, py-rtree requires an environment variables
# to be set *at runtime*, in order to find libspatialindex. That
# is not feasible within the Spack worldview.
version('0.8.2.2', 'b1fe96a73153db49ea6ce45a063d82cb',
url='https://github.com/citibeth/rtree/tarball/95a678cc7350857a1bb631bc41254efcd1fc0a0d')
version('0.8.2.1', '394696ca849dd9f3a5ef24fb02a41ef4',
url='https://github.com/citibeth/rtree/tarball/3a87d86f66a3955676b2507d3bf424ade938a22b')
# Does not work with Spack
# version('0.8.2', '593c7ac6babc397b8ba58f1636c1e0a0')
depends_on('py-setuptools', type='build') depends_on('py-setuptools', type='build')
depends_on('libspatialindex') depends_on('libspatialindex')

View file

@ -29,7 +29,7 @@ class RLava(RPackage):
"""Estimation and simulation of latent variable models.""" """Estimation and simulation of latent variable models."""
homepage = "https://cran.r-project.org/package=lava" homepage = "https://cran.r-project.org/package=lava"
url = "https://cran.r-project.org/src/contrib/lava_1.4.6.tar.gz" url = "https://cran.r-project.org/src/contrib/lava_1.4.7.tar.gz"
list_url = "https://cran.r-project.org/src/contrib/Archive/lava" list_url = "https://cran.r-project.org/src/contrib/Archive/lava"
version('1.4.7', '28039248a7039ba9281d172e4dbf9543') version('1.4.7', '28039248a7039ba9281d172e4dbf9543')

View file

@ -30,7 +30,7 @@
class Root(Package): class Root(Package):
"""ROOT is a data analysis framework.""" """ROOT is a data analysis framework."""
homepage = "https://root.cern.ch" homepage = "https://root.cern.ch"
url = "https://root.cern.ch/download/root_v6.07.02.source.tar.gz" url = "https://root.cern.ch/download/root_v6.06.06.source.tar.gz"
version('6.06.06', '4308449892210c8d36e36924261fea26') version('6.06.06', '4308449892210c8d36e36924261fea26')
version('6.06.04', '55a2f98dd4cea79c9c4e32407c2d6d17') version('6.06.04', '55a2f98dd4cea79c9c4e32407c2d6d17')
@ -83,7 +83,3 @@ def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
spack_env.set('ROOTSYS', self.prefix) spack_env.set('ROOTSYS', self.prefix)
spack_env.set('ROOT_VERSION', 'v6') spack_env.set('ROOT_VERSION', 'v6')
spack_env.prepend_path('PYTHONPATH', self.prefix.lib) spack_env.prepend_path('PYTHONPATH', self.prefix.lib)
def url_for_version(self, version):
"""Handle ROOT's unusual version string."""
return "https://root.cern.ch/download/root_v%s.source.tar.gz" % version

View file

@ -35,10 +35,11 @@ class Rose(Package):
(Developed at Lawrence Livermore National Lab)""" (Developed at Lawrence Livermore National Lab)"""
homepage = "http://rosecompiler.org/" homepage = "http://rosecompiler.org/"
url = "https://github.com/rose-compiler/edg4x-rose" url = "https://github.com/rose-compiler/rose/archive/v0.9.7.tar.gz"
version('0.9.7', 'e14ce5250078df4b09f4f40559d46c75')
version('master', branch='master', version('master', branch='master',
git='https://github.com/rose-compiler/edg4x-rose.git') git='https://github.com/rose-compiler/rose.git')
patch('add_spack_compiler_recognition.patch') patch('add_spack_compiler_recognition.patch')
@ -46,7 +47,7 @@ class Rose(Package):
depends_on("automake@1.14", type='build') depends_on("automake@1.14", type='build')
depends_on("libtool@2.4", type='build') depends_on("libtool@2.4", type='build')
depends_on("boost@1.54.0") depends_on("boost@1.54.0")
depends_on("jdk@8u25-linux-x64") depends_on("jdk@8u25")
def install(self, spec, prefix): def install(self, spec, prefix):
# Bootstrap with autotools # Bootstrap with autotools

View file

@ -29,9 +29,9 @@
class RustBindgen(Package): class RustBindgen(Package):
"""The rust programming language toolchain""" """The rust programming language toolchain"""
homepage = "http://www.rust-lang.org" homepage = "http://www.rust-lang.org"
url = "https://github.com/crabtw/rust-bindgen" url = "https://github.com/servo/rust-bindgen/archive/v0.20.5.tar.gz"
version('0.16', tag='0.16', git='https://github.com/crabtw/rust-bindgen') version('0.20.5', '3e4d70a5bec540324fdd95bc9e82bebc')
extends("rust") extends("rust")
depends_on("llvm") depends_on("llvm")

View file

@ -32,14 +32,11 @@ class Scorep(Package):
""" """
homepage = "http://www.vi-hps.org/projects/score-p" homepage = "http://www.vi-hps.org/projects/score-p"
url = "http://www.vi-hps.org/upload/packages/scorep/scorep-1.2.3.tar.gz" url = "http://www.vi-hps.org/upload/packages/scorep/scorep-2.0.2.tar.gz"
version('2.0.2', '8f00e79e1b5b96e511c5ebecd10b2888', version('2.0.2', '8f00e79e1b5b96e511c5ebecd10b2888')
url='http://www.vi-hps.org/upload/packages/scorep/scorep-2.0.2.tar.gz') version('1.4.2', '3b9a042b13bdd5836452354e6567f71e')
version('1.4.2', '3b9a042b13bdd5836452354e6567f71e', version('1.3', '9db6f957b7f51fa01377a9537867a55c')
url='http://www.vi-hps.org/upload/packages/scorep/scorep-1.4.2.tar.gz')
version('1.3', '9db6f957b7f51fa01377a9537867a55c',
url='http://www.vi-hps.org/upload/packages/scorep/scorep-1.3.tar.gz')
########## ##########
# Dependencies for SCORE-P are quite tight. See the homepage for more # Dependencies for SCORE-P are quite tight. See the homepage for more

View file

@ -31,8 +31,7 @@ class Scotch(Package):
partitioning, graph clustering, and sparse matrix ordering.""" partitioning, graph clustering, and sparse matrix ordering."""
homepage = "http://www.labri.fr/perso/pelegrin/scotch/" homepage = "http://www.labri.fr/perso/pelegrin/scotch/"
url = "http://gforge.inria.fr/frs/download.php/latestfile/298/scotch_6.0.3.tar.gz" # noqa: E501 url = "http://gforge.inria.fr/frs/download.php/latestfile/298/scotch_6.0.4.tar.gz"
base_url = "http://gforge.inria.fr/frs/download.php/latestfile/298"
list_url = "http://gforge.inria.fr/frs/?group_id=248" list_url = "http://gforge.inria.fr/frs/?group_id=248"
version('6.0.4', 'd58b825eb95e1db77efe8c6ff42d329f') version('6.0.4', 'd58b825eb95e1db77efe8c6ff42d329f')
@ -71,12 +70,10 @@ class Scotch(Package):
# from the Scotch hosting site. These alternative archives include a # from the Scotch hosting site. These alternative archives include a
# superset of the behavior in their default counterparts, so we choose to # superset of the behavior in their default counterparts, so we choose to
# always grab these versions for older Scotch versions for simplicity. # always grab these versions for older Scotch versions for simplicity.
def url_for_version(self, version):
return super(Scotch, self).url_for_version(version)
@when('@:6.0.0') @when('@:6.0.0')
def url_for_version(self, version): def url_for_version(self, version):
return '%s/scotch_%s_esmumps.tar.gz' % (Scotch.base_url, version) url = "http://gforge.inria.fr/frs/download.php/latestfile/298/scotch_{0}_esmumps.tar.gz"
return url.format(version)
def patch(self): def patch(self):
self.configure() self.configure()

View file

@ -30,7 +30,7 @@ class Silo(Package):
data to binary, disk files.""" data to binary, disk files."""
homepage = "http://wci.llnl.gov/simulation/computer-codes/silo" homepage = "http://wci.llnl.gov/simulation/computer-codes/silo"
base_url = "https://wci.llnl.gov/content/assets/docs/simulation/computer-codes/silo" url = "https://wci.llnl.gov/content/assets/docs/simulation/computer-codes/silo/silo-4.10.2/silo-4.10.2.tar.gz"
version('4.10.2', '9ceac777a2f2469ac8cef40f4fab49c8') version('4.10.2', '9ceac777a2f2469ac8cef40f4fab49c8')
version('4.9', 'a83eda4f06761a86726e918fc55e782a') version('4.9', 'a83eda4f06761a86726e918fc55e782a')
@ -67,6 +67,3 @@ def install(self, spec, prefix):
make() make()
make('install') make('install')
def url_for_version(self, version):
return '%s/silo-%s/silo-%s.tar.gz' % (Silo.base_url, version, version)

View file

@ -31,6 +31,7 @@ class StarCcmPlus(Package):
"""STAR-CCM+ (Computational Continuum Mechanics) CFD solver.""" """STAR-CCM+ (Computational Continuum Mechanics) CFD solver."""
homepage = "http://mdx.plm.automation.siemens.com/star-ccm-plus" homepage = "http://mdx.plm.automation.siemens.com/star-ccm-plus"
url = "file://{0}/STAR-CCM+11.06.010_02_linux-x86_64.tar.gz".format(os.getcwd())
version('11.06.010_02', 'd349c6ac8293d8e6e7a53533d695588f') version('11.06.010_02', 'd349c6ac8293d8e6e7a53533d695588f')
@ -40,10 +41,6 @@ class StarCcmPlus(Package):
license_required = True license_required = True
license_vars = ['CDLMD_LICENSE_FILE', 'LM_LICENSE_FILE'] license_vars = ['CDLMD_LICENSE_FILE', 'LM_LICENSE_FILE']
def url_for_version(self, version):
return "file://{0}/STAR-CCM+{1}_linux-x86_64.tar.gz".format(
os.getcwd(), version)
def install(self, spec, prefix): def install(self, spec, prefix):
# There is a known issue with the LaunchAnywhere application. # There is a known issue with the LaunchAnywhere application.
# Specifically, it cannot handle long prompts or prompts # Specifically, it cannot handle long prompts or prompts

View file

@ -33,8 +33,8 @@ class SublimeText(Package):
homepage = "http://www.sublimetext.com/" homepage = "http://www.sublimetext.com/"
url = "https://download.sublimetext.com/sublime_text_3_build_3126_x64.tar.bz2" url = "https://download.sublimetext.com/sublime_text_3_build_3126_x64.tar.bz2"
version('3126', 'acc34252b0ea7dff1f581c5db1564dcb') version('3_build_3126', 'acc34252b0ea7dff1f581c5db1564dcb')
version('2.0.2', '699cd26d7fe0bada29eb1b2cd7b50e4b') version('2.0.2', '699cd26d7fe0bada29eb1b2cd7b50e4b')
# Sublime text comes as a pre-compiled binary. # Sublime text comes as a pre-compiled binary.
# Since we can't link to Spack packages, we'll just have to # Since we can't link to Spack packages, we'll just have to

View file

@ -34,6 +34,7 @@ class Tcl(AutotoolsPackage):
that is truly cross platform, easily deployed and highly that is truly cross platform, easily deployed and highly
extensible.""" extensible."""
homepage = "http://www.tcl.tk" homepage = "http://www.tcl.tk"
url = "http://prdownloads.sourceforge.net/tcl/tcl8.6.5-src.tar.gz"
version('8.6.6', '5193aea8107839a79df8ac709552ecb7') version('8.6.6', '5193aea8107839a79df8ac709552ecb7')
version('8.6.5', '0e6426a4ca9401825fbc6ecf3d89a326') version('8.6.5', '0e6426a4ca9401825fbc6ecf3d89a326')
@ -45,10 +46,6 @@ class Tcl(AutotoolsPackage):
configure_directory = 'unix' configure_directory = 'unix'
def url_for_version(self, version):
base_url = 'http://prdownloads.sourceforge.net/tcl'
return '{0}/tcl{1}-src.tar.gz'.format(base_url, version)
def setup_environment(self, spack_env, run_env): def setup_environment(self, spack_env, run_env):
# When using Tkinter from within spack provided python+tk, python # When using Tkinter from within spack provided python+tk, python
# will not be able to find Tcl/Tk unless TCL_LIBRARY is set. # will not be able to find Tcl/Tk unless TCL_LIBRARY is set.

View file

@ -34,7 +34,7 @@ class Tetgen(Package):
boundary conforming Delaunay meshes, and Voronoi paritions. boundary conforming Delaunay meshes, and Voronoi paritions.
""" """
homepage = "http://www.tetgen.org" homepage = "http://wias-berlin.de/software/tetgen/"
version('1.5.0', '3b9fd9cdec121e52527b0308f7aad5c1', url='http://www.tetgen.org/1.5/src/tetgen1.5.0.tar.gz') version('1.5.0', '3b9fd9cdec121e52527b0308f7aad5c1', url='http://www.tetgen.org/1.5/src/tetgen1.5.0.tar.gz')
version('1.4.3', 'd6a4bcdde2ac804f7ec66c29dcb63c18', url='http://www.tetgen.org/files/tetgen1.4.3.tar.gz') version('1.4.3', 'd6a4bcdde2ac804f7ec66c29dcb63c18', url='http://www.tetgen.org/files/tetgen1.4.3.tar.gz')

View file

@ -34,6 +34,10 @@ class Tinyxml(CMakePackage):
version('2.6.2', 'cba3f50dd657cb1434674a03b21394df9913d764') version('2.6.2', 'cba3f50dd657cb1434674a03b21394df9913d764')
def url_for_version(self, version):
url = "https://sourceforge.net/projects/tinyxml/files/tinyxml/{0}/tinyxml_{1}.tar.gz"
return url.format(version.dotted, version.underscored)
def patch(self): def patch(self):
copyfile(join_path(os.path.dirname(__file__), copyfile(join_path(os.path.dirname(__file__),
"CMakeLists.txt"), "CMakeLists.txt") "CMakeLists.txt"), "CMakeLists.txt")

View file

@ -33,6 +33,7 @@ class Tk(AutotoolsPackage):
applications that run unchanged across Windows, Mac OS X, Linux applications that run unchanged across Windows, Mac OS X, Linux
and more.""" and more."""
homepage = "http://www.tcl.tk" homepage = "http://www.tcl.tk"
url = "http://prdownloads.sourceforge.net/tcl/tk8.6.5-src.tar.gz"
version('8.6.6', 'dd7dbb3a6523c42d05f6ab6e86096e99') version('8.6.6', 'dd7dbb3a6523c42d05f6ab6e86096e99')
version('8.6.5', '11dbbd425c3e0201f20d6a51482ce6c4') version('8.6.5', '11dbbd425c3e0201f20d6a51482ce6c4')
@ -43,10 +44,6 @@ class Tk(AutotoolsPackage):
configure_directory = 'unix' configure_directory = 'unix'
def url_for_version(self, version):
base_url = "http://prdownloads.sourceforge.net/tcl"
return "{0}/tk{1}-src.tar.gz".format(base_url, version)
def setup_environment(self, spack_env, run_env): def setup_environment(self, spack_env, run_env):
# When using Tkinter from within spack provided python+tk, python # When using Tkinter from within spack provided python+tk, python
# will not be able to find Tcl/Tk unless TK_LIBRARY is set. # will not be able to find Tcl/Tk unless TK_LIBRARY is set.

View file

@ -44,7 +44,7 @@ class Trilinos(CMakePackage):
A unique design feature of Trilinos is its focus on packages. A unique design feature of Trilinos is its focus on packages.
""" """
homepage = "https://trilinos.org/" homepage = "https://trilinos.org/"
base_url = "https://github.com/trilinos/Trilinos/archive" url = "https://github.com/trilinos/Trilinos/archive/trilinos-release-12-10-1.tar.gz"
version('develop', version('develop',
git='https://github.com/trilinos/Trilinos.git', tag='develop') git='https://github.com/trilinos/Trilinos.git', tag='develop')
@ -63,10 +63,6 @@ class Trilinos(CMakePackage):
version('11.14.2', 'e7c3cdbbfe3279a8a68838b873ad6d51') version('11.14.2', 'e7c3cdbbfe3279a8a68838b873ad6d51')
version('11.14.1', 'b7760b142eef66c79ed13de7c9560f81') version('11.14.1', 'b7760b142eef66c79ed13de7c9560f81')
def url_for_version(self, version):
return '%s/trilinos-release-%s.tar.gz' % \
(Trilinos.base_url, version.dashed)
variant('xsdkflags', default=False, variant('xsdkflags', default=False,
description='Compile using the default xSDK configuration') description='Compile using the default xSDK configuration')
variant('metis', default=True, variant('metis', default=True,
@ -125,6 +121,10 @@ def url_for_version(self, version):
patch('umfpack_from_suitesparse.patch', when='@:12.8.1') patch('umfpack_from_suitesparse.patch', when='@:12.8.1')
def url_for_version(self, version):
url = "https://github.com/trilinos/Trilinos/archive/trilinos-release-{0}.tar.gz"
return url.format(version.dashed)
# check that the combination of variants makes sense # check that the combination of variants makes sense
def variants_check(self): def variants_check(self):
if '+superlu-dist' in self.spec and self.spec.satisfies('@:11.4.3'): if '+superlu-dist' in self.spec and self.spec.satisfies('@:11.4.3'):

View file

@ -34,7 +34,7 @@ class Unison(Package):
other.""" other."""
homepage = "https://www.cis.upenn.edu/~bcpierce/unison/" homepage = "https://www.cis.upenn.edu/~bcpierce/unison/"
url = "https://www.seas.upenn.edu/~bcpierce/unison//download/releases/stable/unison-2.48.3.tar.gz" url = "https://www.seas.upenn.edu/~bcpierce/unison//download/releases/stable/unison-2.48.4.tar.gz"
version('2.48.4', '5334b78c7e68169df7de95f4c6c4b60f') version('2.48.4', '5334b78c7e68169df7de95f4c6c4b60f')

View file

@ -31,19 +31,10 @@ class Voropp(MakefilePackage):
scientific fields.""" scientific fields."""
homepage = "http://math.lbl.gov/voro++/about.html" homepage = "http://math.lbl.gov/voro++/about.html"
url = "http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz"
# This url is wrong but it passes the test the ++ make the url parser fail,
# the correct url is constructed by url_for_version that has to be used in
# any case due to the difference between the package name and the url
url = "http://math.lbl.gov/voropp/download/dir/voropp-0.4.6.tar.gz"
version('0.4.6', '2338b824c3b7b25590e18e8df5d68af9') version('0.4.6', '2338b824c3b7b25590e18e8df5d68af9')
def url_for_version(self, version):
url = "http://math.lbl.gov/voro++/download/dir/voro++-{0}.tar.gz".format( # noqa: E501
str(version))
return url
def edit(self, spec, prefix): def edit(self, spec, prefix):
filter_file(r'CC=g\+\+', filter_file(r'CC=g\+\+',
'CC={0}'.format(self.compiler.cxx), 'CC={0}'.format(self.compiler.cxx),

View file

@ -33,6 +33,7 @@ class Vtk(CMakePackage):
homepage = "http://www.vtk.org" homepage = "http://www.vtk.org"
url = "http://www.vtk.org/files/release/7.1/VTK-7.1.0.tar.gz" url = "http://www.vtk.org/files/release/7.1/VTK-7.1.0.tar.gz"
list_url = "http://www.vtk.org/download/"
version('7.1.0', 'a7e814c1db503d896af72458c2d0228f') version('7.1.0', 'a7e814c1db503d896af72458c2d0228f')
version('7.0.0', '5fe35312db5fb2341139b8e4955c367d') version('7.0.0', '5fe35312db5fb2341139b8e4955c367d')

View file

@ -32,16 +32,12 @@ class Xsdktrilinos(CMakePackage):
Trilinos. Trilinos.
""" """
homepage = "https://trilinos.org/" homepage = "https://trilinos.org/"
base_url = "https://github.com/trilinos/xSDKTrilinos/archive" url = "https://github.com/trilinos/xSDKTrilinos/archive/trilinos-release-12-8-1.tar.gz"
version('develop', git='https://github.com/trilinos/xSDKTrilinos.git', tag='master') version('develop', git='https://github.com/trilinos/xSDKTrilinos.git', tag='master')
version('12.8.1', '9cc338ded17d1e10ea6c0dc18b22dcd4') version('12.8.1', '9cc338ded17d1e10ea6c0dc18b22dcd4')
version('12.6.4', '44c4c54ccbac73bb8939f68797b9454a') version('12.6.4', '44c4c54ccbac73bb8939f68797b9454a')
def url_for_version(self, version):
return '%s/trilinos-release-%s.tar.gz' % \
(Xsdktrilinos.base_url, version.dashed)
variant('hypre', default=True, variant('hypre', default=True,
description='Compile with Hypre preconditioner') description='Compile with Hypre preconditioner')
variant('petsc', default=True, variant('petsc', default=True,
@ -59,6 +55,10 @@ def url_for_version(self, version):
depends_on('trilinos@12.8.1', when='@12.8.1') depends_on('trilinos@12.8.1', when='@12.8.1')
depends_on('trilinos@develop', when='@develop') depends_on('trilinos@develop', when='@develop')
def url_for_version(self, version):
url = "https://github.com/trilinos/xSDKTrilinos/archive/trilinos-release-{0}.tar.gz"
return url.format(version.dashed)
def cmake_args(self): def cmake_args(self):
spec = self.spec spec = self.spec

View file

@ -31,7 +31,7 @@
class Yorick(Package): class Yorick(Package):
"""Yorick is an interpreted programming language for scientific simulations """Yorick is an interpreted programming language for scientific simulations
or calculations, postprocessing or steering large simulation codes, or calculations, postprocessing or steering large simulation codes,
interactive scientific graphics, and reading, writing, or translating interactive scientific graphics, and reading, writing, or translating
files of numbers. Yorick includes an interactive graphics package, and a files of numbers. Yorick includes an interactive graphics package, and a
binary file package capable of translating to and from the raw numeric binary file package capable of translating to and from the raw numeric
formats of all modern computers. Yorick is written in ANSI C and runs on formats of all modern computers. Yorick is written in ANSI C and runs on
@ -39,9 +39,9 @@ class Yorick(Package):
""" """
homepage = "http://dhmunro.github.io/yorick-doc/" homepage = "http://dhmunro.github.io/yorick-doc/"
url = "https://github.com/dhmunro/yorick/archive/y_2_2_04.tar.gz" url = "https://github.com/dhmunro/yorick/archive/y_2_2_04.tar.gz"
version('2.2.04', md5='1b5b0da6ad81b2d9dba64d991ec17939') version('2.2.04', '1b5b0da6ad81b2d9dba64d991ec17939')
version('master', branch='master', version('master', branch='master',
git='https://github.com/dhmunro/yorick.git') git='https://github.com/dhmunro/yorick.git')
version('f90-plugin', branch='f90-plugin', version('f90-plugin', branch='f90-plugin',
@ -51,6 +51,10 @@ class Yorick(Package):
depends_on('libx11', when='+X') depends_on('libx11', when='+X')
def url_for_version(self, version):
url = "https://github.com/dhmunro/yorick/archive/y_{0}.tar.gz"
return url.format(version.underscored)
def install(self, spec, prefix): def install(self, spec, prefix):
os.environ['FORTRAN_LINKAGE'] = '-Df_linkage' os.environ['FORTRAN_LINKAGE'] = '-Df_linkage'

View file

@ -41,7 +41,7 @@ class Zoltan(Package):
""" """
homepage = "http://www.cs.sandia.gov/zoltan" homepage = "http://www.cs.sandia.gov/zoltan"
base_url = "http://www.cs.sandia.gov/~kddevin/Zoltan_Distributions" url = "http://www.cs.sandia.gov/~kddevin/Zoltan_Distributions/zoltan_distrib_v3.83.tar.gz"
version('3.83', '1ff1bc93f91e12f2c533ddb01f2c095f') version('3.83', '1ff1bc93f91e12f2c533ddb01f2c095f')
version('3.8', '9d8fba8a990896881b85351d4327c4a9') version('3.8', '9d8fba8a990896881b85351d4327c4a9')
@ -56,9 +56,6 @@ class Zoltan(Package):
depends_on('mpi', when='+mpi') depends_on('mpi', when='+mpi')
def url_for_version(self, version):
return '%s/zoltan_distrib_v%s.tar.gz' % (Zoltan.base_url, version)
def install(self, spec, prefix): def install(self, spec, prefix):
# FIXME: The older Zoltan versions fail to compile the F90 MPI wrappers # FIXME: The older Zoltan versions fail to compile the F90 MPI wrappers
# because of some complicated generic type problem. # because of some complicated generic type problem.