blob: f5b30bd498247dec7d2bac9e6d23421569194aca [file] [log] [blame]
#!/usr/bin/python
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$
# NOTE: this file does not respect ROOT
from __future__ import print_function
import sys
try:
import portage
except ImportError:
from os import path as osp
sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
from portage import os
import re
import portage.exception
__candidatematcher__ = re.compile("^[0-9]+: \\*\\*\\* emerge ")
__noncandidatematcher__ = re.compile(" sync( |$)| clean( |$)| search( |$)|--oneshot|--fetchonly| unmerge( |$)")
def issyspkg(pkgline):
return (pkgline[0] == "*")
def iscandidate(logline):
return (__candidatematcher__.match(logline) \
and not __noncandidatematcher__.search(logline))
def getpkginfo(logline):
logline = re.sub("^[0-9]+: \\*\\*\\* emerge ", "", logline)
logline = logline.strip()
logline = re.sub("(\\S+\\.(ebuild|tbz2))|(--\\S+)|inject ", "", logline)
return logline.strip()
__uniqlist__ = []
def isunwanted(pkgline):
if pkgline in ["world", "system", "depclean", "info", "regen", ""]:
return False
elif pkgline in __uniqlist__:
return False
elif not re.search("^[a-zA-Z<>=~]", pkgline):
return False
else:
__uniqlist__.append(pkgline)
return True
world_file = os.path.join("/", portage.WORLD_FILE)
# show a little description if we have arguments
if len(sys.argv) >= 2 and sys.argv[1] in ["-h", "--help"]:
print("This script regenerates the portage world file by checking the portage")
print("logfile for all actions that you've done in the past. It ignores any")
print("arguments except --help. It is recommended that you make a backup of")
print("your existing world file (%s) before using this tool." % world_file)
sys.exit(0)
worldlist = portage.grabfile(os.path.join("/", portage.WORLD_FILE))
syslist = [x for x in portage.settings.packages if issyspkg(x)]
logfile = portage.grabfile("/var/log/emerge.log")
biglist = [getpkginfo(x) for x in logfile if iscandidate(x)]
tmplist = []
for l in biglist:
tmplist += l.split()
biglist = [x for x in tmplist if isunwanted(x)]
#for p in biglist:
# print(p)
#sys.exit(0)
# resolving virtuals
realsyslist = []
for mykey in syslist:
# drop the asterix
mykey = mykey[1:]
#print("candidate:",mykey)
mylist=portage.db["/"]["vartree"].dbapi.match(mykey)
if mylist:
mykey=portage.cpv_getkey(mylist[0])
if mykey not in realsyslist:
realsyslist.append(mykey)
for mykey in biglist:
#print("checking:",mykey)
try:
mylist=portage.db["/"]["vartree"].dbapi.match(mykey)
except (portage.exception.InvalidAtom, KeyError):
if "--debug" in sys.argv:
print("* ignoring broken log entry for %s (likely injected)" % mykey)
except ValueError as e:
print("* %s is an ambigous package name, candidates are:\n%s" % (mykey, e))
continue
if mylist:
#print "mylist:",mylist
myfavkey=portage.cpv_getkey(mylist[0])
if (myfavkey not in realsyslist) and (myfavkey not in worldlist):
print("add to world:",myfavkey)
worldlist.append(myfavkey)
portage.write_atomic(os.path.join("/", portage.WORLD_FILE),
"\n".join(sorted(worldlist)) + "\n")