Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 83 lines (64 sloc) 3.17 KB
#!/usr/bin/env python
import os.path
import subprocess
import sys
import re
if len(sys.argv) <= 1:
print "Usage: `basename %s` [--clean] package[-version] ... [-- configure-arg ...]" % sys.argv[0]
sys.exit(1)
args = sys.argv[1:]
args, clean = (args[0] == "--clean") and (args[1:], True) or (args, False)
packageargs, configureargs = ("--" in args) and (args[:args.index("--")], args[args.index("--") + 1:]) or (args, [])
def takelastwhile(xs, p):
ys = []
for x in reversed(xs):
if p(x):
ys.append(x)
else:
break
return list(reversed(ys))
def splitlast(xs, p):
tail = takelastwhile(xs, p)
return (xs[:len(xs) - len(tail)], tail)
def parsepackage(package):
(name, mb_version) = splitlast(package, lambda c: c in ['.'] + [str(i) for i in range(0, 10)])
if name[-1] == "-" and mb_version:
return (name[:-1], "".join(mb_version))
else:
return (package, None)
packages = map(parsepackage, packageargs)
for name, mb_version in packages:
# Abuse Hackage index page to discover most recent version. Remember:
# -e /pattern/!d == delete lines not matching this pattern
# -e 's,foo,bar,g' == substitute foo for bar globally. \1 is the first capture from foo
# -e '/latest/d' == delete lines matching latest
if mb_version:
version = mb_version
else:
html = subprocess.Popen(["wget", "http://hackage.haskell.org/packages/archive/%s/" % name, "-O", "-"], stdout=subprocess.PIPE).communicate()[0]
versions = re.findall(r'\<img\ src\=\"\/icons\/folder\.gif\"\ alt\=\"\[DIR\]\"\>\<\/td\>\<td\>\<a\ href\=\"([^"]+)\/\"\>', html)
versions = sorted(filter(lambda v: v != "latest", versions))
version = versions[-1]
downloads_dir = os.path.expanduser("~/Downloads")
target_dir = os.path.join(downloads_dir, name + "-" + version)
# Create if not present
if not os.path.exists(target_dir):
archive_file = os.path.join(downloads_dir, name + "-" + version + ".tar.gz")
# Download if not present
if not os.path.exists(archive_file):
subprocess.check_call(["wget", "http://hackage.haskell.org/packages/archive/%(name)s/%(version)s/%(name)s-%(version)s.tar.gz" % { "name" : name, "version" : version }, "-O", archive_file])
# Extract
subprocess.check_call(["tar", "-xzf", archive_file], cwd=downloads_dir)
setup_file = os.path.exists(os.path.join(target_dir, "Setup.hs")) and "Setup.hs" or "Setup.lhs"
# Build the Setup program. Strictly speaking we could use runghc, but this is slightly more reliable
# because I've observed problems where a GHC extra library won't be present
build_setup = True
if build_setup:
subprocess.check_call(["ghc", "--make", setup_file, "-o", "setup"], cwd=target_dir)
# Actually build the package
cabal = lambda command, sudo=False: subprocess.check_call((sudo and ["sudo"] or []) + (build_setup and ["./setup"] or ["runghc", setup_file]) + command, cwd=target_dir)
if clean:
cabal(["clean"])
cabal(["configure"] + configureargs)
cabal(["build"])
cabal(["install"], sudo=("--user" not in configureargs))