#!/usr/bin/env python
import os, sys
from subprocess import Popen, PIPE, check_call, CalledProcessError
def tar_file(dir, no_compress=False):
"""
Create tar file from ``dir``. If ``no_compress`` is True, don't
compress; otherwise, compress using bzip2.
If on a Mac, set the environment variable ``COPYFILE_DISABLE`` to
True and use the subprocess module to call tar (to use the new
environment variable). Otherwise, use the tarfile module to
create the tar file.
"""
if sys.platform == 'darwin':
# workaround OS X issue -- see trac #2522
COPYFILE_DISABLE = True
os.environ['COPYFILE_DISABLE'] = 'true'
if no_compress:
cmd = "tar -cf %s.spkg %s" % (dir, dir)
else:
cmd = "tar -cf - %s | bzip2 > %s.spkg" % (dir, dir)
try:
check_call(cmd, shell=True)
except CalledProcessError:
print "Package creation failed."
sys.exit(1)
else:
import tarfile
if no_compress:
mode = "w"
else:
mode = "w:bz2"
try:
tar = tarfile.open("%s.spkg" % dir, mode=mode)
tar.add(dir, exclude=lambda f: f == ".DS_Store")
tar.close()
except tarfile.TarError:
print "Package creation failed."
sys.exit(1)
def main():
import re
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-n", "--no-compress", "--no_compress", "--nocompress",
dest="no_compress", action="store_true",
help="don't compress the spkg file")
(options, args) = parser.parse_args()
for path in args:
print "Creating {1}Sage package from {0}".format(path,
"uncompressed " if options.no_compress else "")
if not os.path.isdir(path):
print "No directory %s" % path
sys.exit(1)
dir = os.path.basename(path.rstrip("/"))
file = dir + ".spkg"
s = dir.split("-", 1)
try:
name = s[0]
version = s[1]
except IndexError:
name = dir
version = ""
if len(version) == 0:
print "Warning: no version number detected"
else:
m = re.match(r"[0-9]+[-.0-9a-zA-Z]*(\.p[0-9]+)?$", version)
if not m:
print "Warning: version number (%s) not of the expected form." % version
print """The version number should start with a number and contain only numbers,
letters, periods, and hyphens. It may optionally end with a string of
the form 'pNUM' where NUM is a non-negative integer.
Proceeding anyway..."""
tar_file(dir, no_compress = options.no_compress)
size = os.path.getsize(file)
if size < 1024 * 1024:
size = "%sK" % (size / 1024)
else:
size = "%0.1fM" % (size / (1024 * 1024.0))
if os.path.exists(os.path.join(dir, "SPKG.txt")):
spkg_txt = "Good"
else:
spkg_txt = "File is missing"
p = Popen("cd '%s' && hg diff" % dir, shell=True, stdout=PIPE, stderr=PIPE)
std_out, std_err = p.communicate()
if len(std_err) != 0:
hgrepo_txt = "Error reading repository"
elif len(std_out) != 0:
hgrepo_txt = "Unchecked in changes"
else:
hgrepo_txt = "Good"
print """
Created package %(file)s.
NAME: %(name)s
VERSION: %(version)s
SIZE: %(size)s
HG REPO: %(hgrepo)s
SPKG.txt: %(spkg)s
Please test this package using
sage -f %(file)s
immediately.""" % {'file': file, 'name': name, 'version': version, 'size': size,
'hgrepo': hgrepo_txt, 'spkg': spkg_txt},
if options.no_compress:
print ""
print ""
else:
print """ Also, note that you can use
sage -pkg_nc %(dir)s
to make an uncompressed version of the package (useful if the
package is full of compressed data).
""" % {'dir': dir}
if __name__ == "__main__":
main()