commit: 852c729bdef3d4c2e2d459a43dc21f0a05dfa2ba Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sat Mar 4 06:24:21 2017 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Wed Mar 8 19:19:53 2017 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=852c729b
emerge: auto-enable --with-bdeps if --usepkg is not enabled (bug 598444) It's useful to automatically enable --with-bdeps so that @world updates will update all packages that are not eligible for removal by emerge --depclean. However, many users of binary packages do not want unnecessary build time dependencies installed, therefore do not auto-enable --with-bdeps for installation actions when the --usepkg option is enabled. A new --with-bdeps-auto=<y|n> option is provided, making it possible to enable or disable the program logic that causes --with-bdeps to be automatically enabled. Use --with-bdeps-auto=n to prevent --with-bdeps from being automatically enabled for installation actions. This is useful for some rare cases in which --with-bdeps triggers unsolvable dependency conflicts (and putting --with-bdeps=n in EMERGE_DEFAULT_OPTS would cause undesirable --depclean behavior). X-Gentoo-bug: 598444 X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=598444 Acked-by: Brian Dolbec <dolsen <AT> gentoo.org> man/emerge.1 | 37 +++- pym/_emerge/create_depgraph_params.py | 5 + pym/_emerge/depgraph.py | 4 +- pym/_emerge/main.py | 5 + pym/portage/tests/resolver/ResolverPlayground.py | 5 + pym/portage/tests/resolver/test_bdeps.py | 215 +++++++++++++++++++++++ 6 files changed, 266 insertions(+), 5 deletions(-) diff --git a/man/emerge.1 b/man/emerge.1 index 5b6122023..7db427199 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -986,13 +986,44 @@ The default is set to "y" (on). .TP .BR "\-\-with\-bdeps < y | n >" In dependency calculations, pull in build time dependencies -that are not strictly required. This defaults to \'n\' for -installation actions, meaning they will not be installed, and -\'y\' for the \fB\-\-depclean\fR action, meaning they will not be removed. +that are not strictly required. This option is automatically enabled for +installation actions, meaning they will be installed, and defaults to +\(aqy\(aq for the \fB\-\-depclean\fR action, meaning they will not be +removed. In order to prevent the \fB\-\-with\-bdeps\fR option from being +automatically enabled for installation actions, specify +\fB\-\-with\-bdeps\-auto=n\fR in either the command line or +\fBEMERGE_DEFAULT_OPTS\fR. + +Since many users of binary packages do not want unnecessary build time +dependencies installed, this option is not automatically enabled for +installation actions when the \fB\-\-usepkg\fR option is enabled. In +order to pull in build time dependencies for binary packages with +\fB\-\-usepkg\fR, \fB\-\-with\-bdeps=y\fR must be specified explicitly. +This also applies to options that enable the \fB\-\-usepkg\fR option +implicitly, such as \fB\-\-getbinpkg\fR. + This setting can be added to \fBEMERGE_DEFAULT_OPTS\fR (see make.conf(5)) and later overridden via the command line. .TP +.BR "\-\-with\-bdeps\-auto < y | n >" +This option is used to enable or disable the program logic that causes +\fB\-\-with\-bdeps\fR is to be automatically enabled for installation +actions. This option is enabled by default. Use +\fB\-\-with\-bdeps\-auto=n\fR to prevent \fB\-\-with\-bdeps\fR from +being automatically enabled for installation actions. This setting can +be added to \fBEMERGE_DEFAULT_OPTS\fR (see make.conf(5)) and later +overridden via the command line. + +\fBNOTE:\fR The program logic that causes \fB\-\-with\-bdeps\fR to be +automatically enabled for installation actions does not affect removal +actions such as the \fB\-\-depclean\fR action. Therefore, when +\fB\-\-with\-bdeps\-auto=n\fR is specified in \fBEMERGE_DEFAULT_OPTS\fR, +it does not affect the default \fB\-\-with\-bdeps=y\fR setting that +applies to the \fB\-\-depclean\fR action. The default +\fB\-\-with\-bdeps=y\fR setting that applies to the \fB\-\-depclean\fR +action can be overridden only by specifying \fB\-\-with\-bdeps=n\fR. +.TP .BR "\-\-with\-test\-deps [ y | n ]" For packages matched by arguments, this option will pull in dependencies that are conditional on the "test" USE flag, even if "test" is not diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py index 2c6492883..cdea029ba 100644 --- a/pym/_emerge/create_depgraph_params.py +++ b/pym/_emerge/create_depgraph_params.py @@ -13,6 +13,8 @@ def create_depgraph_params(myopts, myaction): # deep: go into the dependencies of already merged packages # empty: pretend nothing is merged # complete: completely account for all known dependencies + # bdeps: satisfy build time dependencies of packages that are + # already built, even though they are not strictly required # remove: build graph for use in removing packages # rebuilt_binaries: replace installed packages with rebuilt binaries # rebuild_if_new_slot: rebuild or reinstall packages when @@ -32,6 +34,9 @@ def create_depgraph_params(myopts, myaction): bdeps = myopts.get("--with-bdeps") if bdeps is not None: myparams["bdeps"] = bdeps + elif myaction == "remove" or ( + myopts.get("--with-bdeps-auto") != "n" and "--usepkg" not in myopts): + myparams["bdeps"] = "auto" ignore_built_slot_operator_deps = myopts.get("--ignore-built-slot-operator-deps") if ignore_built_slot_operator_deps is not None: diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index ce0fde156..02a32260a 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2362,7 +2362,7 @@ class depgraph(object): if ebuild is None: changed = False else: - if self._dynamic_config.myparams.get("bdeps", "n") == "y": + if self._dynamic_config.myparams.get("bdeps") in ("y", "auto"): depvars = Package._dep_keys else: depvars = Package._runtime_keys @@ -2998,7 +2998,7 @@ class depgraph(object): ignore_build_time_deps = False if pkg.built and not removal_action: - if self._dynamic_config.myparams.get("bdeps", "n") == "y": + if self._dynamic_config.myparams.get("bdeps") in ("y", "auto"): # Pull in build time deps as requested, but marked them as # "optional" since they are not strictly required. This allows # more freedom in the merge order calculation for solving diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index a83b328aa..76e963ac9 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -516,6 +516,11 @@ def parse_opts(tmpcmdline, silent=False): "help":"include unnecessary build time dependencies", "choices":("y", "n") }, + "--with-bdeps-auto": { + "help":("automatically enable --with-bdeps for installation" + " actions, unless --usepkg is enabled"), + "choices":("y", "n") + }, "--reinstall": { "help":"specify conditions to trigger package reinstallation", "choices":["changed-use"] diff --git a/pym/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py index d1434f724..d8037194b 100644 --- a/pym/portage/tests/resolver/ResolverPlayground.py +++ b/pym/portage/tests/resolver/ResolverPlayground.py @@ -558,6 +558,7 @@ class ResolverPlaygroundTestCase(object): def __init__(self, request, **kwargs): self.all_permutations = kwargs.pop("all_permutations", False) self.ignore_mergelist_order = kwargs.pop("ignore_mergelist_order", False) + self.ignore_cleanlist_order = kwargs.pop("ignore_cleanlist_order", False) self.ambiguous_merge_order = kwargs.pop("ambiguous_merge_order", False) self.ambiguous_slot_collision_solutions = kwargs.pop("ambiguous_slot_collision_solutions", False) self.check_repo_names = kwargs.pop("check_repo_names", False) @@ -675,6 +676,10 @@ class ResolverPlaygroundTestCase(object): str((node1, node2))) + \ ", got: " + str(got)) + elif key == "cleanlist" and self.ignore_cleanlist_order: + got = set(got) + expected = set(expected) + elif key == "slot_collision_solutions" and \ self.ambiguous_slot_collision_solutions: # Tests that use all_permutations can have multiple diff --git a/pym/portage/tests/resolver/test_bdeps.py b/pym/portage/tests/resolver/test_bdeps.py new file mode 100644 index 000000000..c0d64991c --- /dev/null +++ b/pym/portage/tests/resolver/test_bdeps.py @@ -0,0 +1,215 @@ +# Copyright 2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import ( + ResolverPlayground, + ResolverPlaygroundTestCase, +) + +class BdepsTestCase(TestCase): + + def testImageMagickUpdate(self): + + ebuilds = { + "app-misc/A-1" : { + "EAPI": "6", + "DEPEND": "app-misc/B", + "RDEPEND": "app-misc/C", + }, + + "app-misc/B-1" : { + "EAPI": "6" + }, + "app-misc/B-2" : { + "EAPI": "6", + }, + + "app-misc/C-1" : { + "EAPI": "6", + "DEPEND": "app-misc/D", + }, + "app-misc/C-2" : { + "EAPI": "6", + "DEPEND": "app-misc/D", + }, + + "app-misc/D-1" : { + "EAPI": "6", + }, + "app-misc/D-2" : { + "EAPI": "6", + }, + } + + installed = { + "app-misc/A-1" : { + "EAPI": "6", + "DEPEND": "app-misc/B", + "RDEPEND": "app-misc/C", + }, + + "app-misc/B-1" : { + "EAPI": "6", + }, + "app-misc/C-1" : { + "EAPI": "6", + "DEPEND": "app-misc/D", + }, + + "app-misc/D-1" : { + "EAPI": "6", + }, + } + + binpkgs = { + "app-misc/A-1" : { + "EAPI": "6", + "DEPEND": "app-misc/B", + "RDEPEND": "app-misc/C", + }, + + "app-misc/B-1" : { + "EAPI": "6", + }, + "app-misc/B-2" : { + "EAPI": "6", + }, + + "app-misc/C-1" : { + "EAPI": "6", + "DEPEND": "app-misc/D", + }, + "app-misc/C-2" : { + "EAPI": "6", + "DEPEND": "app-misc/D", + }, + + "app-misc/D-1" : { + "EAPI": "6", + }, + "app-misc/D-2" : { + "EAPI": "6", + }, + } + + world = ( + "app-misc/A", + ) + + test_cases = ( + + # Enable --with-bdeps automatically when + # --usepkg has not been specified. + ResolverPlaygroundTestCase( + ["@world"], + options = { + "--update": True, + "--deep": True, + }, + success = True, + ambiguous_merge_order = True, + mergelist = [ + "app-misc/D-2", + ("app-misc/B-2", "app-misc/C-2"), + ] + ), + + # Use --with-bdeps-auto=n to prevent --with-bdeps + # from being enabled automatically. + ResolverPlaygroundTestCase( + ["@world"], + options = { + "--update": True, + "--deep": True, + "--with-bdeps-auto": "n", + }, + success = True, + mergelist = [ + "app-misc/D-2", + "app-misc/C-2", + ] + ), + + # Do not enable --with-bdeps automatically when + # --usepkg has been specified, since many users of binary + # packages do not want unnecessary build time dependencies + # installed. In this case we miss an update to + # app-misc/D-2, since DEPEND is not pulled in for + # the [binary]app-misc/C-2 update. + ResolverPlaygroundTestCase( + ["@world"], + options = { + "--update": True, + "--deep": True, + "--usepkg": True, + }, + success = True, + mergelist = [ + "[binary]app-misc/C-2", + ] + ), + + # Use --with-bdeps=y to pull in build-time dependencies of + # binary packages. + ResolverPlaygroundTestCase( + ["@world"], + options = { + "--update": True, + "--deep": True, + "--usepkg": True, + "--with-bdeps": "y", + }, + success = True, + ambiguous_merge_order = True, + mergelist = [ + ( + "[binary]app-misc/D-2", + "[binary]app-misc/B-2", + "[binary]app-misc/C-2", + ), + ] + ), + + # For --depclean, do not remove build-time dependencies by + # default. Specify --with-bdeps-auto=n, in order to + # demonstrate that it does not affect removal actions. + ResolverPlaygroundTestCase( + [], + options = { + "--depclean": True, + "--with-bdeps-auto": "n", + }, + success = True, + cleanlist = [], + ), + + # For --depclean, remove build-time dependencies if + # --with-bdeps=n has been specified. + ResolverPlaygroundTestCase( + [], + options = { + "--depclean": True, + "--with-bdeps": "n", + }, + success = True, + ignore_cleanlist_order = True, + cleanlist = [ + "app-misc/D-1", + "app-misc/B-1", + ], + ), + ) + + playground = ResolverPlayground(debug=False, + ebuilds=ebuilds, installed=installed, + binpkgs=binpkgs, world=world) + try: + for test_case in test_cases: + playground.run_TestCase(test_case) + self.assertEqual(test_case.test_success, True, + test_case.fail_msg) + finally: + # Disable debug so that cleanup works. + playground.debug = False + playground.cleanup()