aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'integration_with_portage.patch')
-rw-r--r--integration_with_portage.patch441
1 files changed, 263 insertions, 178 deletions
diff --git a/integration_with_portage.patch b/integration_with_portage.patch
index a74beed..ff8f487 100644
--- a/integration_with_portage.patch
+++ b/integration_with_portage.patch
@@ -1,17 +1,16 @@
-diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
-index 0144cfc..1c423a3 100644
---- a/pym/_emerge/EbuildBuild.py
-+++ b/pym/_emerge/EbuildBuild.py
-@@ -9,6 +9,8 @@ from _emerge.CompositeTask import CompositeTask
+diff -urN /usr/lib/portage/pym/_emerge/EbuildBuild.py ./pym/_emerge/EbuildBuild.py
+--- /usr/lib/portage/pym/_emerge/EbuildBuild.py 2014-01-23 14:09:03.647948532 +0600
++++ ./pym/_emerge/EbuildBuild.py 2014-02-17 17:25:59.335376529 +0600
+@@ -9,6 +9,8 @@
from _emerge.EbuildMerge import EbuildMerge
from _emerge.EbuildFetchonly import EbuildFetchonly
from _emerge.EbuildBuildDir import EbuildBuildDir
+from _emerge.EventsAnalyser import EventsAnalyser, FilterProcGenerator
+from _emerge.EventsLogger import EventsLogger
from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
- from portage.util import writemsg
- import portage
-@@ -21,7 +23,7 @@ from portage.package.ebuild._spawn_nofetch import spawn_nofetch
+ from _emerge.TaskSequence import TaskSequence
+
+@@ -24,7 +26,7 @@
class EbuildBuild(CompositeTask):
__slots__ = ("args_set", "config_pool", "find_blockers",
@@ -20,7 +19,7 @@ index 0144cfc..1c423a3 100644
"prefetcher", "settings", "world_atom") + \
("_build_dir", "_buildpkg", "_ebuild_path", "_issyspkg", "_tree")
-@@ -244,8 +246,54 @@ class EbuildBuild(CompositeTask):
+@@ -259,8 +261,52 @@
build = EbuildExecuter(background=self.background, pkg=pkg,
scheduler=scheduler, settings=settings)
@@ -35,7 +34,7 @@ index 0144cfc..1c423a3 100644
+ "depcheckstrict" in self.settings["FEATURES"]:
+ # Lets start a log listening server
+ temp_path=self.settings.get("T",self.settings["PORTAGE_TMPDIR"])
-+
++
+ if "depcheckstrict" not in self.settings["FEATURES"]:
+ # use default filter_proc
+ self.logserver=EventsLogger(socket_dir=temp_path)
@@ -44,11 +43,11 @@ index 0144cfc..1c423a3 100644
+ "This may take some time\n")
+ filter_gen=FilterProcGenerator(self.pkg.cpv, self.settings)
+ filter_proc=filter_gen.get_filter_proc()
-+ self.logserver=EventsLogger(socket_dir=temp_path,
++ self.logserver=EventsLogger(socket_dir=temp_path,
+ filter_proc=filter_proc)
-+
++
+ self.logserver.start()
-+
++
+ # Copy socket path to LOG_SOCKET environment variable
+ env=self.settings.configdict["pkg"]
+ env['LOG_SOCKET'] = self.logserver.socket_name
@@ -62,39 +61,34 @@ index 0144cfc..1c423a3 100644
+ env=self.settings.configdict["pkg"]
+ if 'LOG_SOCKET' in env:
+ del env['LOG_SOCKET']
-+
++
+ events=self.logserver.stop()
+ self.logserver=None
+ analyser=EventsAnalyser(self.pkg.cpv, events, self.settings)
+ analyser.display() # show the analyse
+
+ #import pdb; pdb.set_trace()
-+
-+
+
def _fetch_failed(self):
# We only call the pkg_nofetch phase if either RESTRICT=fetch
# is set or the package has explicitly overridden the default
-diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
-index f53570a..82c165d 100644
---- a/pym/_emerge/EbuildPhase.py
-+++ b/pym/_emerge/EbuildPhase.py
-@@ -33,7 +33,8 @@ class EbuildPhase(CompositeTask):
- ("_ebuild_lock",)
+diff -urN /usr/lib/portage/pym/_emerge/EbuildPhase.py ./pym/_emerge/EbuildPhase.py
+--- /usr/lib/portage/pym/_emerge/EbuildPhase.py 2014-01-23 14:09:03.648948532 +0600
++++ ./pym/_emerge/EbuildPhase.py 2014-02-17 17:27:57.509371559 +0600
+@@ -44,7 +44,8 @@
# FEATURES displayed prior to setup phase
-- _features_display = ("ccache", "distcc", "distcc-pump", "fakeroot",
-+ _features_display = ("ccache", "depcheck", "depcheckstrict" "distcc",
-+ "distcc-pump", "fakeroot",
+ _features_display = (
+- "ccache", "compressdebug", "distcc", "distcc-pump", "fakeroot",
++ "ccache", "compressdebug", "depcheck", "depcheckstrict",
++ "distcc", "distcc-pump", "fakeroot",
"installsources", "keeptemp", "keepwork", "nostrip",
"preserve-libs", "sandbox", "selinux", "sesandbox",
"splitdebug", "suidctl", "test", "userpriv",
-diff --git a/pym/_emerge/EventsAnalyser.py b/pym/_emerge/EventsAnalyser.py
-new file mode 100644
-index 0000000..65ece7b
---- /dev/null
-+++ b/pym/_emerge/EventsAnalyser.py
-@@ -0,0 +1,511 @@
+diff -urN /usr/lib/portage/pym/_emerge/EventsAnalyser.py ./pym/_emerge/EventsAnalyser.py
+--- /usr/lib/portage/pym/_emerge/EventsAnalyser.py 1970-01-01 05:00:00.000000000 +0500
++++ ./pym/_emerge/EventsAnalyser.py 2014-02-17 17:34:27.954355139 +0600
+@@ -0,0 +1,514 @@
+# Distributed under the terms of the GNU General Public License v2
+
+import portage
@@ -131,36 +125,36 @@ index 0000000..65ece7b
+ def get_dep(self,pkg,dep_type=["RDEPEND","DEPEND"]):
+ """
+ Gets current dependencies of a package. Looks in portage db
-+
++
+ :param pkg: name of package
-+ :param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or
++ :param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or
+ ["RDEPEND", "DEPEND"]
+ :returns: **set** of packages names
+ """
+ ret=set()
-+
-+ pkg = self.get_best_visible_pkg(pkg)
++
++ pkg = self.get_best_visible_pkg(pkg)
+ if not pkg:
+ return ret
-+
++
+ # we found the best visible match in common tree
+
+
-+ metadata = dict(zip(self.metadata_keys,
++ metadata = dict(zip(self.metadata_keys,
+ self.portdbapi.aux_get(pkg, self.metadata_keys)))
+ dep_str = " ".join(metadata[k] for k in dep_type)
+
+ # the IUSE default are very important for us
+ iuse_defaults=[
+ u[1:] for u in metadata.get("IUSE",'').split() if u.startswith("+")]
-+
++
+ use=self.use.split()
-+
++
+ for u in iuse_defaults:
+ if u not in use:
+ use.append(u)
+
-+ success, atoms = portage.dep_check(dep_str, None, self.settings,
++ success, atoms = portage.dep_check(dep_str, None, self.settings,
+ myuse=use, myroot=self.settings["ROOT"],
+ trees={self.settings["ROOT"]:{"vartree":self.vartree, "porttree": self.vartree}})
+ if not success:
@@ -171,7 +165,7 @@ index 0000000..65ece7b
+
+ if not atomname:
+ continue
-+
++
+ for unvirt_pkg in expand_new_virt(self.vardbapi,'='+atomname):
+ for pkg in self.vartree.dep_match(unvirt_pkg):
+ ret.add(pkg)
@@ -180,12 +174,12 @@ index 0000000..65ece7b
+
+ # recursive dependency getter
+ def get_deps(self,pkg,dep_type=["RDEPEND","DEPEND"]):
-+ """
-+ Gets current dependencies of a package on any depth
++ """
++ Gets current dependencies of a package on any depth
+ All dependencies **must** be installed
-+
++
+ :param pkg: name of package
-+ :param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or
++ :param dep_type: type of dependencies to recurse. Can be ["DEPEND"] or
+ ["RDEPEND", "DEPEND"]
+ :returns: **set** of packages names
+ """
@@ -194,14 +188,14 @@ index 0000000..65ece7b
+
+ # get porttree dependencies on the first package
+
-+ pkg = self.portdbapi.xmatch("bestmatch-visible", pkg)
++ pkg = self.portdbapi.xmatch("bestmatch-visible", pkg)
+ if not pkg:
+ return ret
+
+ known_packages=set()
+ unknown_packages=self.get_dep(pkg,dep_type)
+ ret=ret.union(unknown_packages)
-+
++
+ while unknown_packages:
+ p=unknown_packages.pop()
+ if p in known_packages:
@@ -211,18 +205,18 @@ index 0000000..65ece7b
+ metadata = dict(zip(self.metadata_keys, self.vardbapi.aux_get(p, self.metadata_keys)))
+
+ dep_str = " ".join(metadata[k] for k in dep_type)
-+
++
+ # the IUSE default are very important for us
+ iuse_defaults=[
+ u[1:] for u in metadata.get("IUSE",'').split() if u.startswith("+")]
-+
++
+ use=self.use.split()
-+
++
+ for u in iuse_defaults:
+ if u not in use:
+ use.append(u)
-+
-+ success, atoms = portage.dep_check(dep_str, None, self.settings,
++
++ success, atoms = portage.dep_check(dep_str, None, self.settings,
+ myuse=use, myroot=self.settings["ROOT"],
+ trees={self.settings["ROOT"]:{"vartree":self.vartree,"porttree": self.vartree}})
+
@@ -233,7 +227,7 @@ index 0000000..65ece7b
+ atomname = self.vartree.dep_bestmatch(atom)
+ if not atomname:
+ continue
-+
++
+ for unvirt_pkg in expand_new_virt(self.vardbapi,'='+atomname):
+ for pkg in self.vartree.dep_match(unvirt_pkg):
+ ret.add(pkg)
@@ -241,8 +235,8 @@ index 0000000..65ece7b
+ return ret
+
+ def get_deps_for_package_building(self, pkg):
-+ """
-+ returns buildtime dependencies of current package and
++ """
++ returns buildtime dependencies of current package and
+ all runtime dependencies of that buildtime dependencies
+ """
+ buildtime_deps=self.get_dep(pkg, ["DEPEND"])
@@ -254,9 +248,9 @@ index 0000000..65ece7b
+ return ret
+
+ def get_system_packages_list(self):
-+ """
++ """
+ returns all packages from system set. They are always implicit dependencies
-+
++
+ :returns: **list** of package names
+ """
+ ret=[]
@@ -269,11 +263,12 @@ index 0000000..65ece7b
+
+
+class GentoolkitUtils:
-+ """
-+ Interface with qfile and qlist utils. They are much faster than
++ """
++ Interface with qfile and qlist utils. They are much faster than
+ internals.
+ """
+
++ @staticmethod
+ def getpackagesbyfiles(files):
+ """
+ :param files: list of filenames
@@ -287,14 +282,14 @@ index 0000000..65ece7b
+ ret[f]="directory"
+ else:
+ listtocheck.append(f)
-+
++
+ try:
+ proc=subprocess.Popen(['qfile']+['--nocolor','--exact','','--from','-'],
-+ stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE,
++ stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE,
+ bufsize=4096)
-+
++
+ out,err=proc.communicate("\n".join(listtocheck).encode("utf8"))
-+
++
+ lines=out.decode("utf8").split("\n")
+ #print lines
+ line_re=re.compile(r"^([^ ]+)\s+\(([^)]+)\)$")
@@ -309,24 +304,25 @@ index 0000000..65ece7b
+
+ except OSError as e:
+ portage.util.writemsg("Error while launching qfile: %s\n" % e)
-+
-+
++
++
+ return ret
-+
++
++ @staticmethod
+ def getfilesbypackages(packagenames):
+ """
-+
++
+ :param packagename: name of package
+ :returns: **list** of files in package with name *packagename*
+ """
+ ret=[]
+ try:
+ proc=subprocess.Popen(['qlist']+['--nocolor',"--obj"]+packagenames,
-+ stdout=subprocess.PIPE,stderr=subprocess.PIPE,
++ stdout=subprocess.PIPE,stderr=subprocess.PIPE,
+ bufsize=4096)
-+
++
+ out,err=proc.communicate()
-+
++
+ ret=out.decode("utf8").split("\n")
+ if ret==['']:
+ ret=[]
@@ -334,34 +330,35 @@ index 0000000..65ece7b
+ portage.util.writemsg("Error while launching qfile: %s\n" % e)
+
+ return ret
-+
-+ def get_all_packages_files():
++
++ @staticmethod
++ def get_all_packages_files():
+ """
+ Memory-hungry operation
-+
++
+ :returns: **set** of all files that belongs to package
+ """
+ ret=[]
+ try:
+ proc=subprocess.Popen(['qlist']+['--all',"--obj"],
-+ stdout=subprocess.PIPE,stderr=subprocess.PIPE,
++ stdout=subprocess.PIPE,stderr=subprocess.PIPE,
+ bufsize=4096)
-+
++
+ out,err=proc.communicate()
-+
++
+ ret=out.decode("utf8").split("\n")
+ except OSError as e:
+ portage.util.writemsg("Error while launching qfile: %s\n" % e)
+
+ return set(ret)
-+
++
+class FilterProcGenerator:
+ def __init__(self, pkgname, settings):
+ portageutils=PortageUtils(settings=settings)
+
+ deps_all=portageutils.get_deps_for_package_building(pkgname)
+ deps_portage=portageutils.get_dep('portage',["RDEPEND"])
-+
++
+ system_packages=portageutils.get_system_packages_list()
+
+ allfiles=GentoolkitUtils.get_all_packages_files()
@@ -369,8 +366,8 @@ index 0000000..65ece7b
+ "a list of allowed files\n")
+
+
-+ allowedpkgs=system_packages+list(deps_portage)+list(deps_all)
-+
++ allowedpkgs=system_packages+list(deps_portage)+list(deps_all)
++
+ allowedfiles=GentoolkitUtils.getfilesbypackages(allowedpkgs)
+ #for pkg in allowedpkgs:
+ # allowedfiles+=GentoolkitUtils.getfilesbypackage(pkg)
@@ -380,14 +377,14 @@ index 0000000..65ece7b
+ # manually add all python interpreters to this list
+ allowedfiles+=GentoolkitUtils.getfilesbypackages(['python'])
+ allowedfiles=set(allowedfiles)
-+
++
+ deniedfiles=allfiles-allowedfiles
+
+ def filter_proc(eventname,filename,stage):
+ if filename in deniedfiles:
+ return False
+ return True
-+
++
+ self.filter_proc=filter_proc
+ def get_filter_proc(self):
+ return self.filter_proc
@@ -402,10 +399,10 @@ index 0000000..65ece7b
+ self.deps_all=self.portageutils.get_deps_for_package_building(pkgname)
+ self.deps_direct=self.portageutils.get_dep(pkgname,["DEPEND"])
+ self.deps_portage=self.portageutils.get_dep('portage',["RDEPEND"])
-+
++
+ self.system_packages=self.portageutils.get_system_packages_list()
+ # All analyse work is here
-+
++
+ # get unique filenames
+ filenames=set()
+ for stage in events:
@@ -416,7 +413,7 @@ index 0000000..65ece7b
+ filenames=list(filenames)
+
+ file_to_package=GentoolkitUtils.getpackagesbyfiles(filenames)
-+ # This part is completly unreadable.
++ # This part is completly unreadable.
+ # It converting one complex struct(returned by getfsevents) to another complex
+ # struct which good for generating output.
+ #
@@ -427,24 +424,24 @@ index 0000000..65ece7b
+ for stage in sorted(events):
+ succ_events=events[stage][0]
+ fail_events=events[stage][1]
-+
++
+ for filename in succ_events:
+ if filename in file_to_package:
+ package=file_to_package[filename]
+ else:
+ package="unknown"
-+
++
+ if not package in packagesinfo:
+ packagesinfo[package]={}
+ stageinfo=packagesinfo[package]
+ if not stage in stageinfo:
+ stageinfo[stage]={}
-+
++
+ filesinfo=stageinfo[stage]
+ if not filename in filesinfo:
+ filesinfo[filename]={"found":[],"notfound":[]}
+ filesinfo[filename]["found"]=succ_events[filename]
-+
++
+ for filename in fail_events:
+ if filename in file_to_package:
+ package=file_to_package[filename]
@@ -455,13 +452,13 @@ index 0000000..65ece7b
+ stageinfo=packagesinfo[package]
+ if not stage in stageinfo:
+ stageinfo[stage]={}
-+
++
+ filesinfo=stageinfo[stage]
+ if not filename in filesinfo:
+ filesinfo[filename]={"found":[],"notfound":[]}
+ filesinfo[filename]["notfound"]=fail_events[filename]
+ self.packagesinfo=packagesinfo
-+
++
+ def display(self):
+ portage.util.writemsg(
+ portage.output.colorize(
@@ -470,12 +467,12 @@ index 0000000..65ece7b
+ stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile":6,"test":7,
+ "install":8,"preinst":9,"postinst":10,"prerm":11,"postrm":12,"unknown":13}
+ packagesinfo=self.packagesinfo
-+ # print information grouped by package
++ # print information grouped by package
+ for package in sorted(packagesinfo):
+ # not showing special directory package
+ if package=="directory":
+ continue
-+
++
+ if package=="unknown":
+ continue
+
@@ -492,7 +489,7 @@ index 0000000..65ece7b
+
+ if len(stages)==0:
+ continue
-+
++
+ filenames={}
+ for stage in stages:
+ for filename in packagesinfo[package][stage]:
@@ -503,7 +500,7 @@ index 0000000..65ece7b
+ else:
+ status, old_was_readed, old_was_writed=filenames[filename]
+ filenames[filename]=[
-+ 'ok',old_was_readed | was_readed, old_was_writed | was_writed
++ 'ok',old_was_readed | was_readed, old_was_writed | was_writed
+ ]
+ if len(packagesinfo[package][stage][filename]["notfound"])!=0:
+ was_notfound,was_blocked=packagesinfo[package][stage][filename]["notfound"]
@@ -512,9 +509,9 @@ index 0000000..65ece7b
+ else:
+ status, old_was_notfound, old_was_blocked=filenames[filename]
+ filenames[filename]=[
-+ 'err',old_was_notfound | was_notfound, old_was_blocked | was_blocked
++ 'err',old_was_notfound | was_notfound, old_was_blocked | was_blocked
+ ]
-+
++
+
+ if is_pkg_in_dep:
+ portage.util.writemsg("[OK]")
@@ -543,9 +540,9 @@ index 0000000..65ece7b
+ ('err',False,True):"blocked",
+ ('err',True,True):"not found and blocked"
+ }
-+
++
+ filescounter=0
-+
++
+ for filename in filenames:
+ event_info=tuple(filenames[filename])
+ portage.util.writemsg(" %-56s %-21s\n" % (filename,action[event_info]))
@@ -553,7 +550,7 @@ index 0000000..65ece7b
+ if filescounter>10:
+ portage.util.writemsg(" ... and %d more ...\n" % (len(filenames)-10))
+ break
-+ # ... and one more check. Making sure that direct build time
++ # ... and one more check. Making sure that direct build time
+ # dependencies were accessed
+ #import pdb; pdb.set_trace()
+ not_accessed_deps=set(self.deps_direct)-set(self.packagesinfo.keys())
@@ -562,7 +559,7 @@ index 0000000..65ece7b
+ portage.util.writemsg("Warning! Some build time dependencies " + \
+ "of packages were not accessed: " + \
+ " ".join(not_accessed_deps) + "\n")
-+
++
+ def is_package_useful(self,pkg,stages,files):
+ """ some basic heuristics here to cut part of packages """
+
@@ -596,22 +593,19 @@ index 0000000..65ece7b
+ for f in files:
+ if is_file_excluded(f):
+ continue
-+
-+ # test 1: package is not useful if all files are *.desktop or *.xml or *.m4
++
++ # test 1: package is not useful if all files are *.desktop or *.xml or *.m4
+ if not (f.endswith(".desktop") or f.endswith(".xml") or f.endswith(".m4") or f.endswith(".pc")):
+ break
+ else:
+ return False # we get here if cycle ends not with break
-+
++
+ return True
-+
-+
-\ No newline at end of file
-diff --git a/pym/_emerge/EventsLogger.py b/pym/_emerge/EventsLogger.py
-new file mode 100644
-index 0000000..68b3c67
---- /dev/null
-+++ b/pym/_emerge/EventsLogger.py
++
++
+diff -urN /usr/lib/portage/pym/_emerge/EventsLogger.py ./pym/_emerge/EventsLogger.py
+--- /usr/lib/portage/pym/_emerge/EventsLogger.py 1970-01-01 05:00:00.000000000 +0500
++++ ./pym/_emerge/EventsLogger.py 2014-02-17 17:36:42.034349501 +0600
@@ -0,0 +1,180 @@
+# Distributed under the terms of the GNU General Public License v2
+
@@ -629,17 +623,17 @@ index 0000000..68b3c67
+class EventsLogger(threading.Thread):
+ def default_filter(eventname, filename, stage):
+ return True
-+
++
+ def __init__(self, socket_dir="/tmp/", filter_proc=default_filter):
+ threading.Thread.__init__(self) # init the Thread
-+
++
+ self.alive=False
-+
++
+ self.main_thread=threading.currentThread()
-+
++
+ self.socket_dir=socket_dir
+ self.filter_proc=filter_proc
-+
++
+ self.socket_name=None
+ self.socket_logger=None
+
@@ -648,16 +642,16 @@ index 0000000..68b3c67
+ try:
+ socket_dir_name = tempfile.mkdtemp(dir=self.socket_dir,
+ prefix="log_socket_")
-+
++
+ socket_name = os.path.join(socket_dir_name, 'socket')
+
+ except OSError as e:
+ return
-+
++
+ self.socket_name=socket_name
-+
++
+ #print(self.socket_name)
-+
++
+ try:
+ socket_logger=socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
+ socket_logger.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -680,21 +674,21 @@ index 0000000..68b3c67
+ stat.S_IROTH|stat.S_IWOTH|stat.S_IXOTH)
+ except OSError as e:
+ return
-+
++
+ def run(self):
+ """ Starts the log server """
+
+ self.alive=True
+ self.listen_thread=threading.currentThread()
+ clients={}
-+
++
+ epoll=select.epoll()
+ epoll.register(self.socket_logger.fileno(), select.EPOLLIN)
+
+ while self.alive:
+ try:
+ sock_events = epoll.poll(3)
-+
++
+ for fileno, sock_event in sock_events:
+ if fileno == self.socket_logger.fileno():
+ ret = self.socket_logger.accept()
@@ -707,13 +701,13 @@ index 0000000..68b3c67
+ elif sock_event & select.EPOLLIN:
+ s=clients[fileno]
+ record=s.recv(8192)
-+
++
+ if not record: # if connection was closed
+ epoll.unregister(fileno)
+ clients[fileno].close()
+ del clients[fileno]
+ continue
-+
++
+ #import pdb; pdb.set_trace()
+ try:
+ message=record.decode("utf8").split("\0")
@@ -724,7 +718,7 @@ index 0000000..68b3c67
+ # continue
+
+ #print(message)
-+
++
+ try:
+ if message[4]=="ASKING":
+ if self.filter_proc(message[1],message[2],message[3]):
@@ -738,7 +732,7 @@ index 0000000..68b3c67
+
+ if not stage in self.events:
+ self.events[stage]=[{},{}]
-+
++
+ hashofsucesses=self.events[stage][0]
+ hashoffailures=self.events[stage][1]
+
@@ -748,19 +742,19 @@ index 0000000..68b3c67
+ if result=="OK":
+ if not filename in hashofsucesses:
+ hashofsucesses[filename]=[False,False]
-+
++
+ readed_or_writed=hashofsucesses[filename]
-+
++
+ if eventname=="read":
+ readed_or_writed[0]=True
+ elif eventname=="write":
+ readed_or_writed[1]=True
-+
++
+ elif result[0:3]=="ERR" or result=="DENIED":
+ if not filename in hashoffailures:
+ hashoffailures[filename]=[False,False]
+ notfound_or_blocked=hashoffailures[filename]
-+
++
+ if result=="ERR/2":
+ notfound_or_blocked[0]=True
+ elif result=="DENIED":
@@ -768,74 +762,122 @@ index 0000000..68b3c67
+
+ else:
+ print("Error in logger module<->analyser protocol")
-+
++
+ except IndexError:
+ print("IndexError while parsing %s" % record)
+ except IOError as e:
+ if e.errno!=4: # handling "Interrupted system call" errors
+ raise
-+
-+ # if main thread doesnt exists then exit
++
++ # if main thread doesnt exists then exit
+ if not self.main_thread.is_alive():
+ break
+ epoll.unregister(self.socket_logger.fileno())
+ epoll.close()
+ self.socket_logger.close()
-+
++
+ def stop(self):
+ """ Stops the log server. Returns all events """
+
+ self.alive=False
-+
++
+ # Block the main thread until listener exists
+ self.listen_thread.join()
-+
++
+ # We assume portage clears tmp folder, so no deleting a socket file
+ # We assume that no new socket data will arrive after this moment
+ return self.events
-diff --git a/pym/portage/const.py b/pym/portage/const.py
-index ecaa8f1..f34398d 100644
---- a/pym/portage/const.py
-+++ b/pym/portage/const.py
-@@ -67,6 +67,8 @@ FAKEROOT_BINARY = "/usr/bin/fakeroot"
+diff -urN /usr/lib/portage/pym/portage/const.py ./pym/portage/const.py
+--- /usr/lib/portage/pym/portage/const.py 2014-01-23 14:09:04.077948503 +0600
++++ ./pym/portage/const.py 2014-02-17 17:38:12.197345709 +0600
+@@ -72,6 +72,7 @@
BASH_BINARY = "/bin/bash"
MOVE_BINARY = "/bin/mv"
PRELINK_BINARY = "/usr/sbin/prelink"
-+AUTODEP_LIBRARY = "/usr/lib/file_hook.so"
-+
++AUTODEP_LIBRARY = "/usr/lib/file_hook.so"
INVALID_ENV_FILE = "/etc/spork/is/not/valid/profile.env"
REPO_NAME_FILE = "repo_name"
-@@ -88,7 +90,8 @@ EBUILD_PHASES = ("pretend", "setup", "unpack", "prepare", "configure"
- SUPPORTED_FEATURES = frozenset([
- "allow-missing-manifests",
- "assume-digests", "binpkg-logs", "buildpkg", "buildsyspkg", "candy",
-- "ccache", "chflags", "collision-protect", "compress-build-logs",
-+ "ccache", "chflags", "collision-protect", "compress-build-logs",
-+ "depcheck", "depcheckstrict",
- "digest", "distcc", "distcc-pump", "distlocks", "ebuild-locks", "fakeroot",
- "fail-clean", "fixpackages", "force-mirror", "getbinpkg",
- "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
-diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py
-index 87aa606..6d42809 100644
---- a/pym/portage/package/ebuild/_config/special_env_vars.py
-+++ b/pym/portage/package/ebuild/_config/special_env_vars.py
-@@ -101,8 +101,8 @@ environ_whitelist += [
+@@ -133,6 +134,8 @@
+ "compressdebug",
+ "compress-index",
+ "config-protect-if-modified",
++ "depcheck",
++ "depcheckstrict",
+ "digest",
+ "distcc",
+ "distcc-pump",
+diff -urN /usr/lib/portage/pym/portage/package/ebuild/_config/special_env_vars.py ./pym/portage/package/ebuild/_config/special_env_vars.py
+--- /usr/lib/portage/pym/portage/package/ebuild/_config/special_env_vars.py 2014-01-23 14:09:06.463948342 +0600
++++ ./pym/portage/package/ebuild/_config/special_env_vars.py 2014-02-17 17:40:56.800338787 +0600
+@@ -113,7 +113,7 @@
# other variables inherited from the calling environment
environ_whitelist += [
"CVS_RSH", "ECHANGELOG_USER",
- "GPG_AGENT_INFO",
-- "SSH_AGENT_PID", "SSH_AUTH_SOCK",
+ "GPG_AGENT_INFO", "LOG_SOCKET",
-+ "SSH_AGENT_PID", "SSH_AUTH_SOCK"
+ "SSH_AGENT_PID", "SSH_AUTH_SOCK",
"STY", "WINDOW", "XAUTHORITY",
]
+diff -urN /usr/lib/portage/pym/portage/package/ebuild/doebuild.py ./pym/portage/package/ebuild/doebuild.py
+--- /usr/lib/portage/pym/portage/package/ebuild/doebuild.py 2014-01-23 14:09:06.183948361 +0600
++++ ./pym/portage/package/ebuild/doebuild.py 2014-02-17 17:43:25.387332538 +0600
+@@ -66,7 +66,7 @@
+ from portage.util import apply_recursive_permissions, \
+ apply_secpass_permissions, noiselimit, normalize_path, \
+ writemsg, writemsg_stdout, write_atomic
+-from portage.util.lafilefixer import rewrite_lafile
++from portage.util.lafilefixer import rewrite_lafile
+ from portage.versions import _pkgsplit
+ from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor
+ from _emerge.EbuildBuildDir import EbuildBuildDir
+@@ -492,7 +492,7 @@
+ """
+ Wrapper function that invokes specific ebuild phases through the spawning
+ of ebuild.sh
+-
++
+ @param myebuild: name of the ebuild to invoke the phase on (CPV)
+ @type myebuild: String
+ @param mydo: Phase to run
+@@ -535,13 +535,13 @@
+ @return:
+ 1. 0 for success
+ 2. 1 for error
+-
++
+ Most errors have an accompanying error message.
+-
++
+ listonly and fetchonly are only really necessary for operations involving 'fetch'
+ prev_mtimes are only necessary for merge operations.
+ Other variables may not be strictly required, many have defaults that are set inside of doebuild.
+-
++
+ """
-diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
-index 49b67ac..c76c1ed 100644
---- a/pym/portage/package/ebuild/doebuild.py
-+++ b/pym/portage/package/ebuild/doebuild.py
-@@ -1038,6 +1038,9 @@ def _spawn_actionmap(settings):
+ if settings is None:
+@@ -563,8 +563,8 @@
+ if not tree:
+ writemsg("Warning: tree not specified to doebuild\n")
+ tree = "porttree"
+-
+- # chunked out deps for each phase, so that ebuild binary can use it
++
++ # chunked out deps for each phase, so that ebuild binary can use it
+ # to collapse targets down.
+ actionmap_deps={
+ "pretend" : [],
+@@ -579,7 +579,7 @@
+ "package":["install"],
+ "merge" :["install"],
+ }
+-
++
+ if mydbapi is None:
+ mydbapi = portage.db[myroot][tree].dbapi
+
+@@ -1306,6 +1306,9 @@
nosandbox = ("sandbox" not in features and \
"usersandbox" not in features)
@@ -845,7 +887,7 @@ index 49b67ac..c76c1ed 100644
if not portage.process.sandbox_capable:
nosandbox = True
-@@ -1215,7 +1218,10 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
+@@ -1551,7 +1554,10 @@
keywords["opt_name"] = "[%s/%s]" % \
(mysettings.get("CATEGORY",""), mysettings.get("PF",""))
@@ -857,20 +899,19 @@ index 49b67ac..c76c1ed 100644
keywords["opt_name"] += " bash"
spawn_func = portage.process.spawn_bash
elif fakeroot:
-diff --git a/pym/portage/process.py b/pym/portage/process.py
-index 3c15370..6866a2f 100644
---- a/pym/portage/process.py
-+++ b/pym/portage/process.py
-@@ -16,7 +16,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
- 'portage.util:dump_traceback',
+diff -urN /usr/lib/portage/pym/portage/process.py ./pym/portage/process.py
+--- /usr/lib/portage/pym/portage/process.py 2014-01-23 14:09:04.079948503 +0600
++++ ./pym/portage/process.py 2014-02-17 17:45:29.526327317 +0600
+@@ -22,7 +22,7 @@
+ 'portage.util:dump_traceback,writemsg',
)
-from portage.const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY
+from portage.const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY, AUTODEP_LIBRARY
from portage.exception import CommandNotFound
+ from portage.util._ctypes import find_library, LoadLibrary, ctypes
- try:
-@@ -39,6 +39,9 @@ else:
+@@ -87,13 +87,16 @@
sandbox_capable = (os.path.isfile(SANDBOX_BINARY) and
os.access(SANDBOX_BINARY, os.X_OK))
@@ -880,7 +921,15 @@ index 3c15370..6866a2f 100644
fakeroot_capable = (os.path.isfile(FAKEROOT_BINARY) and
os.access(FAKEROOT_BINARY, os.X_OK))
-@@ -66,6 +69,16 @@ def spawn_bash(mycommand, debug=False, opt_name=None, **keywords):
+ def spawn_bash(mycommand, debug=False, opt_name=None, **keywords):
+ """
+ Spawns a bash shell running a specific commands
+-
++
+ @param mycommand: The command for bash to run
+ @type mycommand: String
+ @param debug: Turn bash debugging on (set -x)
+@@ -114,6 +117,16 @@
args.append(mycommand)
return spawn(args, opt_name=opt_name, **keywords)
@@ -892,8 +941,44 @@ index 3c15370..6866a2f 100644
+
+ # Core part: tell the loader to preload logging library
+ keywords["env"]["LD_PRELOAD"]=AUTODEP_LIBRARY
-+ return spawn_bash(mycommand, opt_name=opt_name, **keywords)
++ return spawn_bash(mycommand, opt_name=opt_name, **keywords)
+
def spawn_sandbox(mycommand, opt_name=None, **keywords):
if not sandbox_capable:
return spawn_bash(mycommand, opt_name=opt_name, **keywords)
+@@ -199,7 +212,7 @@
+ unshare_ipc=False, cgroup=None):
+ """
+ Spawns a given command.
+-
++
+ @param mycommand: the command to execute
+ @type mycommand: String or List (Popen style list)
+ @param env: A dict of Key=Value pairs for env variables
+@@ -238,7 +251,7 @@
+
+ logfile requires stdout and stderr to be assigned to this process (ie not pointed
+ somewhere else.)
+-
++
+ """
+
+ # mycommand is either a str or a list
+@@ -387,7 +400,7 @@
+
+ """
+ Execute a given binary with options
+-
++
+ @param binary: Name of program to execute
+ @type binary: String
+ @param mycommand: Options for program
+@@ -627,7 +640,7 @@
+ def find_binary(binary):
+ """
+ Given a binary name, find the binary in PATH
+-
++
+ @param binary: Name of the binary to find
+ @type string
+ @rtype: None or string