1 # Copyright 1999-2013 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 from __future__ import print_function
10 portage.proxy.lazyimport.lazyimport(globals(),
13 'portage.util:writemsg_level',
15 '_emerge.actions:load_emerge_config,run_action,' + \
16 'validate_ebuild_environment',
17 '_emerge.help:help@emerge_help',
18 '_emerge.is_valid_package_atom:insert_category_into_atom'
20 from portage import os
21 from portage.util._argparse import ArgumentParser
23 if sys.hexversion >= 0x3000000:
28 "--ask-enter-invalid",
31 "--changelog", "--columns",
35 "--fetchonly", "--fetch-all-uri",
36 "--ignore-default-opts",
39 "--nodeps", "--noreplace",
40 "--nospinner", "--oneshot",
41 "--onlydeps", "--pretend",
42 "--quiet-repo-display",
43 "--quiet-unmerge-warn",
48 "--unordered-display",
50 "--verbose-main-repo-display",
60 "f":"--fetchonly", "F":"--fetch-all-uri",
63 "n":"--noreplace", "N":"--newuse",
64 "o":"--onlydeps", "O":"--nodeps",
65 "p":"--pretend", "P":"--prune",
67 "s":"--search", "S":"--searchdesc",
75 Larry loves Gentoo (%s)
77 _______________________
78 < Have you mooed today? >
79 -----------------------
88 def multiple_actions(action1, action2):
89 sys.stderr.write("\n!!! Multiple actions requested... Please choose one only.\n")
90 sys.stderr.write("!!! '%s' or '%s'\n\n" % (action1, action2))
93 def insert_optional_args(args):
95 Parse optional arguments and insert a value if one has
96 not been provided. This is done before feeding the args
97 to the optparse parser since that parser does not support
98 this feature natively.
101 class valid_integers(object):
102 def __contains__(self, s):
105 except (ValueError, OverflowError):
108 valid_integers = valid_integers()
110 class valid_floats(object):
111 def __contains__(self, s):
114 except (ValueError, OverflowError):
117 valid_floats = valid_floats()
125 '--autounmask' : y_or_n,
126 '--autounmask-keep-masks': y_or_n,
127 '--autounmask-unrestricted-atoms' : y_or_n,
128 '--autounmask-write' : y_or_n,
129 '--buildpkg' : y_or_n,
130 '--complete-graph' : y_or_n,
131 '--deep' : valid_integers,
132 '--depclean-lib-check' : y_or_n,
133 '--deselect' : y_or_n,
134 '--binpkg-respect-use' : y_or_n,
135 '--fail-clean' : y_or_n,
136 '--getbinpkg' : y_or_n,
137 '--getbinpkgonly' : y_or_n,
138 '--jobs' : valid_integers,
139 '--keep-going' : y_or_n,
140 '--load-average' : valid_floats,
141 '--package-moves' : y_or_n,
143 '--quiet-build' : y_or_n,
144 '--quiet-fail' : y_or_n,
145 '--rebuild-if-new-slot': y_or_n,
146 '--rebuild-if-new-rev' : y_or_n,
147 '--rebuild-if-new-ver' : y_or_n,
148 '--rebuild-if-unbuilt' : y_or_n,
149 '--rebuilt-binaries' : y_or_n,
150 '--root-deps' : ('rdeps',),
152 '--selective' : y_or_n,
153 "--use-ebuild-visibility": y_or_n,
155 '--usepkgonly' : y_or_n,
156 '--verbose' : y_or_n,
160 'D' : valid_integers,
161 'j' : valid_integers,
164 # Don't make things like "-kn" expand to "-k n"
165 # since existence of -n makes it too ambiguous.
181 arg = arg_stack.pop()
183 default_arg_choices = default_arg_opts.get(arg)
184 if default_arg_choices is not None:
186 if arg_stack and arg_stack[-1] in default_arg_choices:
187 new_args.append(arg_stack.pop())
189 # insert default argument
190 new_args.append('True')
193 if arg[:1] != "-" or arg[:2] == "--":
198 for k, arg_choices in short_arg_opts.items():
204 for k, arg_choices in short_arg_opts_n.items():
215 if arg_stack and arg_stack[-1] in arg_choices:
216 new_args.append(arg_stack.pop())
218 # insert default argument
219 new_args.append('True')
222 # Insert an empty placeholder in order to
223 # satisfy the requirements of optparse.
225 new_args.append("-" + match)
229 if arg[1:2] == match:
230 if match not in short_arg_opts_n and arg[2:] in arg_choices:
236 saved_opts = arg[1:].replace(match, "")
239 if opt_arg is None and arg_stack and \
240 arg_stack[-1] in arg_choices:
241 opt_arg = arg_stack.pop()
244 new_args.append("True")
246 new_args.append(opt_arg)
248 if saved_opts is not None:
249 # Recycle these on arg_stack since they
250 # might contain another match.
251 arg_stack.append("-" + saved_opts)
255 def _find_bad_atoms(atoms, less_strict=False):
257 Declares all atoms as invalid that have an operator,
258 a use dependency, a blocker or a repo spec.
259 It accepts atoms with wildcards.
260 In less_strict mode it accepts operators and repo specs.
263 for x in ' '.join(atoms).split():
265 if "/" not in x.split(":")[0]:
266 x_cat = insert_category_into_atom(x, 'dummy-category')
267 if x_cat is not None:
272 atom = Atom(atom, allow_wildcard=True, allow_repo=less_strict)
273 except portage.exception.InvalidAtom:
276 if bad_atom or (atom.operator and not less_strict) or atom.blocker or atom.use:
281 def parse_opts(tmpcmdline, silent=False):
286 actions = frozenset([
287 "clean", "check-news", "config", "depclean", "help",
288 "info", "list-sets", "metadata", "moo",
289 "prune", "regen", "search",
290 "sync", "unmerge", "version",
293 longopt_aliases = {"--cols":"--columns", "--skip-first":"--skipfirst"}
295 true_y_or_n = ("True", "y", "n")
296 true_y = ("True", "y")
301 "help" : "prompt before performing any actions",
302 "choices" : true_y_or_n
306 "help" : "automatically unmask packages",
307 "choices" : true_y_or_n
310 "--autounmask-unrestricted-atoms": {
311 "help" : "write autounmask changes with >= atoms if possible",
312 "choices" : true_y_or_n
315 "--autounmask-keep-masks": {
316 "help" : "don't add package.unmask entries",
317 "choices" : true_y_or_n
320 "--autounmask-write": {
321 "help" : "write changes made by --autounmask to disk",
322 "choices" : true_y_or_n
325 "--accept-properties": {
326 "help":"temporarily override ACCEPT_PROPERTIES",
330 "--accept-restrict": {
331 "help":"temporarily override ACCEPT_RESTRICT",
337 "help" : "Specifies how many times to backtrack if dependency " + \
338 "calculation fails ",
345 "help" : "build binary packages",
346 "choices" : true_y_or_n
349 "--buildpkg-exclude": {
350 "help" :"A space separated list of package atoms for which " + \
351 "no binary packages should be built. This option overrides all " + \
352 "possible ways to enable building of binary packages.",
358 "help":"specify the location for portage configuration files",
362 "help":"enable or disable color output",
366 "--complete-graph": {
367 "help" : "completely account for all known dependencies",
368 "choices" : true_y_or_n
371 "--complete-graph-if-new-use": {
372 "help" : "trigger --complete-graph behavior if USE or IUSE will change for an installed package",
376 "--complete-graph-if-new-ver": {
377 "help" : "trigger --complete-graph behavior if an installed package version will change (upgrade or downgrade)",
385 "help" : "Specifies how deep to recurse into dependencies " + \
386 "of packages given as arguments. If no argument is given, " + \
387 "depth is unlimited. Default behavior is to skip " + \
388 "dependencies of installed packages.",
393 "--depclean-lib-check": {
394 "help" : "check for consumers of libraries before removing them",
395 "choices" : true_y_or_n
399 "help" : "remove atoms/sets from the world file",
400 "choices" : true_y_or_n
404 "help": "substitute the dependencies of installed packages with the dependencies of unbuilt ebuilds",
409 "help" :"A space separated list of package names or slot atoms. " + \
410 "Emerge won't install any ebuild or binary package that " + \
411 "matches any of the given package atoms.",
417 "help" : "clean temp files after build failure",
418 "choices" : true_y_or_n
421 "--ignore-built-slot-operator-deps": {
422 "help": "Ignore the slot/sub-slot := operator parts of dependencies that have "
423 "been recorded when packages where built. This option is intended "
424 "only for debugging purposes, and it only affects built packages "
425 "that specify slot/sub-slot := operator dependencies using the "
426 "experimental \"4-slot-abi\" EAPI.",
434 "help" : "Specifies the number of packages to build " + \
441 "help" : "continue as much as possible after an error",
442 "choices" : true_y_or_n
447 "help" :"Specifies that no new builds should be started " + \
448 "if there are other builds running and the load average " + \
449 "is at least LOAD (a floating-point number).",
454 "--misspell-suggestions": {
455 "help" : "enable package name misspell suggestions",
456 "choices" : ("y", "n")
460 "help":"include unnecessary build time dependencies",
464 "help":"specify conditions to trigger package reinstallation",
465 "choices":["changed-use"]
468 "--reinstall-atoms": {
469 "help" :"A space separated list of package names or slot atoms. " + \
470 "Emerge will treat matching packages as if they are not " + \
471 "installed, and reinstall them if necessary. Implies --deep.",
476 "--binpkg-respect-use": {
477 "help" : "discard binary packages if their use flags \
478 don't match the current configuration",
479 "choices" : true_y_or_n
484 "help" : "fetch binary packages",
485 "choices" : true_y_or_n
490 "help" : "fetch binary packages only",
491 "choices" : true_y_or_n
494 "--usepkg-exclude": {
495 "help" :"A space separated list of package names or slot atoms. " + \
496 "Emerge will ignore matching binary packages. ",
501 "--rebuild-exclude": {
502 "help" :"A space separated list of package names or slot atoms. " + \
503 "Emerge will not rebuild these packages due to the " + \
509 "--rebuild-ignore": {
510 "help" :"A space separated list of package names or slot atoms. " + \
511 "Emerge will not rebuild packages that depend on matching " + \
512 "packages due to the --rebuild flag. ",
518 "help" : "perform package moves when necessary",
519 "choices" : true_y_or_n
523 "help" : "specify the installation prefix",
528 "help" : "format of result binary package",
534 "help" : "reduced or condensed output",
535 "choices" : true_y_or_n
539 "help" : "redirect build output to logs",
540 "choices" : true_y_or_n,
544 "help" : "suppresses display of the build log on stdout",
545 "choices" : true_y_or_n,
548 "--rebuild-if-new-slot": {
549 "help" : ("Automatically rebuild or reinstall packages when slot/sub-slot := "
550 "operator dependencies can be satisfied by a newer slot, so that "
551 "older packages slots will become eligible for removal by the "
552 "--depclean action as soon as possible."),
553 "choices" : true_y_or_n
556 "--rebuild-if-new-rev": {
557 "help" : "Rebuild packages when dependencies that are " + \
558 "used at both build-time and run-time are built, " + \
559 "if the dependency is not already installed with the " + \
560 "same version and revision.",
561 "choices" : true_y_or_n
564 "--rebuild-if-new-ver": {
565 "help" : "Rebuild packages when dependencies that are " + \
566 "used at both build-time and run-time are built, " + \
567 "if the dependency is not already installed with the " + \
568 "same version. Revision numbers are ignored.",
569 "choices" : true_y_or_n
572 "--rebuild-if-unbuilt": {
573 "help" : "Rebuild packages when dependencies that are " + \
574 "used at both build-time and run-time are built.",
575 "choices" : true_y_or_n
578 "--rebuilt-binaries": {
579 "help" : "replace installed packages with binary " + \
580 "packages that have been rebuilt",
581 "choices" : true_y_or_n
584 "--rebuilt-binaries-timestamp": {
585 "help" : "use only binaries that are newer than this " + \
586 "timestamp for --rebuilt-binaries",
591 "help" : "specify the target root filesystem for merging packages",
596 "help" : "modify interpretation of depedencies",
597 "choices" :("True", "rdeps")
602 "help" : "add specified packages to the world set " + \
603 "(inverse of --oneshot)",
604 "choices" : true_y_or_n
608 "help" : "identical to --noreplace",
609 "choices" : true_y_or_n
612 "--use-ebuild-visibility": {
613 "help" : "use unbuilt ebuild metadata for visibility checks on built packages",
614 "choices" : true_y_or_n
617 "--useoldpkg-atoms": {
618 "help" :"A space separated list of package names or slot atoms. " + \
619 "Emerge will prefer matching binary packages over newer unbuilt packages. ",
626 "help" : "use binary packages",
627 "choices" : true_y_or_n
632 "help" : "use only binary packages",
633 "choices" : true_y_or_n
638 "help" : "verbose output",
639 "choices" : true_y_or_n
643 parser = ArgumentParser(add_help=False)
645 for action_opt in actions:
646 parser.add_argument("--" + action_opt, action="store_true",
647 dest=action_opt.replace("-", "_"), default=False)
648 for myopt in options:
649 parser.add_argument(myopt, action="store_true",
650 dest=myopt.lstrip("--").replace("-", "_"), default=False)
651 for shortopt, longopt in shortmapping.items():
652 parser.add_argument("-" + shortopt, action="store_true",
653 dest=longopt.lstrip("--").replace("-", "_"), default=False)
654 for myalias, myopt in longopt_aliases.items():
655 parser.add_argument(myalias, action="store_true",
656 dest=myopt.lstrip("--").replace("-", "_"), default=False)
658 for myopt, kwargs in argument_options.items():
659 shortopt = kwargs.pop("shortopt", None)
661 if shortopt is not None:
662 args.append(shortopt)
663 parser.add_argument(dest=myopt.lstrip("--").replace("-", "_"),
666 tmpcmdline = insert_optional_args(tmpcmdline)
668 myoptions, myargs = parser.parse_known_args(args=tmpcmdline)
670 if myoptions.ask in true_y:
675 if myoptions.autounmask in true_y:
676 myoptions.autounmask = True
678 if myoptions.autounmask_unrestricted_atoms in true_y:
679 myoptions.autounmask_unrestricted_atoms = True
681 if myoptions.autounmask_keep_masks in true_y:
682 myoptions.autounmask_keep_masks = True
684 if myoptions.autounmask_write in true_y:
685 myoptions.autounmask_write = True
687 if myoptions.buildpkg in true_y:
688 myoptions.buildpkg = True
690 if myoptions.buildpkg_exclude:
691 bad_atoms = _find_bad_atoms(myoptions.buildpkg_exclude, less_strict=True)
692 if bad_atoms and not silent:
693 parser.error("Invalid Atom(s) in --buildpkg-exclude parameter: '%s'\n" % \
694 (",".join(bad_atoms),))
696 if myoptions.changed_use is not False:
697 myoptions.reinstall = "changed-use"
698 myoptions.changed_use = False
700 if myoptions.deselect in true_y:
701 myoptions.deselect = True
703 if myoptions.binpkg_respect_use is not None:
704 if myoptions.binpkg_respect_use in true_y:
705 myoptions.binpkg_respect_use = 'y'
707 myoptions.binpkg_respect_use = 'n'
709 if myoptions.complete_graph in true_y:
710 myoptions.complete_graph = True
712 myoptions.complete_graph = None
714 if myoptions.depclean_lib_check in true_y:
715 myoptions.depclean_lib_check = True
717 if myoptions.exclude:
718 bad_atoms = _find_bad_atoms(myoptions.exclude)
719 if bad_atoms and not silent:
720 parser.error("Invalid Atom(s) in --exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
721 (",".join(bad_atoms),))
723 if myoptions.reinstall_atoms:
724 bad_atoms = _find_bad_atoms(myoptions.reinstall_atoms)
725 if bad_atoms and not silent:
726 parser.error("Invalid Atom(s) in --reinstall-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
727 (",".join(bad_atoms),))
729 if myoptions.rebuild_exclude:
730 bad_atoms = _find_bad_atoms(myoptions.rebuild_exclude)
731 if bad_atoms and not silent:
732 parser.error("Invalid Atom(s) in --rebuild-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
733 (",".join(bad_atoms),))
735 if myoptions.rebuild_ignore:
736 bad_atoms = _find_bad_atoms(myoptions.rebuild_ignore)
737 if bad_atoms and not silent:
738 parser.error("Invalid Atom(s) in --rebuild-ignore parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
739 (",".join(bad_atoms),))
741 if myoptions.usepkg_exclude:
742 bad_atoms = _find_bad_atoms(myoptions.usepkg_exclude)
743 if bad_atoms and not silent:
744 parser.error("Invalid Atom(s) in --usepkg-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
745 (",".join(bad_atoms),))
747 if myoptions.useoldpkg_atoms:
748 bad_atoms = _find_bad_atoms(myoptions.useoldpkg_atoms)
749 if bad_atoms and not silent:
750 parser.error("Invalid Atom(s) in --useoldpkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
751 (",".join(bad_atoms),))
753 if myoptions.fail_clean in true_y:
754 myoptions.fail_clean = True
756 if myoptions.getbinpkg in true_y:
757 myoptions.getbinpkg = True
759 myoptions.getbinpkg = None
761 if myoptions.getbinpkgonly in true_y:
762 myoptions.getbinpkgonly = True
764 myoptions.getbinpkgonly = None
766 if myoptions.keep_going in true_y:
767 myoptions.keep_going = True
769 myoptions.keep_going = None
771 if myoptions.package_moves in true_y:
772 myoptions.package_moves = True
774 if myoptions.quiet in true_y:
775 myoptions.quiet = True
777 myoptions.quiet = None
779 if myoptions.quiet_build in true_y:
780 myoptions.quiet_build = 'y'
782 if myoptions.quiet_fail in true_y:
783 myoptions.quiet_fail = 'y'
785 if myoptions.rebuild_if_new_slot in true_y:
786 myoptions.rebuild_if_new_slot = 'y'
788 if myoptions.rebuild_if_new_ver in true_y:
789 myoptions.rebuild_if_new_ver = True
791 myoptions.rebuild_if_new_ver = None
793 if myoptions.rebuild_if_new_rev in true_y:
794 myoptions.rebuild_if_new_rev = True
795 myoptions.rebuild_if_new_ver = None
797 myoptions.rebuild_if_new_rev = None
799 if myoptions.rebuild_if_unbuilt in true_y:
800 myoptions.rebuild_if_unbuilt = True
801 myoptions.rebuild_if_new_rev = None
802 myoptions.rebuild_if_new_ver = None
804 myoptions.rebuild_if_unbuilt = None
806 if myoptions.rebuilt_binaries in true_y:
807 myoptions.rebuilt_binaries = True
809 if myoptions.root_deps in true_y:
810 myoptions.root_deps = True
812 if myoptions.select in true_y:
813 myoptions.select = True
814 myoptions.oneshot = False
815 elif myoptions.select == "n":
816 myoptions.oneshot = True
818 if myoptions.selective in true_y:
819 myoptions.selective = True
821 if myoptions.backtrack is not None:
824 backtrack = int(myoptions.backtrack)
825 except (OverflowError, ValueError):
831 parser.error("Invalid --backtrack parameter: '%s'\n" % \
832 (myoptions.backtrack,))
834 myoptions.backtrack = backtrack
836 if myoptions.deep is not None:
838 if myoptions.deep == "True":
842 deep = int(myoptions.deep)
843 except (OverflowError, ValueError):
846 if deep is not True and deep < 0:
849 parser.error("Invalid --deep parameter: '%s'\n" % \
852 myoptions.deep = deep
856 if myoptions.jobs == "True":
860 jobs = int(myoptions.jobs)
864 if jobs is not True and \
868 parser.error("Invalid --jobs parameter: '%s'\n" % \
871 myoptions.jobs = jobs
873 if myoptions.load_average == "True":
874 myoptions.load_average = None
876 if myoptions.load_average:
878 load_average = float(myoptions.load_average)
882 if load_average <= 0.0:
885 parser.error("Invalid --load-average parameter: '%s'\n" % \
886 (myoptions.load_average,))
888 myoptions.load_average = load_average
890 if myoptions.rebuilt_binaries_timestamp:
892 rebuilt_binaries_timestamp = int(myoptions.rebuilt_binaries_timestamp)
894 rebuilt_binaries_timestamp = -1
896 if rebuilt_binaries_timestamp < 0:
897 rebuilt_binaries_timestamp = 0
899 parser.error("Invalid --rebuilt-binaries-timestamp parameter: '%s'\n" % \
900 (myoptions.rebuilt_binaries_timestamp,))
902 myoptions.rebuilt_binaries_timestamp = rebuilt_binaries_timestamp
904 if myoptions.use_ebuild_visibility in true_y:
905 myoptions.use_ebuild_visibility = True
910 if myoptions.usepkg in true_y:
911 myoptions.usepkg = True
913 myoptions.usepkg = None
915 if myoptions.usepkgonly in true_y:
916 myoptions.usepkgonly = True
918 myoptions.usepkgonly = None
920 if myoptions.verbose in true_y:
921 myoptions.verbose = True
923 myoptions.verbose = None
925 for myopt in options:
926 v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"))
930 for myopt in argument_options:
931 v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"), None)
935 if myoptions.searchdesc:
936 myoptions.search = True
938 for action_opt in actions:
939 v = getattr(myoptions, action_opt.replace("-", "_"))
942 multiple_actions(myaction, action_opt)
944 myaction = action_opt
946 if myaction is None and myoptions.deselect is True:
947 myaction = 'deselect'
951 return myaction, myopts, myfiles
953 def profile_check(trees, myaction):
954 if myaction in ("help", "info", "search", "sync", "version"):
956 for root_trees in trees.values():
957 if root_trees["root_config"].settings.profiles:
959 # generate some profile related warning messages
960 validate_ebuild_environment(trees)
961 msg = ("Your current profile is invalid. If you have just changed "
962 "your profile configuration, you should revert back to the "
963 "previous configuration. Allowed actions are limited to "
964 "--help, --info, --search, --sync, and --version.")
965 writemsg_level("".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)),
966 level=logging.ERROR, noiselevel=-1)
970 def emerge_main(args=None):
972 @param args: command arguments (default: sys.argv[1:])
978 args = portage._decode_argv(args)
980 # Disable color until we're sure that it should be enabled (after
981 # EMERGE_DEFAULT_OPTS has been parsed).
982 portage.output.havecolor = 0
984 # This first pass is just for options that need to be known as early as
985 # possible, such as --config-root. They will be parsed again later,
986 # together with EMERGE_DEFAULT_OPTS (which may vary depending on the
987 # the value of --config-root).
988 myaction, myopts, myfiles = parse_opts(args, silent=True)
989 if "--debug" in myopts:
990 os.environ["PORTAGE_DEBUG"] = "1"
991 if "--config-root" in myopts:
992 os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
993 if "--root" in myopts:
994 os.environ["ROOT"] = myopts["--root"]
995 if "--prefix" in myopts:
996 os.environ["EPREFIX"] = myopts["--prefix"]
997 if "--accept-properties" in myopts:
998 os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
999 if "--accept-restrict" in myopts:
1000 os.environ["ACCEPT_RESTRICT"] = myopts["--accept-restrict"]
1002 # optimize --help (no need to load config / EMERGE_DEFAULT_OPTS)
1003 if myaction == "help":
1006 elif myaction == "moo":
1007 print(COWSAY_MOO % platform.system())
1010 # Portage needs to ensure a sane umask for the files it creates.
1012 if myaction == "sync":
1013 portage._sync_disabled_warnings = True
1014 emerge_config = load_emerge_config(
1015 action=myaction, args=myfiles, opts=myopts)
1016 rval = profile_check(emerge_config.trees, emerge_config.action)
1017 if rval != os.EX_OK:
1021 if "--ignore-default-opts" not in myopts:
1022 tmpcmdline.extend(portage.util.shlex_split(
1023 emerge_config.target_config.settings.get(
1024 "EMERGE_DEFAULT_OPTS", "")))
1025 tmpcmdline.extend(args)
1026 emerge_config.action, emerge_config.opts, emerge_config.args = \
1027 parse_opts(tmpcmdline)
1030 return run_action(emerge_config)
1032 # Call destructors for our portdbapi instances.
1033 for x in emerge_config.trees.values():
1034 if "porttree" in x.lazy_items:
1036 x["porttree"].dbapi.close_caches()