You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.3 KiB
Python

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