.TP
.BR "\-\-update " (\fB\-u\fR)
Updates packages to the best version available, which may not always be the
-highest version number due to masking for testing and development. This will
-also update direct dependencies which may not be what you want. Package atoms
+highest version number due to masking for testing and development.
+Package atoms
specified on the command line are greedy, meaning that unspecific atoms may
match multiple installed versions of slotted packages.
.TP
it to output verbose debugging information to stdout. This also enables
a plethora of other output (mostly dependency resolution messages).
.TP
-.BR "\-\-deep " (\fB\-D\fR)
+.BR "\-\-deep [DEPTH] " (\fB\-D\fR)
This flag forces
\fBemerge\fR to consider the entire dependency tree of packages,
instead of checking only the immediate dependencies of the packages.
\fBDEPEND\fR variable. However, behavior may change for new
\fBEAPI\fRs when related extensions are added in the future.
.TP
+.BR "\-\-selective"
+This is similar to the \fB\-\-noreplace\fR option, except that it
+does not take precedence over options such as \fB\-\-newuse\fR.
+.TP
.BR "\-\-skipfirst"
This option is only valid when used with \fB\-\-resume\fR. It removes the
first package in the resume list. Dependencies are recalculated for
# empty: pretend nothing is merged
# complete: completely account for all known dependencies
# remove: build graph for use in removing packages
- myparams = set(["recurse"])
+ myparams = {"recurse" : True}
if myaction == "remove":
- myparams.add("remove")
- myparams.add("complete")
+ myparams["remove"] = True
+ myparams["complete"] = True
return myparams
if "--update" in myopts or \
"--newuse" in myopts or \
"--reinstall" in myopts or \
- "--noreplace" in myopts:
- myparams.add("selective")
+ "--noreplace" in myopts or \
+ "--selective" in myopts:
+ myparams["selective"] = True
if "--emptytree" in myopts:
- myparams.add("empty")
- myparams.discard("selective")
+ myparams["empty"] = True
+ myparams.pop("selective", None)
if "--nodeps" in myopts:
- myparams.discard("recurse")
+ myparams.pop("recurse", None)
if "--deep" in myopts:
- myparams.add("deep")
+ myparams["deep"] = myopts["--deep"]
if "--complete-graph" in myopts:
- myparams.add("complete")
+ myparams["complete"] = True
return myparams
buildpkgonly = "--buildpkgonly" in self._frozen_config.myopts
nodeps = "--nodeps" in self._frozen_config.myopts
empty = "empty" in self._dynamic_config.myparams
- deep = "deep" in self._dynamic_config.myparams
- update = "--update" in self._frozen_config.myopts and dep.depth <= 1
+ deep = self._dynamic_config.myparams.get("deep", 0)
+ recurse = empty or deep is True or dep.depth <= deep
if dep.blocker:
if not buildpkgonly and \
not nodeps and \
# available for optimization of merge order.
if dep.priority.satisfied and \
not dep_pkg.installed and \
- not (existing_node or empty or deep or update):
+ not (existing_node or recurse):
myarg = None
if dep.root == self._frozen_config.target_root:
try:
return 1
else:
# A slot conflict has occurred.
+ # The existing node should not already be in
+ # runtime_pkg_mask, since that would trigger an
+ # infinite backtracking loop.
if self._dynamic_config._allow_backtracking and \
+ existing_node in \
+ self._dynamic_config._runtime_pkg_mask:
+ if "--debug" in self._frozen_config.myopts:
+ writemsg(
+ "!!! backtracking loop detected: %s %s\n" % \
+ (existing_node,
+ self._dynamic_config._runtime_pkg_mask[
+ existing_node]), noiselevel=-1)
+ elif self._dynamic_config._allow_backtracking and \
not self._accept_blocker_conflicts():
self._add_slot_conflict(pkg)
if dep.atom is not None and dep.parent is not None:
emerge --deep <pkgspec>; we need to recursively check dependencies of pkgspec
If we are in --nodeps (no recursion) mode, we obviously only check 1 level of dependencies.
"""
+ if arg_atoms:
+ depth = 0
+ pkg.depth = depth
+ deep = self._dynamic_config.myparams.get("deep", 0)
+ empty = "empty" in self._dynamic_config.myparams
+ recurse = empty or deep is True or depth + 1 <= deep
dep_stack = self._dynamic_config._dep_stack
if "recurse" not in self._dynamic_config.myparams:
return 1
- elif pkg.installed and \
- "deep" not in self._dynamic_config.myparams:
+ elif pkg.installed and not recurse:
dep_stack = self._dynamic_config._ignored_deps
self._frozen_config.spinner.update()
- if arg_atoms:
- depth = 0
- pkg.depth = depth
if not previously_added:
dep_stack.append(pkg)
return 1
# accounted for.
self._select_atoms = self._select_atoms_from_graph
self._select_package = self._select_pkg_from_graph
- already_deep = "deep" in self._dynamic_config.myparams
+ already_deep = self._dynamic_config.myparams.get("deep") is True
if not already_deep:
- self._dynamic_config.myparams.add("deep")
+ self._dynamic_config.myparams["deep"] = True
for root in self._frozen_config.roots:
required_set_names = self._frozen_config._required_set_names.copy()
if have_uninstall_task and \
not complete and \
not unsolvable_blockers:
- self._dynamic_config.myparams.add("complete")
+ self._dynamic_config.myparams["complete"] = True
raise self._serialize_tasks_retry("")
if unsolvable_blockers and \
self._dynamic_config._scheduler_graph = self._dynamic_config.digraph
else:
self._select_package = self._select_pkg_from_graph
- self._dynamic_config.myparams.add("selective")
+ self._dynamic_config.myparams["selective"] = True
# Always traverse deep dependencies in order to account for
# potentially unsatisfied dependencies of installed packages.
# This is necessary for correct --keep-going or --resume operation
# deep depenedencies of a scheduled build, that build needs to
# be cancelled. In order for this type of situation to be
# recognized, deep traversal of dependencies is required.
- self._dynamic_config.myparams.add("deep")
+ self._dynamic_config.myparams["deep"] = True
favorites = resume_data.get("favorites")
args_set = self._dynamic_config._sets["args"]
print " "+green("--update")+" ("+green("-u")+" short option)"
print " Updates packages to the best version available, which may not"
print " always be the highest version number due to masking for testing"
- print " and development. This will also update direct dependencies which"
- print " may not be what you want. Package atoms specified on the command"
+ print " and development. Package atoms specified on the command"
print " line are greedy, meaning that unspecific atoms may match multiple"
print " installed versions of slotted packages."
print
print " --debug is great for finding bash syntax errors as providing"
print " very verbose information about the dependency and build process."
print
- print " "+green("--deep")+" ("+green("-D")+" short option)"
+ print " "+green("--deep") + " " + turquoise("[DEPTH]") + \
+ " (" + green("-D") + " short option)"
print " This flag forces emerge to consider the entire dependency tree of"
print " packages, instead of checking only the immediate dependencies of"
print " the packages. As an example, this catches updates in libraries"
for line in wrap(desc, desc_width):
print desc_indent + line
print
+ print " " + green("--selective")
+ desc = "This is similar to the --noreplace option, except that it " + \
+ "does not take precedence over options such as --newuse."
+ for line in wrap(desc, desc_width):
+ print desc_indent + line
+ print
print " "+green("--skipfirst")
desc = "This option is only valid when " + \
"used with --resume. It removes the " + \
"--buildpkg", "--buildpkgonly",
"--changelog", "--columns",
"--complete-graph",
-"--debug", "--deep",
+"--debug",
"--digest",
"--emptytree",
"--fetchonly", "--fetch-all-uri",
"a":"--ask",
"b":"--buildpkg", "B":"--buildpkgonly",
"c":"--clean", "C":"--unmerge",
-"d":"--debug", "D":"--deep",
+"d":"--debug",
"e":"--emptytree",
"f":"--fetchonly", "F":"--fetch-all-uri",
"g":"--getbinpkg", "G":"--getbinpkgonly",
this feature natively.
"""
+ class valid_integers(object):
+ def __contains__(self, s):
+ try:
+ int(s)
+ except (ValueError, OverflowError):
+ return False
+ return True
+
+ valid_integers = valid_integers()
+
new_args = []
- jobs_opts = ("-j", "--jobs")
+
default_arg_opts = {
+ '--deep' : valid_integers,
'--deselect' : ('n',),
'--binpkg-respect-use' : ('n', 'y',),
+ '--jobs' : valid_integers,
'--root-deps' : ('rdeps',),
}
+
+ short_arg_opts = {
+ 'D' : valid_integers,
+ 'j' : valid_integers,
+ }
+
arg_stack = args[:]
arg_stack.reverse()
while arg_stack:
new_args.append('True')
continue
- short_job_opt = bool("j" in arg and arg[:1] == "-" and arg[:2] != "--")
- if not (short_job_opt or arg in jobs_opts):
+ if arg[:1] != "-" or arg[:2] == "--":
new_args.append(arg)
continue
+ match = None
+ for k, arg_choices in short_arg_opts.iteritems():
+ if k in arg:
+ match = k
+ break
+
+ if match is None:
+ new_args.append(arg)
+ continue
+
+ if len(arg) == 2:
+ new_args.append(arg)
+ if arg_stack and arg_stack[-1] in arg_choices:
+ new_args.append(arg_stack.pop())
+ else:
+ # insert default argument
+ new_args.append('True')
+ continue
+
# Insert an empty placeholder in order to
# satisfy the requirements of optparse.
- new_args.append("--jobs")
- job_count = None
+ new_args.append("-" + match)
+ opt_arg = None
saved_opts = None
- if short_job_opt and len(arg) > 2:
- if arg[:2] == "-j":
- try:
- job_count = int(arg[2:])
- except ValueError:
- saved_opts = arg[2:]
- else:
- job_count = "True"
- saved_opts = arg[1:].replace("j", "")
- if job_count is None and arg_stack:
- try:
- job_count = int(arg_stack[-1])
- except ValueError:
- pass
+ if arg[1:2] == match:
+ if arg[2:] in arg_choices:
+ opt_arg = arg[2:]
else:
- # Discard the job count from the stack
- # since we're consuming it here.
- arg_stack.pop()
+ saved_opts = arg[2:]
+ opt_arg = "True"
+ else:
+ saved_opts = arg[1:].replace(match, "")
+ opt_arg = "True"
- if job_count is None:
- # unlimited number of jobs
+ if opt_arg is None and arg_stack and \
+ arg_stack[-1] in arg_choices:
+ opt_arg = arg_stack.pop()
+
+ if opt_arg is None:
new_args.append("True")
else:
- new_args.append(str(job_count))
+ new_args.append(opt_arg)
if saved_opts is not None:
new_args.append("-" + saved_opts)
"choices":("y", "n")
},
+ "--deep": {
+
+ "shortopt" : "-D",
+
+ "help" : "Specifies how deep to recurse into dependencies " + \
+ "of packages given as arguments. If no argument is given, " + \
+ "depth is unlimited. Default behavior is to skip " + \
+ "dependencies of installed packages.",
+
+ "action" : "store"
+ },
+
"--deselect": {
"help" : "remove atoms from the world file",
"type" : "choice",
"--jobs": {
+ "shortopt" : "-j",
+
"help" : "Specifies the number of packages to build " + \
"simultaneously.",
dest=myopt.lstrip("--").replace("-", "_"), default=False)
for myopt, kwargs in argument_options.iteritems():
- parser.add_option(myopt,
- dest=myopt.lstrip("--").replace("-", "_"), **kwargs)
+ shortopt = kwargs.pop("shortopt", None)
+ args = [myopt]
+ if shortopt is not None:
+ args.append(shortopt)
+ parser.add_option(dest=myopt.lstrip("--").replace("-", "_"),
+ *args, **kwargs)
tmpcmdline = insert_optional_args(tmpcmdline)
if myoptions.root_deps == "True":
myoptions.root_deps = True
+ if myoptions.deep is not None:
+ deep = None
+ if myoptions.deep == "True":
+ deep = True
+ else:
+ try:
+ deep = int(myoptions.deep)
+ except (OverflowError, ValueError):
+ deep = -1
+
+ if deep is not True and deep < 0:
+ deep = None
+ if not silent:
+ writemsg("!!! Invalid --deep parameter: '%s'\n" % \
+ (myoptions.deep,), noiselevel=-1)
+
+ myoptions.deep = deep
+
if myoptions.jobs:
jobs = None
if myoptions.jobs == "True":
preferred_in_graph.append(this_choice)
else:
other.append(this_choice)
+ else:
+ preferred_in_graph.append(this_choice)
else:
preferred_non_installed.append(this_choice)
else: