From: Fabian Groffen Date: Fri, 13 Jul 2007 17:59:44 +0000 (-0000) Subject: Merged from trunk 7209:7242 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=6deff62f93644180de4ca141c52cfdd5031cc9a3;p=portage.git Merged from trunk 7209:7242 +------------------------------------------------------------------------+ | 7210 | - remove readable bits for debug files if the souce ELF is | | solar | setXid | |---------+--------------------------------------------------------------| | 7211 | - be quiet about overlays profiles/repo_name entry when | | solar | --quiet mode is used | |---------+--------------------------------------------------------------| | 7212 | Remove the repo_name warning in the portdbapi constructor | | zmedico | since we don't want to see a warning every time the portage | | | module is imported. | |---------+--------------------------------------------------------------| | 7214 | For bug #184806, account for the fact the metadata is not | | zmedico | cached for slot_collision_nodes. | |---------+--------------------------------------------------------------| | 7216 | For bug #184604, make env-update write $ in front of quoted | | zmedico | values when appropriate. | |---------+--------------------------------------------------------------| | 7218 | For bug #184843, allow USE_EXPAND variables to pass through | | zmedico | if none of their flags are in IUSE. This allows packages | | | that support LINGUAS but don't declare it in IUSE to use the | | | variable outside of the USE_EXPAND context. | |---------+--------------------------------------------------------------| | 7220 | For bug #184679, handle ENOTDIR by finding the non-directory | | zmedico | parent and testing that for collision instead. | |---------+--------------------------------------------------------------| | 7222 | For bug #184687, skip the huge --depclean warning when | | zmedico | --quiet mode is enabled. | |---------+--------------------------------------------------------------| | 7224 | Fix typo. | | zmedico | | |---------+--------------------------------------------------------------| | 7226 | Fix another case similar to bug #184806 that can occur with | | zmedico | --onlydeps. | |---------+--------------------------------------------------------------| | 7228 | Fix typo. | | zmedico | | |---------+--------------------------------------------------------------| | 7230 | Use set.discard() instead of remove() to avoid a potential | | zmedico | KeyError. | |---------+--------------------------------------------------------------| | 7237 | For bug #184983, prevent USE_EXPAND_HIDDEN flags from being | | zmedico | hidden if they are the only thing that triggered | | | reinstallation. | |---------+--------------------------------------------------------------| | 7239 | Make depgraph._reinstall_for_flags() always return all | | zmedico | revelant flags. | |---------+--------------------------------------------------------------| | 7241 | Fix the case where the currently installed package is from a | | zmedico | repo that is no longer in the overlay (oldrepo is None | | | rather than an empty string). | |---------+--------------------------------------------------------------| | 7242 | Add "reset" to the list of attributes. | | zmedico | | +------------------------------------------------------------------------+ svn path=/main/branches/prefix/; revision=7244 --- diff --git a/bin/prepstrip b/bin/prepstrip index df187c127..68418b5f2 100755 --- a/bin/prepstrip +++ b/bin/prepstrip @@ -50,6 +50,8 @@ save_elf_debug() { mkdir -p $(dirname "${y}") ${OBJCOPY} --only-keep-debug "${x}" "${y}" ${OBJCOPY} --add-gnu-debuglink="${y}" "${x}" + [ -g "${x}" ] && chmod go-r "${y}" + [ -u "${x}" ] && chmod go-r "${y}" chmod a-x,o-w "${y}" } diff --git a/man/color.map.5 b/man/color.map.5 index 7a0f1b2ec..bf63bbaed 100644 --- a/man/color.map.5 +++ b/man/color.map.5 @@ -123,6 +123,8 @@ Defines color used for warnings. .B Other attributes .RS .TP +.B reset +.TP .B bold .TP .B faint diff --git a/pym/emerge/__init__.py b/pym/emerge/__init__.py index 6966b7928..20bb8dac2 100644 --- a/pym/emerge/__init__.py +++ b/pym/emerge/__init__.py @@ -352,9 +352,9 @@ def create_depgraph_params(myopts, myaction): myparams.add("selective") if "--emptytree" in myopts: myparams.add("empty") - myparams.remove("selective") + myparams.discard("selective") if "--nodeps" in myopts: - myparams.remove("recurse") + myparams.discard("recurse") if "--deep" in myopts: myparams.add("deep") return myparams @@ -1083,6 +1083,8 @@ class depgraph(object): self.pkg_node_map = {} # Maps slot atom to digraph node for all nodes added to the graph. self._slot_node_map = {} + # Maps nodes to the reasons they were selected for reinstallation. + self._reinstall_nodes = {} self.mydbapi = {} self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND", "USE", "IUSE", "PROVIDE", "RESTRICT", "repository"] @@ -1204,18 +1206,21 @@ class depgraph(object): def _reinstall_for_flags(self, forced_flags, orig_use, orig_iuse, cur_use, cur_iuse): + """Return a set of flags that trigger reinstallation, or None if there + are no such flags.""" if "--newuse" in self.myopts: - if orig_iuse.symmetric_difference( - cur_iuse).difference(forced_flags): - return True - elif orig_iuse.intersection(orig_use) != \ - cur_iuse.intersection(cur_use): - return True + flags = orig_iuse.symmetric_difference( + cur_iuse).difference(forced_flags) + flags.update(orig_iuse.intersection(orig_use).symmetric_difference( + cur_iuse.intersection(cur_use))) + if flags: + return flags elif "changed-use" == self.myopts.get("--reinstall"): - if orig_iuse.intersection(orig_use) != \ - cur_iuse.intersection(cur_use): - return True - return False + flags = orig_iuse.intersection(orig_use).symmetric_difference( + cur_iuse.intersection(cur_use)) + if flags: + return flags + return None def create(self, mybigkey, myparent=None, addme=1, myuse=None, priority=DepPriority(), rev_dep=False, arg=None): @@ -1286,6 +1291,7 @@ class depgraph(object): return 0 del e + reinstall_for_flags = None merging=1 if mytype == "installed": merging = 0 @@ -1299,6 +1305,7 @@ class depgraph(object): If the package has new iuse flags or different use flags then if --newuse is specified, we need to merge the package. """ if merging == 0 and \ + myroot == self.target_root and \ ("--newuse" in self.myopts or "--reinstall" in self.myopts) and \ vardbapi.cpv_exists(mykey): @@ -1310,8 +1317,9 @@ class depgraph(object): iuses = set(filter_iuse_defaults(metadata["IUSE"].split())) old_iuse = set(filter_iuse_defaults( vardbapi.aux_get(mykey, ["IUSE"])[0].split())) - if self._reinstall_for_flags( - forced_flags, old_use, old_iuse, myuse, iuses): + reinstall_for_flags = self._reinstall_for_flags( + forced_flags, old_use, old_iuse, myuse, iuses) + if reinstall_for_flags: merging = 1 if addme and merging == 1: @@ -1379,6 +1387,8 @@ class depgraph(object): self._slot_node_map[myroot][slot_atom] = jbigkey self.pkg_node_map[myroot][mykey] = jbigkey self.useFlags[myroot][mykey] = myuse + if reinstall_for_flags: + self._reinstall_nodes[jbigkey] = reinstall_for_flags if rev_dep and myparent: self.digraph.addnode(myparent, jbigkey, @@ -1748,6 +1758,9 @@ class depgraph(object): # Update old-style virtuals if this package provides any. # These are needed for dep_virtual calls inside dep_check. p_db = self.mydbapi[p_root] # contains cached metadata + if myparent in self._slot_collision_nodes: + # The metadata isn't cached due to the slot collision. + p_db = self.trees[p_root][self.pkg_tree_map[p_type]].dbapi try: self.pkgsettings[p_root].setinst(p_key, p_db) # For consistency, also update the global virtuals. @@ -2740,6 +2753,7 @@ class depgraph(object): for mylist_index in xrange(len(mylist)): x, depth, ordered = mylist[mylist_index] + pkg_node = tuple(x) pkg_type = x[0] myroot = x[1] pkg_key = x[2] @@ -2771,14 +2785,18 @@ class depgraph(object): addl += bad(" (is blocking %s)") % block_parents blockers.append(addl) else: - mydbapi = self.trees[myroot][self.pkg_tree_map[pkg_type]].dbapi pkg_status = x[3] pkg_merge = ordered and pkg_status != "nomerge" binary_package = pkg_type != "ebuild" + if pkg_node in self._slot_collision_nodes or \ + (pkg_status == "nomerge" and pkg_type != "installed"): + # The metadata isn't cached due to a slot collision or + # --onlydeps. + mydbapi = self.trees[myroot][self.pkg_tree_map[pkg_type]].dbapi + else: + mydbapi = self.mydbapi[myroot] # contains cached metadata metadata = dict(izip(self._mydbapi_keys, - self.mydbapi[myroot].aux_get( - pkg_key, self._mydbapi_keys))) - mydbapi = self.mydbapi[myroot] # use the cached metadata + mydbapi.aux_get(pkg_key, self._mydbapi_keys))) if pkg_key not in self.useFlags[myroot]: """If this is a --resume then the USE flags need to be fetched from the appropriate locations here.""" @@ -2896,7 +2914,8 @@ class depgraph(object): use_expand_hidden = \ pkgsettings["USE_EXPAND_HIDDEN"].lower().split() - def map_to_use_expand(myvals, forcedFlags=False): + def map_to_use_expand(myvals, forcedFlags=False, + removeHidden=True): ret = {} forced = {} for exp in use_expand: @@ -2911,13 +2930,32 @@ class depgraph(object): ret["USE"] = myvals forced["USE"] = [val for val in myvals \ if val in forced_flags] - for exp in use_expand_hidden: - if exp in ret: - del ret[exp] + if removeHidden: + for exp in use_expand_hidden: + ret.pop(exp, None) if forcedFlags: return ret, forced return ret + # Prevent USE_EXPAND_HIDDEN flags from being hidden if they + # are the only thing that triggered reinstallation. + reinst_flags_map = None + reinstall_for_flags = self._reinstall_nodes.get(pkg_node) + if reinstall_for_flags: + reinst_flags_map = map_to_use_expand( + list(reinstall_for_flags), removeHidden=False) + if reinst_flags_map["USE"]: + reinst_flags_map = None + else: + for k in reinst_flags_map.keys(): + if not reinst_flags_map[k]: + del reinst_flags_map[k] + if reinst_flags_map and \ + not set(reinst_flags_map).difference( + use_expand_hidden): + use_expand_hidden = set(use_expand_hidden).difference( + reinst_flags_map) + cur_iuse_map, iuse_forced = \ map_to_use_expand(cur_iuse, forcedFlags=True) cur_use_map = map_to_use_expand(cur_use) @@ -2978,7 +3016,7 @@ class depgraph(object): newrepoindex += 1 # assing lookup indexes - if oldrepo == "": + if not oldrepo: oldrepoindex = "?" elif oldrepo == pkgsettings["PORTDIR"]: oldrepoindex = "0" @@ -5275,23 +5313,26 @@ def action_depclean(settings, trees, ldpath_mtimes, # Kill packages that aren't explicitly merged or are required as a # dependency of another package. World file is explicit. - warn_prefix = colorize("BAD", "*** WARNING *** ") - print - print warn_prefix + "Depclean may break link level dependencies. Thus, it is" - print warn_prefix + "recommended to use a tool such as " + good("`revdep-rebuild`") + " (from" - print warn_prefix + "app-portage/gentoolkit) in order to detect such breakage." - print warn_prefix - print warn_prefix + "Also study the list of packages to be cleaned for any obvious" - print warn_prefix + "mistakes. Packages that are part of the world set will always" - print warn_prefix + "be kept. They can be manually added to this set with" - print warn_prefix + good("`emerge --noreplace `") + ". Packages that are listed in" - print warn_prefix + "package.provided (see portage(5)) will be removed by" - print warn_prefix + "depclean, even if they are part of the world set." - print warn_prefix - print warn_prefix + "As a safety measure, depclean will not remove any packages" - print warn_prefix + "unless *all* required dependencies have been resolved. As a" - print warn_prefix + "consequence, it is often necessary to run " - print warn_prefix + good("`emerge --update --newuse --deep world`") + " prior to depclean." + msg = [] + msg.append("Depclean may break link level dependencies. Thus, it is\n") + msg.append("recommended to use a tool such as " + good("`revdep-rebuild`") + " (from\n") + msg.append("app-portage/gentoolkit) in order to detect such breakage.\n") + msg.append("\n") + msg.append("Also study the list of packages to be cleaned for any obvious\n") + msg.append("mistakes. Packages that are part of the world set will always\n") + msg.append("be kept. They can be manually added to this set with\n") + msg.append(good("`emerge --noreplace `") + ". Packages that are listed in\n") + msg.append("package.provided (see portage(5)) will be removed by\n") + msg.append("depclean, even if they are part of the world set.\n") + msg.append("\n") + msg.append("As a safety measure, depclean will not remove any packages\n") + msg.append("unless *all* required dependencies have been resolved. As a\n") + msg.append("consequence, it is often necessary to run\n") + msg.append(good("`emerge --update --newuse --deep world`") + " prior to depclean.\n") + + portage.writemsg_stdout("\n") + for x in msg: + portage.writemsg_stdout(colorize("BAD", "*** WARNING *** ") + x) xterm_titles = "notitles" not in settings.features myroot = settings["ROOT"] diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 6515df00c..a6a39c895 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -706,8 +706,12 @@ def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None, env_keys = [ x for x in env if x != "LDPATH" ] env_keys.sort() - for x in env_keys: - outfile.write("export %s='%s'\n" % (x, env[x])) + for k in env_keys: + v = env[k] + if v.startswith('$') and not v.startswith('${'): + outfile.write("export %s=$'%s'\n" % (k, v[1:])) + else: + outfile.write("export %s='%s'\n" % (k, v)) outfile.close() #create /etc/csh.env for (t)csh support @@ -2080,34 +2084,49 @@ class config(object): # like LINGUAS. var_split = [ x for x in var_split if x in expand_flags ] var_split.extend(expand_flags.difference(var_split)) - if (var_split or var in self) and \ - "*" not in var_split: + has_wildcard = "*" in var_split + if has_wildcard: + var_split = [ x for x in var_split if x != "*" ] + has_iuse = False + for x in iuse: + if x.startswith(prefix): + has_iuse = True + break + if has_wildcard: + # * means to enable everything in IUSE that's not masked + if has_iuse: + for x in iuse: + if x.startswith(prefix) and x not in self.usemask: + suffix = x[prefix_len:] + if suffix in var_split: + continue + var_split.append(suffix) + usesplit.append(x) + else: + # If there is a wildcard and no matching flags in IUSE then + # LINGUAS should be unset so that all .mo files are + # installed. + var_split = [] + if var_split: + self[var] = " ".join(var_split) + else: # Don't export empty USE_EXPAND vars unless the user config # exports them as empty. This is required for vars such as # LINGUAS, where unset and empty have different meanings. - self[var] = " ".join(var_split) - elif "*" in var_split: - # * means to enable everything in IUSE that's not masked - filtered_split = [] - for x in var_split: - if x == "*": - continue - if (prefix + x) in iuse: - filtered_split.append(x) - var_split = filtered_split - for x in iuse: - if x.startswith(prefix) and x not in self.usemask: - suffix = x[prefix_len:] - if suffix in var_split: - continue - var_split.append(suffix) - usesplit.append(x) - if var_split: - self[var] = " ".join(var_split) - elif var in self: + if has_wildcard: # ebuild.sh will see this and unset the variable so # that things like LINGUAS work properly self[var] = "*" + else: + if has_iuse: + self[var] = "" + else: + # It's not in IUSE, so just allow the variable content + # to pass through if it is defined somewhere. This + # allows packages that support LINGUAS but don't + # declare it in IUSE to use the variable outside of the + # USE_EXPAND context. + pass # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch. if self.configdict["defaults"].has_key("ARCH"): diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py index 128e5b166..34eff92a7 100644 --- a/pym/portage/dbapi/porttree.py +++ b/pym/portage/dbapi/porttree.py @@ -91,8 +91,9 @@ class portdbapi(dbapi): repo_name = open(repo_name_path, 'r').readline().strip() self.treemap[repo_name] = path except (OSError,IOError): - writemsg("Note: The repository at %s does not have a profiles/repo_name entry.\n" % path \ - + " This can reduce the functionality of the repository in some cases.\n") + # warn about missing repo_name at some other time, since we + # don't want to see a warning every time the portage module is + # imported. pass self.auxdbmodule = self.mysettings.load_best_module("portdbapi.auxdbmodule") diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index ad16e7661..f90c970a6 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -1440,7 +1440,8 @@ class dblink(object): stopmerge = False i=0 collisions = [] - + destroot = normalize_path(destroot).rstrip(os.path.sep) + \ + os.path.sep print green("*")+" checking "+str(len(mycontents))+" files for package collisions" for f in mycontents: nocheck = False @@ -1460,10 +1461,34 @@ class dblink(object): try: dest_lstat = os.lstat(dest_path) except EnvironmentError, e: - if e.errno != errno.ENOENT: + if e.errno == errno.ENOENT: + del e + continue + elif e.errno == errno.ENOTDIR: + del e + # A non-directory is in a location where this package + # expects to have a directory. + dest_lstat = None + parent_path = dest_path + while len(parent_path) > len(destroot): + parent_path = os.path.dirname(parent_path) + try: + dest_lstat = os.lstat(parent_path) + break + except EnvironmentError, e: + if e.errno != errno.ENOTDIR: + raise + del e + if not dest_lstat: + raise AssertionError( + "unable to find non-directory " + \ + "parent for '%s'" % dest_path) + dest_path = parent_path + f = os.path.sep + dest_path[len(destroot):] + if f in collisions: + continue + else: raise - del e - continue if f[0] != "/": f="/"+f isowned = False diff --git a/pym/portage/output.py b/pym/portage/output.py index 384625bea..26a5c4f08 100644 --- a/pym/portage/output.py +++ b/pym/portage/output.py @@ -129,7 +129,8 @@ codes["bg_lightgray"] = esc_seq + "47m" codes["bg_darkyellow"] = codes["bg_brown"] -# Colors from /sbin/functions.sh +# Colors from /etc/init.d/functions.sh +codes["NORMAL"] = esc_seq + "0m" codes["GOOD"] = codes["green"] codes["WARN"] = codes["yellow"] codes["BAD"] = codes["red"]