#!/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)