#!/usr/bin/python # Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # 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")