aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-08 15:35:02 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-08 15:35:02 +0100
commitb4ab443375d5f8848e4084cd408dbb753fcaf771 (patch)
tree08400dc71612a36ebd6ffb5e0862bd5514d073cf
parent391a11571d99f0b9ccb030381c32dd9a36721f37 (diff)
downloadpaludis-b4ab443375d5f8848e4084cd408dbb753fcaf771.tar.gz
paludis-b4ab443375d5f8848e4084cd408dbb753fcaf771.tar.xz
GetResolventsForHelper
-rw-r--r--paludis/resolver/Makefile.am4
-rw-r--r--paludis/resolver/get_resolvents_for_helper-fwd.hh31
-rw-r--r--paludis/resolver/get_resolvents_for_helper.cc302
-rw-r--r--paludis/resolver/get_resolvents_for_helper.hh63
-rw-r--r--paludis/resolver/reason_utils-fwd.hh35
-rw-r--r--paludis/resolver/reason_utils.cc78
-rw-r--r--paludis/resolver/reason_utils.hh33
-rw-r--r--paludis/resolver/resolver_test.cc26
-rw-r--r--paludis/resolver/resolver_test.hh8
-rw-r--r--src/clients/cave/resolve_common.cc141
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),