local x
local y
local myfail
-
+ local tar_opts=""
[ -z "$*" ] && die "Nothing passed to the 'unpack' command"
for x in "$@"; do
myfail="failure unpacking ${x}"
case "${x##*.}" in
tar)
- tar xof "${srcdir}${x}" || die "$myfail"
+ tar xof "${srcdir}${x}" ${tar_opts} || die "$myfail"
;;
tgz)
- tar xozf "${srcdir}${x}" || die "$myfail"
+ tar xozf "${srcdir}${x}" ${tar_opts} || die "$myfail"
;;
tbz|tbz2)
- bzip2 -dc "${srcdir}${x}" | tar xof -
+ bzip2 -dc "${srcdir}${x}" | tar xof - ${tar_opts}
assert "$myfail"
;;
ZIP|zip|jar)
;;
gz|Z|z)
if [ "${y}" == "tar" ]; then
- tar zoxf "${srcdir}${x}" || die "$myfail"
+ tar zoxf "${srcdir}${x}" ${tar_opts} || die "$myfail"
else
gzip -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
fi
;;
bz2|bz)
if [ "${y}" == "tar" ]; then
- bzip2 -dc "${srcdir}${x}" | tar xof -
+ bzip2 -dc "${srcdir}${x}" | tar xof - ${tar_opts}
assert "$myfail"
else
bzip2 -dc "${srcdir}${x}" > ${x%.*} || die "$myfail"
break
return acceptable
+ def _merge_order_bias(self, mygraph):
+ """Order nodes from highest to lowest overall reference count for
+ optimal leaf node selection."""
+ node_info = {}
+ for node in mygraph.order:
+ node_info[node] = len(mygraph.parent_nodes(node))
+ def cmp_merge_preference(node1, node2):
+ return node_info[node2] - node_info[node1]
+ mygraph.order.sort(cmp_merge_preference)
+
def altlist(self, reversed=False):
if reversed in self._altlist_cache:
return self._altlist_cache[reversed][:]
self._altlist_cache[reversed] = retlist[:]
return retlist
mygraph=self.digraph.copy()
+ self._merge_order_bias(mygraph)
myblockers = self.blocker_digraph.copy()
retlist=[]
circular_blocks = False
# output, so it's disabled in reversed mode.
selected_nodes = nodes
else:
- # Only pop one node for optimal merge order.
- selected_nodes = [nodes[0]]
+ # For optimal merge order:
+ # * Only pop one node.
+ # * Removing a root node (node without a parent)
+ # will not produce a leaf node, so avoid it.
+ for node in nodes:
+ if mygraph.parent_nodes(node):
+ # found a non-root node
+ selected_nodes = [node]
+ break
+ if not selected_nodes:
+ # settle for a root node
+ selected_nodes = [nodes[0]]
else:
"""Recursively gather a group of nodes that RDEPEND on
eachother. This ensures that they are merged as a group
selected_nodes = [blocker_deps.pop()]
if not selected_nodes:
- if reversed:
- """The circular deps ouput should have less noise when
- altlist is not in reversed mode."""
- self.altlist()
- print "!!! Error: circular dependencies:"
- print
- # Reduce the noise level to a minimum via elimination of root
- # nodes.
+ # No leaf nodes are available, so we have a circular
+ # dependency panic situation. Reduce the noise level to a
+ # minimum via repeated elimination of root nodes since they
+ # have no parents and thus can not be part of a cycle.
while True:
root_nodes = mygraph.root_nodes(
ignore_priority=DepPriority.SOFT)
break
for node in root_nodes:
mygraph.remove(node)
+ # Display the USE flags that are enabled on nodes that are part
+ # of dependency cycles in case that helps the user decide to
+ # disable some of them.
+ display_order = []
+ tempgraph = mygraph.copy()
+ while not tempgraph.empty():
+ nodes = tempgraph.leaf_nodes()
+ if not nodes:
+ node = tempgraph.order[0]
+ else:
+ node = nodes[0]
+ display_order.append(list(node))
+ tempgraph.remove(node)
+ display_order.reverse()
+ self.myopts.pop("--quiet", None)
+ self.myopts.pop("--verbose", None)
+ self.myopts["--tree"] = True
+ self.display(display_order)
+ print "!!! Error: circular dependencies:"
+ print
mygraph.debug_print()
+ print
+ print "!!! Note that circular dependencies can often be avoided by temporarily"
+ print "!!! disabling USE flags that trigger optional dependencies."
sys.exit(1)
for node in selected_nodes:
myopts, myaction, myfiles, spinner):
ldpath_mtimes = mtimedb["ldpath"]
favorites=[]
- if ("--ask" in myopts or "--pretend" in myopts) and not "--quiet" in myopts:
+ if "--quiet" not in myopts:
action = ""
if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
action = "fetched"
sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
sys.exit(1)
- if "--ask" in myopts:
+ if "--pretend" not in myopts and \
+ not ("--quiet" in myopts and "--ask" not in myopts):
if "--resume" in myopts:
validate_merge_list(trees, mtimedb["resume"]["mergelist"])
mymergelist = mtimedb["resume"]["mergelist"]
else:
prompt="Would you like to merge these packages?"
print
- if userquery(prompt)=="No":
+ if "--ask" in myopts and userquery(prompt) == "No":
print
print "Quitting."
print
sys.exit(0)
# Don't ask again (e.g. when auto-cleaning packages after merge)
- del myopts["--ask"]
+ myopts.pop("--ask", None)
if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
if ("--resume" in myopts):
use for a given cpv. If a collision will occur with an existing
package from another category, the existing package will be bumped to
${PKGDIR}/${CATEGORY}/${PF}.tbz2 so that both can coexist."""
+ if not self.populated:
+ # Try to avoid the population routine when possible, so that
+ # FEATURES=buildpkg doesn't always force population.
+ mycat, mypkg = catsplit(cpv)
+ myfile = mypkg + ".tbz2"
+ full_path = os.path.join(self.pkgdir, "All", myfile)
+ if not os.path.exists(full_path):
+ return
+ tbz2_cat = portage.xpak.tbz2(full_path).getfile("CATEGORY")
+ if tbz2_cat and tbz2_cat.strip() == mycat:
+ return
full_path = self.getname(cpv)
if "All" == full_path.split(os.path.sep)[-2]:
return