Better python template for 'spack create'

This commit is contained in:
Todd Gamblin 2015-07-02 00:39:33 -07:00
parent edfcac32c3
commit b3e34be972
3 changed files with 127 additions and 18 deletions

View File

@ -103,21 +103,35 @@ def __call__(self, stage):
"""Try to guess the type of build system used by the project, and return """Try to guess the type of build system used by the project, and return
an appropriate configure line. an appropriate configure line.
""" """
autotools = "configure('--prefix=%s' % prefix)"
cmake = "cmake('.', *std_cmake_args)"
python = "python('setup.py', 'install', '--prefix=%s' % prefix)"
config_lines = ((r'/configure$', 'autotools', autotools),
(r'/CMakeLists.txt$', 'cmake', cmake),
(r'/setup.py$', 'python', python))
# Peek inside the tarball.
tar = which('tar') tar = which('tar')
output = tar( output = tar(
"--exclude=*/*/*", "-tf", stage.archive_file, return_output=True) "--exclude=*/*/*", "-tf", stage.archive_file, return_output=True)
lines = output.split("\n")
autotools = 'configure("--prefix=%s" % prefix)' # Set the configure line to the one that matched.
cmake = 'cmake(".", *std_cmake_args)' for pattern, bs, cl in config_lines:
lines = output.split('\n') if any(re.search(pattern, l) for l in lines):
config_line = cl
if any(re.search(r'/configure$', l) for l in lines): build_system = bs
self.configure = autotools break
elif any(re.search(r'/CMakeLists.txt$', l) for l in lines):
self.configure = cmake
else: else:
# Both, with cmake commented out # None matched -- just put both, with cmake commented out
self.configure = '%s\n # %s' % (autotools, cmake) config_line = "# FIXME: Spack couldn't guess one, so here are some options:\n"
config_line += " # " + autotools + "\n"
config_line += " # " + cmake
build_system = 'unknown'
self.configure = config_line
self.build_system = build_system
def make_version_calls(ver_hash_tuples): def make_version_calls(ver_hash_tuples):
@ -152,13 +166,6 @@ def create(parser, args):
tty.msg("This looks like a URL for %s version %s." % (name, version)) tty.msg("This looks like a URL for %s version %s." % (name, version))
tty.msg("Creating template for package %s" % name) tty.msg("Creating template for package %s" % name)
# Create a directory for the new package.
pkg_path = spack.db.filename_for_package_name(name)
if os.path.exists(pkg_path) and not args.force:
tty.die("%s already exists." % pkg_path)
else:
mkdirp(os.path.dirname(pkg_path))
versions = spack.package.find_versions_of_archive(url) versions = spack.package.find_versions_of_archive(url)
rkeys = sorted(versions.keys(), reverse=True) rkeys = sorted(versions.keys(), reverse=True)
versions = OrderedDict(zip(rkeys, (versions[v] for v in rkeys))) versions = OrderedDict(zip(rkeys, (versions[v] for v in rkeys)))
@ -190,6 +197,17 @@ def create(parser, args):
if not ver_hash_tuples: if not ver_hash_tuples:
tty.die("Could not fetch any tarballs for %s." % name) tty.die("Could not fetch any tarballs for %s." % name)
# Prepend 'py-' to python package names, by convention.
if guesser.build_system == 'python':
name = 'py-%s' % name
# Create a directory for the new package.
pkg_path = spack.db.filename_for_package_name(name)
if os.path.exists(pkg_path) and not args.force:
tty.die("%s already exists." % pkg_path)
else:
mkdirp(os.path.dirname(pkg_path))
# Write out a template for the file # Write out a template for the file
with open(pkg_path, "w") as pkg_file: with open(pkg_path, "w") as pkg_file:
pkg_file.write( pkg_file.write(

View File

@ -55,7 +55,8 @@
'link_tree', 'link_tree',
'spec_yaml', 'spec_yaml',
'optional_deps', 'optional_deps',
'make_executable'] 'make_executable',
'configure_guess']
def list_tests(): def list_tests():

View File

@ -0,0 +1,90 @@
##############################################################################
# Copyright (c) 2013-2015, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://scalability-llnl.github.io/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License (as published by
# the Free Software Foundation) version 2.1 dated February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import os
import unittest
import shutil
import tempfile
from llnl.util.filesystem import *
from spack.cmd.create import ConfigureGuesser
from spack.stage import Stage
from spack.fetch_strategy import URLFetchStrategy
from spack.directory_layout import YamlDirectoryLayout
from spack.util.executable import which
from spack.test.mock_packages_test import *
from spack.test.mock_repo import MockArchive
class InstallTest(unittest.TestCase):
"""Tests the configure guesser in spack create"""
def setUp(self):
self.tar = which('tar')
self.tmpdir = tempfile.mkdtemp()
self.orig_dir = os.getcwd()
os.chdir(self.tmpdir)
self.stage = None
def tearDown(self):
shutil.rmtree(self.tmpdir, ignore_errors=True)
if self.stage:
self.stage.destroy()
os.chdir(self.orig_dir)
def check_archive(self, filename, system):
mkdirp('archive')
touch(join_path('archive', filename))
self.tar('czf', 'archive.tar.gz', 'archive')
url = 'file://' + join_path(os.getcwd(), 'archive.tar.gz')
print url
self.stage = Stage(url)
self.stage.fetch()
guesser = ConfigureGuesser()
guesser(self.stage)
self.assertEqual(system, guesser.build_system)
def test_python(self):
self.check_archive('setup.py', 'python')
def test_autotools(self):
self.check_archive('configure', 'autotools')
def test_cmake(self):
self.check_archive('CMakeLists.txt', 'cmake')
def test_unknown(self):
self.check_archive('foobar', 'unknown')