#!/usr/bin/env python
"""
Attempt to automatically generate a port for a CPAN module.
"""
import sys, urllib, re, yaml, os, glob, garstowlib
def die(*s):
print >>sys.stderr, "".join(map(str, s))
sys.exit(1)
def makeport(package):
print "Fetching CPAN info for " + package + "...",
sys.stdout.flush()
url = "http://search.cpan.org/dist/" + package
f = urllib.urlopen(url)
page = f.read()
f.close()
# href="/CPAN/authors/id/M/MS/MSCHILLI/Log-Log4perl-1.05.tar.gz">Download<
m = re.search(r'href="[^"]*/([^"/]*)/([^"/]*)">Download<', page)
if m is None:
die("cannot find Download link in page for ", package)
(author, distfile) = m.group(1, 2)
m = re.match(r'^(.*)-([0-9._]+)\.tar\.gz$', distfile)
if m is None:
die("cannot parse distfile name for ", package, ": ", distfile)
(n, version) = m.group(1, 2)
if n != package:
print "changing package name from " + package + " to " + n
package = n
i = page.find("
Modules
")
if i == -1:
die("cannot find Modules heading in ", package)
d = page[i:]
i = d.find(">" + package.replace("-", "::") + "<")
if i != -1:
d = d[i:]
m = re.search(r'([^<]+) ', d)
if m is None:
print "cannot find description for " + package
description = "Perl module " + package
else:
description = m.group(1)
print package, author, version
# href="/src/MSCHILLI/Log-Log4perl-1.05/META.yml">META.yml
m = re.search(r'href="([^"]*)">META.yml<', page)
deps = {}
deps["perl/perl"] = True
if m is not None:
print "Fetching META.yml...",
sys.stdout.flush()
f = urllib.urlopen(urllib.basejoin(url, m.group(1)))
meta = yaml.load(f.read())
f.close()
print meta
stowdir = garstowlib.get_stow_dir()
reqs = meta["requires"]
if reqs is None:
reqs = {}
for dep in reqs.keys():
if dep == "perl":
continue
fn = dep.replace("::", "/") + ".pm"
installed = []
for path in ("lib/perl5/*", "lib/perl5/*/*", "lib/perl5/site_perl/*/*"):
installed += glob.glob(stowdir + "/" + path + "/" + fn)
if installed == []:
deps["perl/p5-" + dep.replace("::", "-")] = True
print "Needs new package " + dep
else:
op = garstowlib.get_owning_package(installed[0])
pn = garstowlib.get_full_package_name(op)
deps[pn] = True
print "Needs existing package " + pn
garname = "p5-" + package
try:
os.stat(garname)
except OSError:
os.mkdir(garname)
makefile = "../cpan.mk"
port = """GARNAME = %s
GARVERSION = %s
CPAN_AUTHOR = %s
LIBDEPS = %s
DESCRIPTION = %s
include %s
""" % (garname, version, author, " ".join(deps.keys()), description.strip(), makefile)
f = open(garname + "/Makefile", "w")
f.write(port)
f.close()
if __name__ == "__main__":
for package in sys.argv[1:]:
makeport(package)