Spack create works again w/new package format.

This commit is contained in:
Todd Gamblin 2013-12-23 12:09:19 -08:00
parent 358bfdaaf1
commit 7267734a5b
5 changed files with 75 additions and 10 deletions

View file

@ -1,28 +1,50 @@
import string import string
import os import os
import hashlib
import re
import spack import spack
import spack.packages as packages import spack.packages as packages
import spack.tty as tty import spack.tty as tty
import spack.url import spack.url
import spack.util.crypto as crypto
from spack.util.executable import which
from spack.stage import Stage from spack.stage import Stage
from contextlib import closing from contextlib import closing
description = "Create a new package file from an archive URL" description = "Create a new package file from an archive URL"
package_template = string.Template("""\ package_template = string.Template("""\
# FIXME:
# This is a template package file for Spack. We've conveniently
# put giant "FIXME" labels next to all the things you'll probably
# want to change.
#
# Once you've edited all the FIXME's, delete this whole message,
# save this file, and test out your package like this:
#
# spack install ${name}
#
# You can always get back here with 'spack edit ${name}'. See
# the spack documentation for more information on building
# packages.
#
from spack import * from spack import *
class ${class_name}(Package): class ${class_name}(Package):
""\"FIXME: put a proper description of your package here.""\"
# FIXME: add a proper url for your package's homepage here.
homepage = "http://www.example.com" homepage = "http://www.example.com"
url = "${url}" url = "${url}"
md5 = "${md5}"
versions = ${versions}
def install(self, prefix): def install(self, prefix):
# Insert the configure line for your build system here. # FIXME: Modify the configure line to suit your build system here.
configure("--prefix=%s" % prefix) ${configure}
# cmake(".", *std_cmake_args)
# FIXME:
make() make()
make("install") make("install")
""") """)
@ -34,6 +56,26 @@ def setup_parser(subparser):
help="Remove existing package file.") help="Remove existing package file.")
def guess_configure(archive_file):
"""Try to guess the type of build system used by the project, and return
an appropriate configure line.
"""
tar = which('tar')
output = tar("--exclude=*/*/*", "-tf", archive_file, return_output=True)
autotools = 'configure("--prefix=%s" % prefix)'
cmake = 'cmake(".", *std_cmake_args)'
lines = output.split('\n')
if any(re.search(r'/configure$', l) for l in lines):
return autotools
elif any(re.search(r'/CMakeLists.txt$', l) for l in lines):
return cmake
else:
# Both, with cmake commented out
return '%s\n # %s' % (autotools, cmake)
def create(parser, args): def create(parser, args):
url = args.url url = args.url
@ -51,7 +93,7 @@ def create(parser, args):
if not version: if not version:
tty.die("Couldn't guess a version string from %s." % url) tty.die("Couldn't guess a version string from %s." % url)
path = packages.filename_for(name) path = packages.filename_for_package_name(name)
if not args.force and os.path.exists(path): if not args.force and os.path.exists(path):
tty.die("%s already exists." % path) tty.die("%s already exists." % path)
@ -62,17 +104,21 @@ def create(parser, args):
except spack.FailedDownloadException, e: except spack.FailedDownloadException, e:
tty.die(e.message) tty.die(e.message)
md5 = spack.md5(archive_file) md5 = crypto.checksum(hashlib.md5, archive_file)
versions = '{ "%s" : "%s" }' % (version, md5)
class_name = packages.class_name_for_package_name(name) class_name = packages.class_name_for_package_name(name)
configure = guess_configure(archive_file)
# Write outa template for the file # Write out a template for the file
tty.msg("Editing %s." % path) tty.msg("Editing %s." % path)
with closing(open(path, "w")) as pkg_file: with closing(open(path, "w")) as pkg_file:
pkg_file.write( pkg_file.write(
package_template.substitute( package_template.substitute(
name=name,
configure=configure,
class_name=class_name, class_name=class_name,
url=url, url=url,
md5=md5)) versions=versions))
# If everything checks out, go ahead and edit. # If everything checks out, go ahead and edit.
spack.editor(path) spack.editor(path)

View file

@ -17,6 +17,14 @@ def info(parser, args):
print "Homepage: ", package.homepage print "Homepage: ", package.homepage
print "Download: ", package.url print "Download: ", package.url
print
print "Safe versions: "
if package.versions:
colify(reversed(sorted(package.versions)), indent=4)
else:
print "None. Use spack versions %s to get a list of downloadable versions." % package.name
print print
print "Dependencies:" print "Dependencies:"
if package.dependencies: if package.dependencies:

View file

@ -9,6 +9,10 @@
ALLOWED_ARCHIVE_TYPES = [".".join(l) for l in product(PRE_EXTS, EXTS)] + EXTS ALLOWED_ARCHIVE_TYPES = [".".join(l) for l in product(PRE_EXTS, EXTS)] + EXTS
def allowed_archive(path):
return any(path.endswith(t) for t in ALLOWED_ARCHIVE_TYPES)
def decompressor_for(path): def decompressor_for(path):
"""Get the appropriate decompressor for a path.""" """Get the appropriate decompressor for a path."""
tar = which('tar', required=True) tar = which('tar', required=True)

View file

@ -9,9 +9,16 @@ class Executable(object):
def __init__(self, name): def __init__(self, name):
self.exe = name.split(' ') self.exe = name.split(' ')
def add_default_arg(self, arg): def add_default_arg(self, arg):
self.exe.append(arg) self.exe.append(arg)
@property
def command(self):
return self.exe[0]
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
"""Run the executable with subprocess.check_output, return output.""" """Run the executable with subprocess.check_output, return output."""
return_output = kwargs.get("return_output", False) return_output = kwargs.get("return_output", False)

View file

@ -1,7 +1,7 @@
import tty import tty
from urlparse import urlparse from urlparse import urlparse
from spack.util.compression import ALLOWED_ARCHIVE_TYPES from spack.util.compression import allowed_archive
ALLOWED_SCHEMES = ["http", "https", "ftp"] ALLOWED_SCHEMES = ["http", "https", "ftp"]
@ -10,5 +10,5 @@ def url(url_string):
if url.scheme not in ALLOWED_SCHEMES: if url.scheme not in ALLOWED_SCHEMES:
tty.die("Invalid protocol in URL: '%s'" % url_string) tty.die("Invalid protocol in URL: '%s'" % url_string)
if not any(url_string.endswith(t) for t in ALLOWED_ARCHIVE_TYPES): if not allowed_archive(url_string):
tty.die("Invalid file type in URL: '%s'" % url_string) tty.die("Invalid file type in URL: '%s'" % url_string)