Merge branch 'develop' of https://github.com/LLNL/spack into features/module_refresh_reworking

Conflicts:
	lib/spack/spack/cmd/module.py
This commit is contained in:
Massimiliano Culpo 2016-06-30 22:19:46 +02:00
commit ba1ada5424
19 changed files with 470 additions and 38 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
/var/spack/stage
/var/spack/cache
*.pyc
/opt/
*~

View File

@ -1131,6 +1131,79 @@ of module files:
"""Set up the compile and runtime environments for a package."""
pass
Recursive Modules
``````````````````
In some cases, it is desirable to load not just a module, but also all
the modules it depends on. This is not required for most modules
because Spack builds binaries with RPATH support. However, not all
packages use RPATH to find their dependencies: this can be true in
particular for Python extensions, which are currently *not* built with
RPATH.
Modules may be loaded recursively with the command:
.. code-block:: sh
$ module load `spack module tcl --dependencies <spec>...
More than one spec may be placed on the command line here.
Module Comamnds for Shell Scripts
``````````````````````````````````
Although Spack is flexbile, the ``module`` command is much faster.
This could become an issue when emitting a series of ``spack load``
commands inside a shell script. By adding the ``--shell`` flag,
``spack module find`` may also be used to generate code that can be
cut-and-pasted into a shell script. For example:
.. code-block:: sh
$ spack module find tcl --dependencies --shell py-numpy git
# bzip2@1.0.6%gcc@4.9.3=linux-x86_64
module load bzip2-1.0.6-gcc-4.9.3-ktnrhkrmbbtlvnagfatrarzjojmkvzsx
# ncurses@6.0%gcc@4.9.3=linux-x86_64
module load ncurses-6.0-gcc-4.9.3-kaazyneh3bjkfnalunchyqtygoe2mncv
# zlib@1.2.8%gcc@4.9.3=linux-x86_64
module load zlib-1.2.8-gcc-4.9.3-v3ufwaahjnviyvgjcelo36nywx2ufj7z
# sqlite@3.8.5%gcc@4.9.3=linux-x86_64
module load sqlite-3.8.5-gcc-4.9.3-a3eediswgd5f3rmto7g3szoew5nhehbr
# readline@6.3%gcc@4.9.3=linux-x86_64
module load readline-6.3-gcc-4.9.3-se6r3lsycrwxyhreg4lqirp6xixxejh3
# python@3.5.1%gcc@4.9.3=linux-x86_64
module load python-3.5.1-gcc-4.9.3-5q5rsrtjld4u6jiicuvtnx52m7tfhegi
# py-setuptools@20.5%gcc@4.9.3=linux-x86_64
module load py-setuptools-20.5-gcc-4.9.3-4qr2suj6p6glepnedmwhl4f62x64wxw2
# py-nose@1.3.7%gcc@4.9.3=linux-x86_64
module load py-nose-1.3.7-gcc-4.9.3-pwhtjw2dvdvfzjwuuztkzr7b4l6zepli
# openblas@0.2.17%gcc@4.9.3+shared=linux-x86_64
module load openblas-0.2.17-gcc-4.9.3-pw6rmlom7apfsnjtzfttyayzc7nx5e7y
# py-numpy@1.11.0%gcc@4.9.3+blas+lapack=linux-x86_64
module load py-numpy-1.11.0-gcc-4.9.3-mulodttw5pcyjufva4htsktwty4qd52r
# curl@7.47.1%gcc@4.9.3=linux-x86_64
module load curl-7.47.1-gcc-4.9.3-ohz3fwsepm3b462p5lnaquv7op7naqbi
# autoconf@2.69%gcc@4.9.3=linux-x86_64
module load autoconf-2.69-gcc-4.9.3-bkibjqhgqm5e3o423ogfv2y3o6h2uoq4
# cmake@3.5.0%gcc@4.9.3~doc+ncurses+openssl~qt=linux-x86_64
module load cmake-3.5.0-gcc-4.9.3-x7xnsklmgwla3ubfgzppamtbqk5rwn7t
# expat@2.1.0%gcc@4.9.3=linux-x86_64
module load expat-2.1.0-gcc-4.9.3-6pkz2ucnk2e62imwakejjvbv6egncppd
# git@2.8.0-rc2%gcc@4.9.3+curl+expat=linux-x86_64
module load git-2.8.0-rc2-gcc-4.9.3-3bib4hqtnv5xjjoq5ugt3inblt4xrgkd
The script may be further edited by removing unnecessary modules.
This script may be directly executed in bash via
.. code-block :: sh
source <( spack module find tcl --dependencies --shell py-numpy git )
Regenerating Module files
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
@ -1395,23 +1468,23 @@ files in the ``cmake`` package while retaining its dependencies.
.. code-block:: sh
$ spack view -v symlink myview cmake@3.5.2
==> Linking package: "ncurses"
==> Linking package: "zlib"
==> Linking package: "openssl"
==> Linking package: "cmake"
$ ls myview/
bin doc etc include lib share
$ ls myview/bin/
captoinfo clear cpack ctest infotocap openssl tabs toe tset
ccmake cmake c_rehash infocmp ncurses6-config reset tic tput
$ spack view -v -d false rm myview cmake@3.5.2
==> Removing package: "cmake"
$ ls myview/bin/
captoinfo c_rehash infotocap openssl tabs toe tset
clear infocmp ncurses6-config reset tic tput
@ -1421,7 +1494,7 @@ Limitations of Filesystem Views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section describes some limitations that should be considered in
using filesystems views.
using filesystems views.
Filesystem views are merely organizational. The binary executable
programs, shared libraries and other build products found in a view

View File

@ -80,10 +80,11 @@ with a high level view of Spack's directory structure::
var/
spack/ <- build & stage directories
repos/ <- contains package repositories
builtin/ <- pkg repository that comes with Spack
repo.yaml <- descriptor for the builtin repository
packages/ <- directories under here contain packages
repos/ <- contains package repositories
builtin/ <- pkg repository that comes with Spack
repo.yaml <- descriptor for the builtin repository
packages/ <- directories under here contain packages
cache/ <- saves resources downloaded during installs
opt/
spack/ <- packages are installed here

View File

@ -214,3 +214,21 @@ Adding a mirror really adds a line in ``~/.spack/mirrors.yaml``::
If you want to change the order in which mirrors are searched for
packages, you can edit this file and reorder the sections. Spack will
search the topmost mirror first and the bottom-most mirror last.
.. _caching:
Local Default Cache
----------------------------
Spack caches resources that are downloaded as part of installs. The cache is
a valid spack mirror: it uses the same directory structure and naming scheme
as other Spack mirrors (so it can be copied anywhere and referenced with a URL
like other mirrors). The mirror is maintained locally (within the Spack
installation directory) at :file:`var/spack/cache/`. It is always enabled (and
is always searched first when attempting to retrieve files for an installation)
but can be cleared with :ref:`purge <spack-purge>`; the cache directory can also
be deleted manually without issue.
Caching includes retrieved tarball archives and source control repositories, but
only resources with an associated digest or commit ID (e.g. a revision number
for SVN) will be cached.

View File

@ -703,6 +703,13 @@ Fetching a revision
Subversion branches are handled as part of the directory structure, so
you can check out a branch or tag by changing the ``url``.
Automatic caching of files fetched during installation
------------------------------------------------------
Spack maintains a cache (described :ref:`here <caching>`) which saves files
retrieved during package installations to avoid re-downloading in the case that
a package is installed with a different specification (but the same version) or
reinstalled on account of a change in the hashing scheme.
.. _license:
@ -776,7 +783,7 @@ Spack will create a global license file located at
file using the editor set in ``$EDITOR``, or vi if unset. It will look like
this:
.. code-block::
.. code-block:: sh
# A license is required to use pgi.
#
@ -807,7 +814,7 @@ You can add your license directly to this file, or tell FlexNet to use a
license stored on a separate license server. Here is an example that
points to a license server called licman1:
.. code-block::
.. code-block:: sh
SERVER licman1.mcs.anl.gov 00163eb7fba5 27200
USE_SERVER
@ -2618,11 +2625,16 @@ build process will start from scratch.
``spack purge``
~~~~~~~~~~~~~~~~~
Cleans up all of Spack's temporary files. Use this to recover disk
space if temporary files from interrupted or failed installs
accumulate in the staging area. This is equivalent to running ``spack
clean`` for every package you have fetched or staged.
Cleans up all of Spack's temporary and cached files. This can be used to
recover disk space if temporary files from interrupted or failed installs
accumulate in the staging area.
When called with ``--stage`` or ``--all`` (or without arguments, in which case
the default is ``--all``) this removes all staged files; this is equivalent to
running ``spack clean`` for every package you have fetched or staged.
When called with ``--cache`` or ``--all`` this will clear all resources
:ref:`cached <caching>` during installs.
Keeping the stage directory on success
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -48,6 +48,10 @@
stage_path = join_path(var_path, "stage")
repos_path = join_path(var_path, "repos")
share_path = join_path(spack_root, "share", "spack")
cache_path = join_path(var_path, "cache")
import spack.fetch_strategy
cache = spack.fetch_strategy.FsCache(cache_path)
prefix = spack_root
opt_path = join_path(prefix, "opt")

View File

@ -95,9 +95,9 @@ class ${class_name}(Package):
url = "${url}"
${versions}
${extends}
# FIXME: Add dependencies if this package requires them.
# depends_on("foo")
# FIXME: Add additional dependencies if required.
${dependencies}
def install(self, spec, prefix):
${install}
@ -136,8 +136,18 @@ def setup_parser(subparser):
class ConfigureGuesser(object):
def __call__(self, stage):
"""Try to guess the type of build system used by the project.
Set the appropriate default installation instructions and any
necessary extensions for Python and R."""
Set any necessary build dependencies or extensions.
Set the appropriate default installation instructions."""
# Build dependencies and extensions
dependenciesDict = {
'autotools': "# depends_on('foo')",
'cmake': "depends_on('cmake')",
'scons': "depends_on('scons')",
'python': "extends('python')",
'R': "extends('R')",
'unknown': "# depends_on('foo')"
}
# Default installation instructions
installDict = {
@ -214,16 +224,12 @@ def __call__(self, stage):
self.build_system = build_system
# Set any necessary build dependencies or extensions.
self.dependencies = dependenciesDict[build_system]
# Set the appropriate default installation instructions
self.install = installDict[build_system]
# Set any necessary extensions for Python and R
extensions = ''
if build_system in ['python', 'R']:
extensions = "\n extends('{0}')\n".format(build_system)
self.extends = extensions
def guess_name_and_version(url, args):
# Try to deduce name and version of the new package from the URL
@ -361,7 +367,7 @@ def create(parser, args):
class_name=mod_to_class(name),
url=url,
versions=make_version_calls(ver_hash_tuples),
extends=guesser.extends,
dependencies=guesser.dependencies,
install=guesser.install))
# If everything checks out, go ahead and edit.

View File

@ -31,7 +31,7 @@ def setup_parser(subparser):
"""Parser is only constructed so that this prints a nice help
message with -h. """
subparser.add_argument(
'spec', nargs=argparse.REMAINDER, help='Spec of package to load with modules.')
'spec', nargs=argparse.REMAINDER, help="Spec of package to load with modules. (If -, read specs from STDIN)")
def load(parser, args):

View File

@ -22,6 +22,7 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from __future__ import print_function
import os
import shutil
import sys
@ -54,6 +55,18 @@ def setup_parser(subparser):
# spack module find
find_parser = sp.add_parser('find', help='Find module files for packages.')
find_parser.add_argument(
'-r', '--dependencies', action='store_true',
dest='recurse_dependencies',
help='Recursively traverse dependencies for modules to load.')
find_parser.add_argument(
'-s', '--shell', action='store_true', dest='shell',
help='Generate shell script (instead of input for module command)')
find_parser.add_argument(
'-p', '--prefix', dest='prefix',
help='Prepend to module names when issuing module load commands')
_add_common_arguments(find_parser)
@ -78,11 +91,54 @@ def module_find(mtype, specs, args):
if len(specs) > 1:
raise MultipleMatches()
mod = module_types[mtype](specs.pop())
if not os.path.isfile(mod.file_name):
tty.die("No %s module is installed for %s" % (mtype, spec))
spec = specs.pop()
if not args.recurse_dependencies:
mod = module_types[mtype](spec)
if not os.path.isfile(mod.file_name):
tty.die("No %s module is installed for %s" % (mtype, spec))
print(mod.use_name)
print(mod.use_name)
else:
def _find_modules(spec, modules_list):
"""Finds all modules and sub-modules for a spec"""
if str(spec.version) == 'system':
# No Spack module for system-installed packages
return
if args.recurse_dependencies:
for dep in spec.dependencies.values():
_find_modules(dep, modules_list)
mod = module_types[mtype](spec)
if not os.path.isfile(mod.file_name):
tty.die("No %s module is installed for %s" % (mtype, spec))
modules_list.append((spec, mod))
# --------------------------------------
modules = set() # Modules we will load
seen = set()
# ----------- Chase down modules for it and all its dependencies
modules_dups = list()
_find_modules(spec, modules_dups)
# Remove duplicates while keeping order
modules_unique = list()
for spec, mod in modules_dups:
if mod.use_name not in seen:
modules_unique.append((spec,mod))
seen.add(mod.use_name)
# Output...
if args.shell:
module_cmd = {'tcl': 'module load', 'dotkit': 'dotkit use'}[mtype]
for spec, mod in modules_unique:
if args.shell:
print('# %s' % spec.format())
print('%s %s%s' % (module_cmd, args.prefix, mod.use_name))
else:
print(mod.use_name)
def module_refresh(name, specs, args):

View File

@ -22,9 +22,31 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import spack
import spack.stage as stage
description = "Remove all temporary build files and downloaded archives"
description = "Remove temporary build files and/or downloaded archives"
def setup_parser(subparser):
subparser.add_argument(
'-s', '--stage', action='store_true', default=True,
help="Remove all temporary build stages (default).")
subparser.add_argument(
'-c', '--cache', action='store_true', help="Remove cached downloads.")
subparser.add_argument(
'-a', '--all', action='store_true',
help="Remove all of the above.")
def purge(parser, args):
stage.purge()
# Special case: no flags.
if not any((args.stage, args.cache, args.all)):
stage.purge()
return
# handle other flags with fall through.
if args.stage or args.all:
stage.purge()
if args.cache or args.all:
spack.cache.destroy()

View File

@ -31,6 +31,7 @@
import spack
import spack.test
from spack.fetch_strategy import FetchError
description ="Run unit tests"
@ -50,6 +51,24 @@ def setup_parser(subparser):
help="verbose output")
class MockCache(object):
def store(self, copyCmd, relativeDst):
pass
def fetcher(self, targetPath, digest):
return MockCacheFetcher()
class MockCacheFetcher(object):
def set_stage(self, stage):
pass
def fetch(self):
raise FetchError("Mock cache always fails for tests")
def __str__(self):
return "[mock fetcher]"
def test(parser, args):
if args.list:
print "Available tests:"
@ -66,4 +85,5 @@ def test(parser, args):
if not os.path.exists(outputDir):
mkdirp(outputDir)
spack.cache = MockCache()
spack.test.run(args.names, outputDir, args.verbose)

View File

@ -310,7 +310,7 @@ def archive(self, destination):
if not extension(destination) == extension(self.archive_file):
raise ValueError("Cannot archive without matching extensions.")
shutil.move(self.archive_file, destination)
shutil.copy(self.archive_file, destination)
@_needs_stage
def check(self):
@ -348,7 +348,7 @@ def reset(self):
def __repr__(self):
url = self.url if self.url else "no url"
return "URLFetchStrategy<%s>" % url
return "%s<%s>" % (self.__class__.__name__, url)
def __str__(self):
if self.url:
@ -357,6 +357,24 @@ def __str__(self):
return "[no url]"
class CacheURLFetchStrategy(URLFetchStrategy):
"""The resource associated with a cache URL may be out of date."""
def __init__(self, *args, **kwargs):
super(CacheURLFetchStrategy, self).__init__(*args, **kwargs)
@_needs_stage
def fetch(self):
super(CacheURLFetchStrategy, self).fetch()
if self.digest:
try:
self.check()
except ChecksumError:
# Future fetchers will assume they don't need to download if the
# file remains
os.remove(self.archive_file)
raise
class VCSFetchStrategy(FetchStrategy):
def __init__(self, name, *rev_types, **kwargs):
@ -815,6 +833,35 @@ def for_package_version(pkg, version):
raise InvalidArgsError(pkg, version)
class FsCache(object):
def __init__(self, root):
self.root = os.path.abspath(root)
def store(self, fetcher, relativeDst):
unique = False
uidGroups = [['tag', 'commit'], ['digest'], ['revision']]
for grp in uidGroups:
try:
unique |= any(getattr(fetcher, x) for x in grp)
except AttributeError:
pass
if unique:
break
if not unique:
return
dst = join_path(self.root, relativeDst)
mkdirp(os.path.dirname(dst))
fetcher.archive(dst)
def fetcher(self, targetPath, digest):
url = "file://" + join_path(self.root, targetPath)
return CacheURLFetchStrategy(url, digest)
def destroy(self):
shutil.rmtree(self.root, ignore_errors=True)
class FetchError(spack.error.SpackError):
def __init__(self, msg, long_msg=None):

View File

@ -748,6 +748,9 @@ def do_fetch(self, mirror_only=False):
if spack.do_checksum and self.version in self.versions:
self.stage.check()
self.stage.cache_local()
def do_stage(self, mirror_only=False):
"""Unpacks the fetched tarball, then changes into the expanded tarball
directory."""

View File

@ -304,6 +304,7 @@ def fetch(self, mirror_only=False):
# Add URL strategies for all the mirrors with the digest
for url in urls:
fetchers.insert(0, fs.URLFetchStrategy(url, digest))
fetchers.insert(0, spack.cache.fetcher(self.mirror_path, digest))
for fetcher in fetchers:
try:
@ -320,6 +321,7 @@ def fetch(self, mirror_only=False):
self.fetcher = self.default_fetcher
raise fs.FetchError(errMessage, None)
def check(self):
"""Check the downloaded archive against a checksum digest.
No-op if this stage checks code out of a repository."""
@ -333,6 +335,11 @@ def check(self):
else:
self.fetcher.check()
def cache_local(self):
spack.cache.store(self.fetcher, self.mirror_path)
def expand_archive(self):
"""Changes to the stage directory and attempt to expand the downloaded
archive. Fail if the stage is not set up or if the archive is not yet
@ -436,7 +443,7 @@ def expand_archive(self):
shutil.move(source_path, destination_path)
@pattern.composite(method_list=['fetch', 'create', 'check', 'expand_archive', 'restage', 'destroy'])
@pattern.composite(method_list=['fetch', 'create', 'check', 'expand_archive', 'restage', 'destroy', 'cache_local'])
class StageComposite:
"""
Composite for Stage type objects. The first item in this composite is considered to be the root package, and
@ -511,6 +518,9 @@ def destroy(self):
# No need to destroy DIY stage.
pass
def cache_local(self):
tty.msg("Sources for DIY stages are not cached")
def _get_mirrors():
"""Get mirrors from spack configuration."""

View File

@ -0,0 +1,44 @@
##############################################################################
# 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
##############################################################################
from spack import *
class OctaveSplines(Package):
"""Additional spline functions."""
homepage = "http://octave.sourceforge.net/splines/index.html"
url = "http://downloads.sourceforge.net/octave/splines-1.3.1.tar.gz"
version('1.3.1', 'f9665d780c37aa6a6e17d1f424c49bdeedb89d1192319a4e39c08784122d18f9')
extends('octave@3.6.0:')
def install(self, spec, prefix):
octave('--quiet',
'--norc',
'--built-in-docstrings-file=/dev/null',
'--texi-macros-file=/dev/null',
'--eval', 'pkg prefix %s; pkg install %s' %
(prefix, self.stage.archive_file))

View File

@ -36,6 +36,8 @@ class Octave(Package):
homepage = "https://www.gnu.org/software/octave/"
url = "ftp://ftp.gnu.org/gnu/octave/octave-4.0.0.tar.gz"
extendable = True
version('4.0.2', 'c2a5cacc6e4c52f924739cdf22c2c687')
version('4.0.0', 'a69f8320a4f20a8480c1b278b1adb799')
@ -212,3 +214,16 @@ def install(self, spec, prefix):
make()
make("install")
# ========================================================================
# Set up environment to make install easy for Octave extensions.
# ========================================================================
def setup_dependent_package(self, module, ext_spec):
"""Called before Octave modules' install() methods.
In most cases, extensions will only need to have one line:
octave('--eval', 'pkg install %s' % self.stage.archive_file)
"""
# Octave extension builds can have a global Octave executable function
module.octave = Executable(join_path(self.spec.prefix.bin, 'octave'))

View File

@ -148,6 +148,22 @@ def install(self, spec, prefix):
make('MAKE_NP=%s' % make_jobs, parallel=False)
make("install")
# solve Poisson equation in 2D to make sure nothing is broken:
with working_dir('src/ksp/ksp/examples/tutorials'):
cc = os.environ['CC'] if '~mpi' in self.spec else self.spec['mpi'].mpicc # NOQA: ignore=E501
os.system('%s ex50.c -I%s -L%s -lpetsc -o ex50' % (
cc, prefix.include, prefix.lib))
ex50 = Executable('./ex50')
ex50('-da_grid_x', '4', '-da_grid_y', '4')
if 'superlu-dist' in spec:
ex50('-da_grid_x', '4', '-da_grid_y', '4', '-pc_type', 'lu', '-pc_factor_mat_solver_package', 'superlu_dist') # NOQA: ignore=E501
if 'mumps' in spec:
ex50('-da_grid_x', '4', '-da_grid_y', '4', '-pc_type', 'lu', '-pc_factor_mat_solver_package', 'mumps') # NOQA: ignore=E501
if 'hypre' in spec:
ex50('-da_grid_x', '4', '-da_grid_y', '4', '-pc_type', 'hypre', '-pc_hypre_type', 'boomeramg') # NOQA: ignore=E501
def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
# set up PETSC_DIR for everyone using PETSc package
spack_env.set('PETSC_DIR', self.prefix)

View File

@ -0,0 +1,43 @@
##############################################################################
# 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
##############################################################################
from spack import *
class PyDocutils(Package):
"""Docutils is an open-source text processing system for processing
plaintext documentation into useful formats, such as HTML, LaTeX,
man-pages, open-document or XML. It includes reStructuredText, the
easy to read, easy to use, what-you-see-is-what-you-get plaintext
markup language."""
homepage = "http://docutils.sourceforge.net/"
url = "https://pypi.python.org/packages/source/d/docutils/docutils-0.12.tar.gz"
version('0.12', '4622263b62c5c771c03502afa3157768')
extends('python')
def install(self, spec, prefix):
python('setup.py', 'install', '--prefix={0}'.format(prefix))

View File

@ -0,0 +1,41 @@
##############################################################################
# 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
##############################################################################
from spack import *
class PyRestview(Package):
"""A viewer for ReStructuredText documents that renders them on the fly."""
homepage = "https://mg.pov.lt/restview/"
url = "https://pypi.python.org/packages/source/r/restview/restview-2.6.1.tar.gz"
version('2.6.1', 'ac8b70e15b8f1732d1733d674813666b')
extends('python')
depends_on('py-docutils')
depends_on('py-pygments')
def install(self, spec, prefix):
python('setup.py', 'install', '--prefix={0}'.format(prefix))