On Mon, 2009-03-23 at 08:27 +0100, Markus Duft wrote: > On Fri, 2009-03-20 at 12:11 +0100, Markus Duft wrote: > > On Fri, 2009-03-20 at 11:35 +0100, Markus Duft wrote: > > > Hey guys :) > > > > > > Just wanted to stop by and get some opinions on a patch i wrote for the > > > prefix branch. > > > [snip] > > Hey there. Seemingly nobody has any comments on this..? :) here's a > working version of the patch. i realized that the last one worked only > "by accident" :) maybe now, some comments (or questions)?
i'm eager to find out how many times i can forget to attach the patch :) sorry for the noise Cheers, Markus > > Thanks, Cheers, Markus > > [snip] > > > > > > Waiting for comments, suggestions, etc. > > > > > > Thanks in advance, > > > Cheers, Markus > > > > > > > >
diff -ru portage.orig/pym/_emerge/__init__.py portage/pym/_emerge/__init__.py --- portage.orig/pym/_emerge/__init__.py 2009-03-18 10:13:34.000000000 +0100 +++ portage/pym/_emerge/__init__.py 2009-03-23 08:46:59.000000000 +0100 @@ -49,7 +49,7 @@ import portage.xpak, commands, errno, re, socket, time from portage.output import blue, bold, colorize, darkblue, darkgreen, darkred, green, \ nc_len, red, teal, turquoise, xtermTitle, \ - xtermTitleReset, yellow + xtermTitleReset, yellow, purple from portage.output import create_color_func good = create_color_func("GOOD") bad = create_color_func("BAD") @@ -69,6 +69,7 @@ from portage.util import cmp_sort_key, writemsg, writemsg_level from portage.sets import load_default_config, SETPREFIX from portage.sets.base import InternalPackageSet +from portage.dbapi.vartree import vartree from itertools import chain, izip @@ -4692,6 +4693,7 @@ self._unsatisfied_deps_for_display = [] self._unsatisfied_blockers_for_display = None self._circular_deps_for_display = None + self._injected_readonly_deps_for_display = [] self._dep_stack = [] self._unsatisfied_deps = [] self._initially_unsatisfied_deps = [] @@ -5270,18 +5272,35 @@ if removal_action and self.myopts.get("--with-bdeps", "y") == "n": edepend["DEPEND"] = "" + # MDUFT: create additional vartrees for every readonly root here + # (maybe FakeVartree's?). Then below search those trees and set + # mypriority.satisfied to True. + # the ro_vartrees instances are created below as they are needed to + # avoid reading vartrees of portage instances which aren't required + # while resolving this dependencies. + ro_trees = {} + ro_vartrees = {} + + for type in ("DEPEND","RDEPEND", "PDEPEND"): + ro_trees[type] = [] + + for ro_root, ro_dep_types in self.settings.readonly_roots.items(): + if type in ro_dep_types: + ro_trees[type].append(ro_root) + deps = ( - ("/", edepend["DEPEND"], + ("/", "DEPEND", self._priority(buildtime=(not bdeps_optional), optional=bdeps_optional)), - (myroot, edepend["RDEPEND"], self._priority(runtime=True)), - (myroot, edepend["PDEPEND"], self._priority(runtime_post=True)) + (myroot, "RDEPEND", self._priority(runtime=True)), + (myroot, "PDEPEND", self._priority(runtime_post=True)) ) debug = "--debug" in self.myopts strict = mytype != "installed" try: - for dep_root, dep_string, dep_priority in deps: + for dep_root, dep_type, dep_priority in deps: + dep_string = edepend[dep_type] if not dep_string: continue if debug: @@ -5309,6 +5328,43 @@ if not atom.blocker and vardb.match(atom): mypriority.satisfied = True + # MDUFT: How erver we do it - if we find "atom" beeing installed + # in a valid readonly root for the current dependency type, then + # _DONT_ call the below, but rather return 1 immediately. + ro_matched = False + for ro_root in ro_trees[dep_type]: + if not ro_vartrees.has_key(ro_root): + # target_root=ro_root ok? or should it be the real target_root? + _tmp_settings = portage.config(config_root=ro_root, target_root=ro_root, + config_incrementals=portage.const.INCREMENTALS) + #_tmp_trees = portage.util.LazyItemsDict() + #_tmp_trees.addLazySingleton("vartree", vartree, ro_root, + # categories=_tmp_settings.categories, settings=_tmp_settings) + + #setconfig = load_default_config(_tmp_trees["vartree"].settings, _tmp_trees) + #ro_vartrees[ro_root] = FakeVartree(RootConfig(_tmp_trees["vartree"].settings, + # _tmp_trees, setconfig), acquire_lock=0) + + ro_vartrees[ro_root] = vartree(root=ro_root, categories=_tmp_settings.categories, + settings=_tmp_settings, kill_eprefix=True) + + ro_matches = ro_vartrees[ro_root].dbapi.match(atom) + + if ro_matches: + if dep_type is "RDEPEND": + # we need to assure binary compatability, so it needs to be + # the same CHOST! But how? for now i cannot do anything... + pass + + # injected dep for display. those get shown with the merge list. + self._injected_readonly_deps_for_display.append({"ro_root" : ro_root, "atom" : atom, + "matches": ro_matches, "type": dep_type, "parent": pkg}) + ro_matched = True + break + + if ro_matched: + continue + if not self._add_dep(Dependency(atom=atom, blocker=atom.blocker, depth=depth, parent=pkg, priority=mypriority, root=dep_root), @@ -8457,6 +8513,21 @@ for x in blockers: print x + # print _injected_readonly_deps_for_display. + if len(self._injected_readonly_deps_for_display) > 0: + out.write("\n%s\n\n" % (darkgreen("Packages resolved from readonly installations:"))) + + for x in self._injected_readonly_deps_for_display: + tmp_type = x["type"].replace("END","") + while len(tmp_type) < 4: + tmp_type += " " + out.write("[%s %s] %s %s %s (%s by %s)\n" % (teal("external"), + green(tmp_type), green(str(x["matches"][0])), yellow("from"), + blue(x["ro_root"]), turquoise(str(x["atom"])), green(x["parent"].cpv))) + + if len(self._injected_readonly_deps_for_display) > 0: + out.write("\n") + if verbosity == 3: print print counters @@ -11825,6 +11896,7 @@ for x in candidate_catpkgs: # cycle through all our candidate deps and determine # what will and will not get unmerged + try: mymatch = vartree.dbapi.match(x) except portage.exception.AmbiguousPackageName, errpkgs: diff -ru portage.orig/pym/portage/__init__.py portage/pym/portage/__init__.py --- portage.orig/pym/portage/__init__.py 2009-03-18 10:13:35.000000000 +0100 +++ portage/pym/portage/__init__.py 2009-03-20 12:12:34.000000000 +0100 @@ -1236,6 +1236,7 @@ self._accept_license = copy.deepcopy(clone._accept_license) self._plicensedict = copy.deepcopy(clone._plicensedict) + self.readonly_roots = copy.deepcopy(clone.readonly_roots) else: def check_var_directory(varname, var): @@ -1802,6 +1803,45 @@ # but needs to be available using portageq self["EPREFIX"] = EPREFIX + # expand READONLY_EROOT to a list of all readonly portage instances + # all the way down to the last one. beware that ATM a deeper instance + # in the chain can provide more than the toplevel! this means that + # if you only inherit DEPENDS from one instance, that instance may + # inherit RDEPENDs from another one, making the top-level instance + # inherit RDEPENDs from there too - even if the intermediate prefix + # does not do this. + self.readonly_roots = {} + my_ro_current_instance = config_root + + while True: + my_ro_current_make_conf_file = os.path.join(my_ro_current_instance,MAKE_CONF_FILE.lstrip(os.path.sep)) + + if os.path.exists(my_ro_current_make_conf_file): + my_ro_cfg = getconfig(my_ro_current_make_conf_file) + + if my_ro_cfg.has_key("READONLY_EROOT"): + + if not my_ro_cfg["READONLY_EROOT"].find(":"): + raise portage.exception.InvalidReadonlyRoot("ERROR: malformed READONLY_EROOT in %s" % (my_ro_current_make_conf_file)) + + (my_ro_cfg_root,my_ro_cfg_root_deps) = my_ro_cfg["READONLY_EROOT"].rsplit(":",1) + + if not os.path.exists(my_ro_cfg_root): + raise portage.exception.InvalidReadonlyRoot("ERROR: malformed READONLY_EROOT in %s: path does not exist!" % (my_ro_current_instance)) + + if self.readonly_roots.has_key(my_ro_cfg_root): + raise portage.exception.InvalidReadonlyRoot("ERROR: circular READONLY_EROOT's in %s. %s already checked for %s" % (my_ro_current_make_conf_file, my_ro_cfg_root, self.readonly_roots[my_ro_cfg_root])) + + if my_ro_cfg_root == config_root: + raise portage.exception.InvalidReadonlyRoot("ERROR: cannot add this instance as READONLY_EROOT in %s." % (my_ro_current_make_conf_file)) + + self.readonly_roots[my_ro_cfg_root] = my_ro_cfg_root_deps.split(",") + my_ro_current_instance = my_ro_cfg_root + + continue + + break + self._init_dirs() if mycpv: diff -ru portage.orig/pym/portage/dbapi/vartree.py portage/pym/portage/dbapi/vartree.py --- portage.orig/pym/portage/dbapi/vartree.py 2009-03-18 10:13:35.000000000 +0100 +++ portage/pym/portage/dbapi/vartree.py 2009-03-23 08:23:23.000000000 +0100 @@ -1270,9 +1270,20 @@ self._counter_path = os.path.join(root, CACHE_PATH.lstrip(os.path.sep), "counter") + plibreg_path = os.path.join(self.root, EPREFIX_LSTRIP, PRIVATE_PATH, "preserved_libs_registry") + + if vartree: + self._kill_eprefix = vartree._kill_eprefix + else: + self._kill_eprefix = False + + if self._kill_eprefix: + self._aux_cache_filename = os.path.join(self.root, self._aux_cache_filename.replace(EPREFIX, "")) + self._counter_path = os.path.join(self.root, self._counter_path.replace(EPREFIX, "")) + plibreg_path = os.path.join(self.root, plibreg_path.replace(EPREFIX, "")) + try: - self.plib_registry = PreservedLibsRegistry( - os.path.join(self.root, EPREFIX_LSTRIP, PRIVATE_PATH, "preserved_libs_registry")) + self.plib_registry = PreservedLibsRegistry(plibreg_path) except PermissionDenied: # apparently this user isn't allowed to access PRIVATE_PATH self.plib_registry = None @@ -1285,6 +1296,10 @@ def getpath(self, mykey, filename=None): rValue = os.path.join(self.root, VDB_PATH, mykey) + + if self._kill_eprefix: + rValue = os.path.join(self.root, rValue.replace(EPREFIX, "")) + if filename != None: rValue = os.path.join(rValue, filename) return rValue @@ -1433,6 +1448,9 @@ returnme = [] basepath = os.path.join(self.root, VDB_PATH) + os.path.sep + if self._kill_eprefix: + basepath = os.path.join(self.root, basepath.replace(EPREFIX, "")) + if use_cache: from portage import listdir else: @@ -1522,7 +1540,12 @@ return list(self._iter_match(mydep, self.cp_list(mydep.cp, use_cache=use_cache))) try: - curmtime = os.stat(self.root+VDB_PATH+"/"+mycat).st_mtime + _tmp_path = self.root+VDB_PATH+"/"+mycat + + if self._kill_eprefix: + _tmp_path = os.path.join(self.root, _tmp_path.replace(EPREFIX, "")) + + curmtime = os.stat(_tmp_path).st_mtime except (IOError, OSError): curmtime=0 @@ -2063,7 +2086,7 @@ class vartree(object): "this tree will scan a var/db/pkg database located at root (passed to init)" def __init__(self, root="/", virtual=None, clone=None, categories=None, - settings=None): + settings=None, kill_eprefix=False): if clone: writemsg("vartree.__init__(): deprecated " + \ "use of clone parameter\n", noiselevel=-1) @@ -2072,6 +2095,7 @@ self.populated = 1 from portage import config self.settings = config(clone=clone.settings) + self._kill_eprefix = clone._kill_eprefix else: self.root = root[:] if settings is None: @@ -2079,6 +2103,7 @@ self.settings = settings # for key_expand calls if categories is None: categories = settings.categories + self._kill_eprefix=kill_eprefix self.dbapi = vardbapi(self.root, categories=categories, settings=settings, vartree=self) self.populated = 1 @@ -2110,6 +2135,10 @@ raise except Exception, e: mydir = os.path.join(self.root, VDB_PATH, mycpv) + + if self._kill_eprefix: + mydir = os.path.join(self.root, mydir.replace(EPREFIX, "")) + writemsg("\nParse Error reading PROVIDE and USE in '%s'\n" % mydir, noiselevel=-1) if mylines: