It's useful to enable --with-bdeps by default 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.
X-Gentoo-bug: 598444 X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=598444 --- man/emerge.1 | 18 ++- pym/_emerge/create_depgraph_params.py | 4 + pym/_emerge/depgraph.py | 4 +- pym/portage/tests/resolver/ResolverPlayground.py | 5 + pym/portage/tests/resolver/test_bdeps.py | 197 +++++++++++++++++++++++ 5 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 pym/portage/tests/resolver/test_bdeps.py diff --git a/man/emerge.1 b/man/emerge.1 index 5b61220..970bb5b 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -986,9 +986,21 @@ 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 enabled automatically for +installation actions, meaning they will be installed, and is also enabled +automatically for the \fB\-\-depclean\fR action, meaning they will not be +removed. In order to prevent this option from being enabled automatically, +\fB\-\-with-bdeps=n\fR must be specified either in the command line or +via \fBEMERGE_DEFAULT_OPTS\fR. + +Since many users of binary packages do not want unnecessary build time +dependencies installed, this option is not enabled automatically 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. diff --git a/pym/_emerge/create_depgraph_params.py b/pym/_emerge/create_depgraph_params.py index 2c64928..676aac5 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,8 @@ def create_depgraph_params(myopts, myaction): bdeps = myopts.get("--with-bdeps") if bdeps is not None: myparams["bdeps"] = bdeps + elif myaction == "remove" or "--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 ce0fde1..02a3226 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/portage/tests/resolver/ResolverPlayground.py b/pym/portage/tests/resolver/ResolverPlayground.py index d1434f7..d803719 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 0000000..19159bd --- /dev/null +++ b/pym/portage/tests/resolver/test_bdeps.py @@ -0,0 +1,197 @@ +# 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"), + ] + ), + + # 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 for + # 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. + ResolverPlaygroundTestCase( + [], + options = { + "--depclean": True, + }, + 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() -- 2.10.2