From 9a29aa8d032f1e5e1dd8cc2640233481f2bfd7a2 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sat, 8 Feb 2014 15:18:24 -0800 Subject: Packages can now live in directories, not just .py files. This gives us a place to put patch files. --- lib/spack/spack/package.py | 7 ++- lib/spack/spack/packages/__init__.py | 29 ++++++++- lib/spack/spack/test/__init__.py | 1 + .../test/mock_packages/directory-pkg/__init__.py | 39 ++++++++++++ lib/spack/spack/test/packages.py | 69 ++++++++++++++++++++++ lib/spack/spack/util/lang.py | 5 +- 6 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 lib/spack/spack/test/mock_packages/directory-pkg/__init__.py create mode 100644 lib/spack/spack/test/packages.py (limited to 'lib') diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index 4f79f56ec9..7fe4d77b71 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -325,8 +325,11 @@ class Package(object): # this determines how the package should be built. self.spec = spec - # Name of package is the name of its module (the file that contains it) - self.name = inspect.getmodulename(self.module.__file__) + # Name of package is the name of its module, without the + # containing module names. + self.name = self.module.__name__ + if '.' in self.name: + self.name = self.name[self.name.rindex('.') + 1:] # Make sure URL is an allowed type validate.url(self.url) diff --git a/lib/spack/spack/packages/__init__.py b/lib/spack/spack/packages/__init__.py index 471b48d902..d9791ed1bc 100644 --- a/lib/spack/spack/packages/__init__.py +++ b/lib/spack/spack/packages/__init__.py @@ -210,9 +210,32 @@ def validate_package_name(pkg_name): def filename_for_package_name(pkg_name): - """Get the filename where a package name should be stored.""" + """Get the filename for the module we should load for a particular package. + The package can be either in a standalone .py file, or it can be in + a directory with an __init__.py file. + + Package "foo" in standalone .py file: + packages/foo.py + + Package "foo" in directory: + packages/foo/__init__.py + + The second form is used when there are files (like patches) that need + to be stored along with the package. + + If the package doesn't exist yet, this will just return the name + of the standalone .py file. + """ validate_package_name(pkg_name) - return new_path(spack.packages_path, "%s.py" % pkg_name) + + pkg_dir = new_path(spack.packages_path, pkg_name) + + if os.path.isdir(pkg_dir): + init_file = new_path(pkg_dir, '__init__.py') + return init_file + else: + pkg_file = "%s.py" % pkg_dir + return pkg_file def installed_package_specs(): @@ -249,7 +272,7 @@ def class_name_for_package_name(pkg_name): def exists(pkg_name): - """Whether a package is concrete.""" + """Whether a package with the supplied name exists .""" return os.path.exists(filename_for_package_name(pkg_name)) diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py index 8f4015529e..bf8dd6ea96 100644 --- a/lib/spack/spack/test/__init__.py +++ b/lib/spack/spack/test/__init__.py @@ -32,6 +32,7 @@ import spack.tty as tty """Names of tests to be included in Spack's test suite""" test_names = ['versions', 'url_parse', + 'packages', 'stage', 'spec_syntax', 'spec_semantics', diff --git a/lib/spack/spack/test/mock_packages/directory-pkg/__init__.py b/lib/spack/spack/test/mock_packages/directory-pkg/__init__.py new file mode 100644 index 0000000000..aa53bb1f36 --- /dev/null +++ b/lib/spack/spack/test/mock_packages/directory-pkg/__init__.py @@ -0,0 +1,39 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://scalability-llnl.github.io/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +from spack import * + +class DirectoryPkg(Package): + """This is a fake package that tests spack's ability to load packages in + directories with __init__.py files. + """ + homepage = "http://www.example.com" + url = "http://www.example.com/directory-pkg-1.0.tar.gz" + + versions = { '1.0' : '0123456789abcdef0123456789abcdef' } + + this_is_a_directory_pkg = True + + def install(self): + pass diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py new file mode 100644 index 0000000000..9541c54c13 --- /dev/null +++ b/lib/spack/spack/test/packages.py @@ -0,0 +1,69 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://scalability-llnl.github.io/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## +import unittest + +from spack.test.mock_packages_test import * +import spack.packages as packages + +class PackagesTest(MockPackagesTest): + + def test_load_regular_package(self): + pkg = packages.get('mpich') + + + def test_regular_package_name(self): + pkg = packages.get('mpich') + self.assertEqual(pkg.name, 'mpich') + + + def test_regular_package_filename(self): + filename = packages.filename_for_package_name('mpich') + self.assertEqual(filename, new_path(mock_packages_path, 'mpich.py')) + + + def test_regular_package_name(self): + pkg = packages.get('mpich') + self.assertEqual(pkg.name, 'mpich') + + + def test_load_directory_package(self): + pkg = packages.get('directory-pkg') + self.assertTrue(hasattr(pkg, 'this_is_a_directory_pkg')) + self.assertTrue(pkg.this_is_a_directory_pkg) + + + def test_directory_package_name(self): + pkg = packages.get('directory-pkg') + self.assertEqual(pkg.name, 'directory-pkg') + + + def test_directory_package_filename(self): + filename = packages.filename_for_package_name('directory-pkg') + self.assertEqual(filename, new_path(mock_packages_path, 'directory-pkg/__init__.py')) + + + def test_nonexisting_package_filename(self): + filename = packages.filename_for_package_name('some-nonexisting-package') + self.assertEqual(filename, new_path(mock_packages_path, 'some-nonexisting-package.py')) diff --git a/lib/spack/spack/util/lang.py b/lib/spack/spack/util/lang.py index ba774325c8..b77182ba7f 100644 --- a/lib/spack/spack/util/lang.py +++ b/lib/spack/spack/util/lang.py @@ -105,8 +105,9 @@ def memoized(obj): def list_modules(directory, **kwargs): - """Lists all of the modules, excluding __init__.py, in - a particular directory.""" + """Lists all of the modules, excluding __init__.py, in a + particular directory. Listed packages have no particular + order.""" list_directories = kwargs.setdefault('directories', True) for name in os.listdir(directory): -- cgit v1.2.3-70-g09d2