#!/usr/bin/env python import sys import os from os import path from subprocess import Popen, PIPE from functools import cmp_to_key from datetime import datetime pym_path = path.join(path.dirname(path.realpath(__file__)), "portage", "pym") sys.path.insert(0, pym_path) from portage.versions import pkgcmp, pkgsplit from portage.dep import use_reduce, Atom from portage.exception import InvalidAtom def format_timedelta(delta): secs = delta.days*60*60*24+delta.seconds hours = secs/3600 minutes = (secs%3600)/60 return "%02d:%02d"%(hours, minutes) def estimate_remaining_time(before, count, i): now = datetime.now() delta = now-before # delta in seconds delta = delta.days*60*60*24+delta.seconds if delta == 0: return "n.a." speed = float(i)/delta remaining = (count - i)/speed remaining_hours = remaining/3600 remaining_minutes = (remaining%3600)/60 return "%02d:%02d"%(remaining_hours, remaining_minutes) portdir = "./portdir" pkgnames = list() for cat in os.listdir(portdir): catpath = os.path.join(portdir, cat) if not os.path.isdir(catpath): continue for pkg in os.listdir(catpath): pkgpath = os.path.join(catpath, pkg) if not os.path.isdir(pkgpath): continue pkgs = [pkgsplit(ver[:-7]) for ver in os.listdir(pkgpath) if ver.endswith(".ebuild")] if len(pkgs) > 0: # only grab newest package pkg, ver, rev = sorted(pkgs, key=cmp_to_key(pkgcmp), reverse=True)[0] if rev == "r0": pkgname = "%s/%s-%s"%(cat, pkg, ver) else: pkgname = "%s/%s-%s-%s"%(cat, pkg, ver, rev) pkgnames.append(pkgname) sys.stderr.write("\rGenerating list of packages... %d"%len(pkgnames)) sys.stderr.write("\rGenerating list of packages... Done.\n") count = 0 deplist = open("./out", "wb") before = datetime.now() for i, pkgname in enumerate(pkgnames): p = Popen(["./portage/bin/portageq", "metadata", "/", "ebuild", pkgname, "DEPEND"], stderr=PIPE, stdout=PIPE, env={"PORTDIR": portdir}) r = p.communicate() if p.returncode != 0: sys.stderr.write("cannot parse %s. Output: %s\n"%(pkgname, r[1])) depend = r[0] all_use = use_reduce(depend, matchall=True) no_use = use_reduce(depend, matchnone=True) # cannot use sets because of possible sublists which are not hashable l = [] for a in all_use: # FIXME: do not discard disjunctions if a not in no_use and a != "||" and not isinstance(a, list): try: l.append(Atom(a).cp) except InvalidAtom: sys.stderr.write("Invalid Atom for %s: %s\n"%(pkgname, str(a))) except TypeError: sys.stderr.write("TypeError for %s: %s\n"%(pkgname, str(a))) if len(l) > 0: deplist.write("%s %s\n"%(pkgname, " ".join(l))) count +=1 sys.stderr.write("\rFinding reduced dependencies: %d/%d, found %d. Estimated time left: %s h"%(i, len(pkgnames), count, estimate_remaining_time(before, len(pkgnames), i))) sys.stdout.flush() sys.stderr.write("\rFinding reduced dependencies: %d/%d, found %d. Estimated time left: %s h\n"%(i, len(pkgnames), count, estimate_remaining_time(before, len(pkgnames), i))) sys.stderr.write("Done. Took %s h\n"%format_timedelta(datetime.now()-before))