diff options
author | 2010-08-08 15:35:02 +0100 | |
---|---|---|
committer | 2010-08-08 15:35:02 +0100 | |
commit | b4ab443375d5f8848e4084cd408dbb753fcaf771 (patch) | |
tree | 08400dc71612a36ebd6ffb5e0862bd5514d073cf | |
parent | 391a11571d99f0b9ccb030381c32dd9a36721f37 (diff) | |
download | paludis-b4ab443375d5f8848e4084cd408dbb753fcaf771.tar.gz paludis-b4ab443375d5f8848e4084cd408dbb753fcaf771.tar.xz |
GetResolventsForHelper
-rw-r--r-- | paludis/resolver/Makefile.am | 4 | ||||
-rw-r--r-- | paludis/resolver/get_resolvents_for_helper-fwd.hh | 31 | ||||
-rw-r--r-- | paludis/resolver/get_resolvents_for_helper.cc | 302 | ||||
-rw-r--r-- | paludis/resolver/get_resolvents_for_helper.hh | 63 | ||||
-rw-r--r-- | paludis/resolver/reason_utils-fwd.hh | 35 | ||||
-rw-r--r-- | paludis/resolver/reason_utils.cc | 78 | ||||
-rw-r--r-- | paludis/resolver/reason_utils.hh | 33 | ||||
-rw-r--r-- | paludis/resolver/resolver_test.cc | 26 | ||||
-rw-r--r-- | paludis/resolver/resolver_test.hh | 8 | ||||
-rw-r--r-- | src/clients/cave/resolve_common.cc | 141 |
10 files changed, 625 insertions, 96 deletions
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am index b49ff50..db679d8 100644 --- a/paludis/resolver/Makefile.am +++ b/paludis/resolver/Makefile.am @@ -49,6 +49,7 @@ noinst_HEADERS = \ get_constraints_for_purge_helper.hh get_constraints_for_dependent_helper-fwd.hh \ get_constraints_for_via_binary_helper.hh get_constraints_for_via_binary_helper-fwd.hh \ get_destination_types_for_error_helper.hh get_destination_types_for_error_helper-fwd.hh \ + get_resolvents_for_helper.hh get_resolvents_for_helper-fwd.hh \ get_use_existing_nothing_helper.hh get_use_existing_nothing_helper-fwd.hh \ interest_in_spec_helper.hh interest_in_spec_helper-fwd.hh \ job.hh job-fwd.hh \ @@ -68,6 +69,7 @@ noinst_HEADERS = \ package_or_block_dep_spec.hh package_or_block_dep_spec-fwd.hh \ prefer_or_avoid_helper.hh prefer_or_avoid_helper-fwd.hh \ reason.hh reason-fwd.hh \ + reason_utils.hh reason_utils-fwd.hh \ remove_if_dependent_helper.hh remove_if_dependent_helper-fwd.hh \ required_confirmations.hh required_confirmations-fwd.hh \ resolution.hh resolution-fwd.hh \ @@ -106,6 +108,7 @@ libpaludisresolver_a_SOURCES = \ get_constraints_for_purge_helper.cc \ get_constraints_for_via_binary_helper.cc \ get_destination_types_for_error_helper.cc \ + get_resolvents_for_helper.cc \ get_use_existing_nothing_helper.cc \ interest_in_spec_helper.cc \ job.cc \ @@ -125,6 +128,7 @@ libpaludisresolver_a_SOURCES = \ package_or_block_dep_spec.cc \ prefer_or_avoid_helper.cc \ reason.cc \ + reason_utils.cc \ remove_if_dependent_helper.cc \ required_confirmations.cc \ resolution.cc \ diff --git a/paludis/resolver/get_resolvents_for_helper-fwd.hh b/paludis/resolver/get_resolvents_for_helper-fwd.hh new file mode 100644 index 0000000..2ff7959 --- /dev/null +++ b/paludis/resolver/get_resolvents_for_helper-fwd.hh @@ -0,0 +1,31 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_GET_RESOLVENTS_FOR_HELPER_FWD_HH +#define PALUDIS_GUARD_PALUDIS_RESOLVER_GET_RESOLVENTS_FOR_HELPER_FWD_HH 1 + +namespace paludis +{ + namespace resolver + { + struct GetResolventsForHelper; + } +} + +#endif diff --git a/paludis/resolver/get_resolvents_for_helper.cc b/paludis/resolver/get_resolvents_for_helper.cc new file mode 100644 index 0000000..d617b71 --- /dev/null +++ b/paludis/resolver/get_resolvents_for_helper.cc @@ -0,0 +1,302 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/resolver/get_resolvents_for_helper.hh> +#include <paludis/resolver/resolvent.hh> +#include <paludis/resolver/resolution.hh> +#include <paludis/resolver/reason_utils.hh> +#include <paludis/resolver/reason.hh> +#include <paludis/resolver/labels_classifier.hh> +#include <paludis/resolver/destination_utils.hh> +#include <paludis/util/pimp-impl.hh> +#include <paludis/util/stringify.hh> +#include <paludis/util/wrapped_output_iterator.hh> +#include <paludis/util/indirect_iterator-impl.hh> +#include <paludis/util/enum_iterator.hh> +#include <paludis/dep_spec.hh> +#include <paludis/environment.hh> +#include <paludis/generator.hh> +#include <paludis/filtered_generator.hh> +#include <paludis/filter.hh> +#include <paludis/selection.hh> +#include <paludis/package_id.hh> +#include <algorithm> + +using namespace paludis; +using namespace paludis::resolver; + +namespace paludis +{ + template <> + struct Imp<GetResolventsForHelper> + { + const Environment * const env; + + DestinationType target_destination_type; + + bool want_target_dependencies; + bool want_target_runtime_dependencies; + + bool want_best_slot_for_targets; + bool want_installed_slots_for_targets; + bool fallback_to_other_slots_for_targets; + + bool want_best_slot_otherwise; + bool want_installed_slots_otherwise; + bool fallback_to_other_slots_otherwise; + + Imp(const Environment * const e) : + env(e), + target_destination_type(dt_install_to_slash), + want_target_dependencies(true), + want_target_runtime_dependencies(true), + want_best_slot_for_targets(true), + want_installed_slots_for_targets(true), + fallback_to_other_slots_for_targets(false), + want_best_slot_otherwise(true), + want_installed_slots_otherwise(true), + fallback_to_other_slots_otherwise(false) + { + } + }; +} + +GetResolventsForHelper::GetResolventsForHelper(const Environment * const e) : + Pimp<GetResolventsForHelper>(e) +{ +} + +GetResolventsForHelper::~GetResolventsForHelper() = default; + +void +GetResolventsForHelper::set_target_destination_type(const DestinationType v) +{ + _imp->target_destination_type = v; +} + +void +GetResolventsForHelper::set_want_target_dependencies(const bool b) +{ + _imp->want_target_dependencies = b; +} + +void +GetResolventsForHelper::set_want_target_runtime_dependencies(const bool b) +{ + _imp->want_target_runtime_dependencies = b; +} + +void +GetResolventsForHelper::set_slots(const bool best, const bool installed, const bool fallback) +{ + _imp->want_best_slot_otherwise = best; + _imp->want_installed_slots_otherwise = installed; + _imp->fallback_to_other_slots_otherwise = fallback; +} + +void +GetResolventsForHelper::set_target_slots(const bool best, const bool installed, const bool fallback) +{ + _imp->want_best_slot_for_targets = best; + _imp->want_installed_slots_for_targets = installed; + _imp->fallback_to_other_slots_for_targets = fallback; +} + +namespace +{ + struct DestinationTypesFinder + { + const DestinationType target_destination_type; + const bool want_target_dependencies; + const bool want_target_runtime_dependencies; + const std::shared_ptr<const PackageID> package_id; + + DestinationTypes visit(const TargetReason &) const + { + return { target_destination_type }; + } + + DestinationTypes visit(const DependentReason &) const + { + return { dt_install_to_slash }; + } + + DestinationTypes visit(const ViaBinaryReason &) const + { + return { }; + } + + DestinationTypes visit(const WasUsedByReason &) const + { + return { dt_install_to_slash }; + } + + DestinationTypes visit(const DependencyReason & dep) const + { + DestinationTypes extras; + + switch (target_destination_type) + { + case dt_create_binary: + { + bool binary_if_possible(false); + if (want_target_dependencies) + binary_if_possible = true; + else if (want_target_runtime_dependencies) + { + /* this will track run deps of build deps, which isn't + * really right... */ + if (is_run_or_post_dep(dep.sanitised_dependency())) + binary_if_possible = true; + } + + if (binary_if_possible && can_make_binary_for(package_id)) + extras += dt_create_binary; + } + break; + + case dt_install_to_chroot: + { + bool chroot_if_possible(false); + if (want_target_dependencies) + chroot_if_possible = true; + else if (want_target_runtime_dependencies) + { + if (is_run_or_post_dep(dep.sanitised_dependency())) + chroot_if_possible = true; + } + + if (chroot_if_possible && can_chroot(package_id)) + extras += dt_install_to_chroot; + } + break; + + case dt_install_to_slash: + break; + + case last_dt: + throw InternalError(PALUDIS_HERE, "unhandled dt"); + } + + return extras + dt_install_to_slash; + } + + DestinationTypes visit(const PresetReason &) const + { + return { }; + } + + DestinationTypes visit(const LikeOtherDestinationTypeReason & r) const + { + return r.reason_for_other()->accept_returning<DestinationTypes>(*this); + } + + DestinationTypes visit(const SetReason & r) const + { + return r.reason_for_set()->accept_returning<DestinationTypes>(*this); + } + }; + + DestinationTypes get_destination_types_for_fn( + const Environment * const, + const PackageDepSpec &, + const DestinationType target_destination_type, + const bool want_target_dependencies, + const bool want_target_runtime_dependencies, + const std::shared_ptr<const PackageID> & package_id, + const std::shared_ptr<const Reason> & reason) + { + DestinationTypesFinder f{target_destination_type, want_target_dependencies, want_target_runtime_dependencies, package_id}; + return reason->accept_returning<DestinationTypes>(f); + } +} + +std::shared_ptr<Resolvents> +GetResolventsForHelper::operator() ( + const PackageDepSpec & spec, + const std::shared_ptr<const SlotName> & maybe_slot, + const std::shared_ptr<const Reason> & reason) const +{ + auto result_ids(std::make_shared<PackageIDSequence>()); + std::shared_ptr<const PackageID> best; + + auto ids((*_imp->env)[selection::BestVersionOnly( + generator::Matches(spec, { mpo_ignore_additional_requirements }) | + filter::SupportsAction<InstallAction>() | + filter::NotMasked() | + (maybe_slot ? Filter(filter::Slot(*maybe_slot)) : Filter(filter::All())))]); + + if (! ids->empty()) + best = *ids->begin(); + + auto installed_ids((*_imp->env)[selection::BestVersionInEachSlot( + generator::Matches(spec, { }) | + (_imp->target_destination_type == dt_install_to_chroot ? + Filter(filter::InstalledAtNotSlash()) : Filter(filter::InstalledAtSlash())))]); + + auto target(is_target(reason)); + auto want_installed(target ? _imp->want_installed_slots_for_targets : _imp->want_installed_slots_otherwise); + auto want_best(target ? _imp->want_best_slot_for_targets : _imp->want_best_slot_otherwise); + auto fallback(target ? _imp->fallback_to_other_slots_for_targets : _imp->fallback_to_other_slots_otherwise); + + if (! best) + std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter()); + else if (want_best && fallback && ! want_installed) // (arg.argument() == "best-or-installed") + { + if (indirect_iterator(installed_ids->end()) == std::find(indirect_iterator(installed_ids->begin()), + indirect_iterator(installed_ids->end()), *best)) + result_ids->push_back(best); + else + std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter()); + } + else if (want_installed && fallback && ! want_best) + { + if (installed_ids->empty()) + result_ids->push_back(best); + else + std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter()); + } + else if (want_installed && want_best) + { + if (indirect_iterator(installed_ids->end()) == std::find(indirect_iterator(installed_ids->begin()), + indirect_iterator(installed_ids->end()), *best)) + result_ids->push_back(best); + std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter()); + } + else if (want_best) + result_ids->push_back(best); + else if (want_installed) + std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter()); + + std::shared_ptr<Resolvents> result(std::make_shared<Resolvents>()); + for (PackageIDSequence::ConstIterator i(result_ids->begin()), i_end(result_ids->end()) ; + i != i_end ; ++i) + { + DestinationTypes destination_types(get_destination_types_for_fn(_imp->env, spec, + _imp->target_destination_type, _imp->want_target_dependencies, _imp->want_target_runtime_dependencies, *i, reason)); + for (EnumIterator<DestinationType> t, t_end(last_dt) ; t != t_end ; ++t) + if (destination_types[*t]) + result->push_back(Resolvent(*i, *t)); + } + + return result; +} + +template class Pimp<GetResolventsForHelper>; + diff --git a/paludis/resolver/get_resolvents_for_helper.hh b/paludis/resolver/get_resolvents_for_helper.hh new file mode 100644 index 0000000..2ffcfd4 --- /dev/null +++ b/paludis/resolver/get_resolvents_for_helper.hh @@ -0,0 +1,63 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_GET_RESOLVENTS_FOR_HELPER_HH +#define PALUDIS_GUARD_PALUDIS_RESOLVER_GET_RESOLVENTS_FOR_HELPER_HH 1 + +#include <paludis/resolver/get_resolvents_for_helper-fwd.hh> +#include <paludis/resolver/resolution-fwd.hh> +#include <paludis/resolver/reason-fwd.hh> +#include <paludis/resolver/destination_types-fwd.hh> +#include <paludis/resolver/resolvent-fwd.hh> +#include <paludis/util/pimp.hh> +#include <paludis/util/attributes.hh> +#include <paludis/package_id-fwd.hh> +#include <paludis/dep_spec-fwd.hh> +#include <paludis/environment-fwd.hh> +#include <paludis/name-fwd.hh> +#include <memory> + +namespace paludis +{ + namespace resolver + { + class PALUDIS_VISIBLE GetResolventsForHelper : + private Pimp<GetResolventsForHelper> + { + public: + explicit GetResolventsForHelper(const Environment * const); + ~GetResolventsForHelper(); + + void set_target_destination_type(const DestinationType); + + void set_want_target_dependencies(const bool); + void set_want_target_runtime_dependencies(const bool); + + void set_slots(const bool best, const bool installed, const bool fallback); + void set_target_slots(const bool best, const bool installed, const bool fallback); + + std::shared_ptr<Resolvents> operator() ( + const PackageDepSpec &, + const std::shared_ptr<const SlotName> &, + const std::shared_ptr<const Reason> &) const; + }; + } +} + +#endif diff --git a/paludis/resolver/reason_utils-fwd.hh b/paludis/resolver/reason_utils-fwd.hh new file mode 100644 index 0000000..23cf6e5 --- /dev/null +++ b/paludis/resolver/reason_utils-fwd.hh @@ -0,0 +1,35 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_REASON_UTILS_FWD_HH +#define PALUDIS_GUARD_PALUDIS_RESOLVER_REASON_UTILS_FWD_HH 1 + +#include <paludis/util/attributes.hh> +#include <paludis/resolver/reason-fwd.hh> +#include <memory> + +namespace paludis +{ + namespace resolver + { + bool is_target(const std::shared_ptr<const Reason> &) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result)); + } +} + +#endif diff --git a/paludis/resolver/reason_utils.cc b/paludis/resolver/reason_utils.cc new file mode 100644 index 0000000..063bd77 --- /dev/null +++ b/paludis/resolver/reason_utils.cc @@ -0,0 +1,78 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/resolver/reason_utils.hh> +#include <paludis/resolver/reason.hh> + +using namespace paludis; +using namespace paludis::resolver; + +namespace +{ + struct IsTargetVisitor + { + bool visit(const DependencyReason &) const + { + return false; + } + + bool visit(const DependentReason &) const + { + return false; + } + + bool visit(const WasUsedByReason &) const + { + return false; + } + + bool visit(const PresetReason &) const + { + return false; + } + + bool visit(const ViaBinaryReason &) const + { + return false; + } + + bool visit(const TargetReason &) const + { + return true; + } + + bool visit(const LikeOtherDestinationTypeReason & r) const + { + return r.reason_for_other()->accept_returning<bool>(*this); + } + + bool visit(const SetReason & r) const + { + return r.reason_for_set()->accept_returning<bool>(*this); + } + }; +} + +bool +paludis::resolver::is_target(const std::shared_ptr<const Reason> & reason) +{ + IsTargetVisitor v; + return reason->accept_returning<bool>(v); +} + diff --git a/paludis/resolver/reason_utils.hh b/paludis/resolver/reason_utils.hh new file mode 100644 index 0000000..fd65b1c --- /dev/null +++ b/paludis/resolver/reason_utils.hh @@ -0,0 +1,33 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2010 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_REASON_UTILS_HH +#define PALUDIS_GUARD_PALUDIS_RESOLVER_REASON_UTILS_HH 1 + +#include <paludis/resolver/reason_utils-fwd.hh> + +namespace paludis +{ + namespace resolver + { + + } +} + +#endif diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc index 9dbbca9..5d8a875 100644 --- a/paludis/resolver/resolver_test.cc +++ b/paludis/resolver/resolver_test.cc @@ -86,28 +86,6 @@ paludis::resolver::resolver_test::initial_constraints_for_fn( return i->second; } -std::shared_ptr<Resolvents> -paludis::resolver::resolver_test::get_resolvents_for_fn( - const Environment * const env, - const PackageDepSpec & spec, - const std::shared_ptr<const SlotName> & slot, - const std::shared_ptr<const Reason> &) -{ - auto result(std::make_shared<Resolvents>()); - if (slot) - result->push_back(Resolvent(spec, *slot, dt_install_to_slash)); - else - { - auto ids((*env)[selection::BestVersionInEachSlot( - generator::Matches(spec, { mpo_ignore_additional_requirements }))]); - for (auto i(ids->begin()), i_end(ids->end()) ; - i != i_end ; ++i) - if ((*i)->slot_key()) - result->push_back(Resolvent(spec, (*i)->slot_key()->value(), dt_install_to_slash)); - } - return result; -} - namespace { #ifdef ENABLE_VIRTUALS_REPOSITORY @@ -146,6 +124,7 @@ ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s, get_constraints_for_purge_helper(&env), get_constraints_for_via_binary_helper(&env), get_destination_types_for_error_helper(&env), + get_resolvents_for_helper(&env), get_use_existing_nothing_helper(&env), interest_in_spec_helper(&env), make_destination_filtered_generator_helper(&env), @@ -217,8 +196,7 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint n::get_initial_constraints_for_fn() = std::bind(&initial_constraints_for_fn, std::ref(initial_constraints), std::placeholders::_1), - n::get_resolvents_for_fn() = std::bind(&get_resolvents_for_fn, &env, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3), + n::get_resolvents_for_fn() = std::cref(get_resolvents_for_helper), n::get_use_existing_nothing_fn() = std::cref(get_use_existing_nothing_helper), n::interest_in_spec_fn() = std::cref(interest_in_spec_helper), n::make_destination_filtered_generator_fn() = std::cref(make_destination_filtered_generator_helper), diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh index 2932bd3..7e9a92a 100644 --- a/paludis/resolver/resolver_test.hh +++ b/paludis/resolver/resolver_test.hh @@ -45,6 +45,7 @@ #include <paludis/resolver/get_constraints_for_purge_helper.hh> #include <paludis/resolver/get_constraints_for_via_binary_helper.hh> #include <paludis/resolver/get_destination_types_for_error_helper.hh> +#include <paludis/resolver/get_resolvents_for_helper.hh> #include <paludis/resolver/get_use_existing_nothing_helper.hh> #include <paludis/resolver/interest_in_spec_helper.hh> #include <paludis/resolver/make_destination_filtered_generator_helper.hh> @@ -87,12 +88,6 @@ namespace paludis const InitialConstraints & initial_constraints, const Resolvent & resolvent); - std::shared_ptr<Resolvents> get_resolvents_for_fn( - const Environment * const, - const PackageDepSpec & spec, - const std::shared_ptr<const SlotName> &, - const std::shared_ptr<const Reason> &); - struct ResolverTestCase : test::TestCase { TestEnvironment env; @@ -109,6 +104,7 @@ namespace paludis GetConstraintsForPurgeHelper get_constraints_for_purge_helper; GetConstraintsForViaBinaryHelper get_constraints_for_via_binary_helper; GetDestinationTypesForErrorHelper get_destination_types_for_error_helper; + GetResolventsForHelper get_resolvents_for_helper; GetUseExistingNothingHelper get_use_existing_nothing_helper; InterestInSpecHelper interest_in_spec_helper; MakeDestinationFilteredGeneratorHelper make_destination_filtered_generator_helper; diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc index d3cd69d..20de983 100644 --- a/src/clients/cave/resolve_common.cc +++ b/src/clients/cave/resolve_common.cc @@ -53,6 +53,7 @@ #include <paludis/resolver/destination_utils.hh> #include <paludis/resolver/resolver_functions.hh> #include <paludis/resolver/reason.hh> +#include <paludis/resolver/reason_utils.hh> #include <paludis/resolver/suggest_restart.hh> #include <paludis/resolver/resolvent.hh> #include <paludis/resolver/constraint.hh> @@ -75,6 +76,7 @@ #include <paludis/resolver/get_constraints_for_purge_helper.hh> #include <paludis/resolver/get_constraints_for_via_binary_helper.hh> #include <paludis/resolver/get_destination_types_for_error_helper.hh> +#include <paludis/resolver/get_resolvents_for_helper.hh> #include <paludis/resolver/get_use_existing_nothing_helper.hh> #include <paludis/resolver/interest_in_spec_helper.hh> #include <paludis/resolver/make_destination_filtered_generator_helper.hh> @@ -124,13 +126,6 @@ namespace typedef std::map<Resolvent, std::shared_ptr<Constraints> > InitialConstraints; typedef std::list<PackageDepSpec> PackageDepSpecList; - bool can_make_binary_for(const std::shared_ptr<const PackageID> & id) - { - if (! id->behaviours_key()) - return true; - return id->behaviours_key()->value()->end() == id->behaviours_key()->value()->find("unbinaryable"); - } - struct DestinationTypesFinder { const Environment * const env; @@ -484,55 +479,6 @@ namespace return i->second; } - struct IsTargetVisitor - { - bool visit(const DependencyReason &) const - { - return false; - } - - bool visit(const DependentReason &) const - { - return false; - } - - bool visit(const WasUsedByReason &) const - { - return false; - } - - bool visit(const PresetReason &) const - { - return false; - } - - bool visit(const ViaBinaryReason &) const - { - return false; - } - - bool visit(const TargetReason &) const - { - return true; - } - - bool visit(const LikeOtherDestinationTypeReason & r) const - { - return r.reason_for_other()->accept_returning<bool>(*this); - } - - bool visit(const SetReason & r) const - { - return r.reason_for_set()->accept_returning<bool>(*this); - } - }; - - bool is_target(const std::shared_ptr<const Reason> & reason) - { - IsTargetVisitor v; - return reason->accept_returning<bool>(v); - } - const std::shared_ptr<Resolvents> get_resolvents_for_fn(const Environment * const env, const ResolveCommandLineResolutionOptions & resolution_options, @@ -995,6 +941,19 @@ namespace throw args::DoHelp("Don't understand argument '" + arg.argument() + "' to '--" + arg.long_name() + "'"); } + + DestinationType destination_type_from_arg(const args::EnumArg & arg) + { + if (arg.argument() == "binaries") + return dt_create_binary; + else if (arg.argument() == "install") + return dt_install_to_slash; + else if (arg.argument() == "chroot") + return dt_install_to_chroot; + else + throw args::DoHelp("Don't understand argument '" + arg.argument() + "' to '--" + + arg.long_name() + "'"); + } } int @@ -1135,15 +1094,66 @@ paludis::cave::resolve_common( GetConstraintsForViaBinaryHelper get_constraints_for_via_binary_helper(env.get()); GetDestinationTypesForErrorHelper get_destination_types_for_error_helper(env.get()); - if (resolution_options.a_make.argument() == "binaries") - get_destination_types_for_error_helper.set_target_destination_type(dt_create_binary); - else if (resolution_options.a_make.argument() == "install") - get_destination_types_for_error_helper.set_target_destination_type(dt_install_to_slash); - else if (resolution_options.a_make.argument() == "chroot") - get_destination_types_for_error_helper.set_target_destination_type(dt_install_to_chroot); + get_destination_types_for_error_helper.set_target_destination_type(destination_type_from_arg(resolution_options.a_make)); + + GetResolventsForHelper get_resolvents_for_helper(env.get()); + get_resolvents_for_helper.set_target_destination_type(destination_type_from_arg(resolution_options.a_make)); + + if (resolution_options.a_make_dependencies.argument() == "auto") + { + if ("install" == resolution_options.a_make.argument()) + { + get_resolvents_for_helper.set_want_target_dependencies(true); + get_resolvents_for_helper.set_want_target_runtime_dependencies(true); + } + else + { + get_resolvents_for_helper.set_want_target_dependencies(false); + get_resolvents_for_helper.set_want_target_runtime_dependencies(true); + } + } + else if (resolution_options.a_make_dependencies.argument() == "runtime") + { + get_resolvents_for_helper.set_want_target_dependencies(false); + get_resolvents_for_helper.set_want_target_runtime_dependencies(true); + } + else if (resolution_options.a_make_dependencies.argument() == "all") + { + get_resolvents_for_helper.set_want_target_dependencies(true); + get_resolvents_for_helper.set_want_target_runtime_dependencies(true); + } + else if (resolution_options.a_make_dependencies.argument() == "none") + { + get_resolvents_for_helper.set_want_target_dependencies(false); + get_resolvents_for_helper.set_want_target_runtime_dependencies(false); + } + else + throw args::DoHelp("Don't understand argument '" + resolution_options.a_make_dependencies.argument() + "' to '--" + + resolution_options.a_make_dependencies.long_name() + "'"); + + if (resolution_options.a_slots.argument() == "best-or-installed") + get_resolvents_for_helper.set_slots(true, false, true); + else if (resolution_options.a_slots.argument() == "installed-or-best") + get_resolvents_for_helper.set_slots(false, true, true); + else if (resolution_options.a_slots.argument() == "all") + get_resolvents_for_helper.set_slots(true, true, false); + else if (resolution_options.a_slots.argument() == "best") + get_resolvents_for_helper.set_slots(true, false, false); + else + throw args::DoHelp("Don't understand argument '" + resolution_options.a_slots.argument() + "' to '--" + + resolution_options.a_slots.long_name() + "'"); + + if (resolution_options.a_target_slots.argument() == "best-or-installed") + get_resolvents_for_helper.set_target_slots(true, false, true); + else if (resolution_options.a_target_slots.argument() == "installed-or-best") + get_resolvents_for_helper.set_target_slots(false, true, true); + else if (resolution_options.a_target_slots.argument() == "all") + get_resolvents_for_helper.set_target_slots(true, true, false); + else if (resolution_options.a_target_slots.argument() == "best") + get_resolvents_for_helper.set_target_slots(true, false, false); else - throw args::DoHelp("Don't understand argument '" + resolution_options.a_make.argument() + "' to '--" - + resolution_options.a_make.long_name() + "'"); + throw args::DoHelp("Don't understand argument '" + resolution_options.a_target_slots.argument() + "' to '--" + + resolution_options.a_target_slots.long_name() + "'"); GetUseExistingNothingHelper get_use_existing_nothing_helper(env.get()); for (args::StringSetArg::ConstIterator i(resolution_options.a_without.begin_args()), @@ -1263,8 +1273,7 @@ paludis::cave::resolve_common( n::get_initial_constraints_for_fn() = std::bind(&initial_constraints_for_fn, env.get(), std::cref(resolution_options), std::cref(without), std::cref(initial_constraints), binary_destinations, _1), - n::get_resolvents_for_fn() = std::bind(&get_resolvents_for_fn, - env.get(), std::cref(resolution_options), _1, _2, _3, DestinationTypes()), + n::get_resolvents_for_fn() = std::cref(get_resolvents_for_helper), n::get_use_existing_nothing_fn() = std::cref(get_use_existing_nothing_helper), n::interest_in_spec_fn() = std::cref(interest_in_spec_helper), n::make_destination_filtered_generator_fn() = std::cref(make_destination_filtered_generator_helper), |