aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-08 09:45:41 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-08 10:53:07 +0100
commit6f0d1e67b6042352af6662342bc3e98840d7892a (patch)
treeae19914b50f0be06a2d6bacfdff8c3052dfba793
parent7d86f4823402c6bb65a28a81a435bd21a2b259f3 (diff)
downloadpaludis-6f0d1e67b6042352af6662342bc3e98840d7892a.tar.gz
paludis-6f0d1e67b6042352af6662342bc3e98840d7892a.tar.xz
InterestInSpecHelper
-rw-r--r--paludis/resolver/Makefile.am4
-rw-r--r--paludis/resolver/interest_in_spec_helper-fwd.hh31
-rw-r--r--paludis/resolver/interest_in_spec_helper.cc308
-rw-r--r--paludis/resolver/interest_in_spec_helper.hh68
-rw-r--r--paludis/resolver/match_qpns-fwd.hh (renamed from src/clients/cave/match_qpns.hh)6
-rw-r--r--paludis/resolver/match_qpns.cc (renamed from src/clients/cave/match_qpns.cc)6
-rw-r--r--paludis/resolver/match_qpns.hh30
-rw-r--r--paludis/resolver/resolver_test.cc16
-rw-r--r--paludis/resolver/resolver_test.hh6
-rw-r--r--src/clients/cave/Makefile.am1
-rw-r--r--src/clients/cave/cmd_display_resolution.cc2
-rw-r--r--src/clients/cave/resolve_common.cc291
12 files changed, 513 insertions, 256 deletions
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index 5670247..6e9453a 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 \
+ interest_in_spec_helper.hh interest_in_spec_helper-fwd.hh \
job.hh job-fwd.hh \
job_list.hh job_list-fwd.hh \
job_lists.hh job_lists-fwd.hh \
@@ -58,6 +59,7 @@ noinst_HEADERS = \
make_destination_filtered_generator_helper.hh make_destination_filtered_generator_helper-fwd.hh \
make_origin_filtered_generator_helper.hh make_origin_filtered_generator_helper-fwd.hh \
make_unmaskable_filter_helper.hh make_unmaskable_filter_helper-fwd.hh \
+ match_qpns.hh match_qpns-fwd.hh \
nag.hh nag-fwd.hh \
order_early_helper.hh order_early_helper-fwd.hh \
orderer.hh orderer-fwd.hh \
@@ -103,6 +105,7 @@ libpaludisresolver_a_SOURCES = \
get_constraints_for_purge_helper.cc \
get_constraints_for_via_binary_helper.cc \
get_destination_types_for_error_helper.cc \
+ interest_in_spec_helper.cc \
job.cc \
job_list.cc \
job_lists.cc \
@@ -112,6 +115,7 @@ libpaludisresolver_a_SOURCES = \
make_destination_filtered_generator_helper.cc \
make_origin_filtered_generator_helper.cc \
make_unmaskable_filter_helper.cc \
+ match_qpns.cc \
nag.cc \
order_early_helper.cc \
orderer.cc \
diff --git a/paludis/resolver/interest_in_spec_helper-fwd.hh b/paludis/resolver/interest_in_spec_helper-fwd.hh
new file mode 100644
index 0000000..078973c
--- /dev/null
+++ b/paludis/resolver/interest_in_spec_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_INTEREST_IN_SPEC_HELPER_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_INTEREST_IN_SPEC_HELPER_FWD_HH 1
+
+namespace paludis
+{
+ namespace resolver
+ {
+ struct InterestInSpecHelper;
+ }
+}
+
+#endif
diff --git a/paludis/resolver/interest_in_spec_helper.cc b/paludis/resolver/interest_in_spec_helper.cc
new file mode 100644
index 0000000..c210eb0
--- /dev/null
+++ b/paludis/resolver/interest_in_spec_helper.cc
@@ -0,0 +1,308 @@
+/* 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/interest_in_spec_helper.hh>
+#include <paludis/resolver/reason.hh>
+#include <paludis/resolver/constraint.hh>
+#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/resolution.hh>
+#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/match_qpns.hh>
+#include <paludis/resolver/labels_classifier.hh>
+#include <paludis/util/pimp-impl.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/tribool.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/selection.hh>
+#include <paludis/generator.hh>
+#include <paludis/filter.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_dep_spec_collection.hh>
+#include <list>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+namespace paludis
+{
+ template <>
+ struct Imp<InterestInSpecHelper>
+ {
+ const Environment * const env;
+ std::list<PackageDepSpec> take_specs;
+ std::list<PackageDepSpec> take_from_specs;
+ std::list<PackageDepSpec> ignore_specs;
+ std::list<PackageDepSpec> ignore_from_specs;
+ PackageDepSpecCollection no_blockers_from_specs;
+ PackageDepSpecCollection no_dependencies_from_specs;
+ bool follow_installed_build_dependencies;
+ bool follow_installed_dependencies;
+ Tribool take_suggestions;
+ Tribool take_recommendations;
+
+ Imp(const Environment * const e) :
+ env(e),
+ follow_installed_build_dependencies(false),
+ follow_installed_dependencies(true),
+ take_suggestions(indeterminate),
+ take_recommendations(true)
+ {
+ }
+ };
+}
+
+InterestInSpecHelper::InterestInSpecHelper(const Environment * const e) :
+ Pimp<InterestInSpecHelper>(e)
+{
+}
+
+InterestInSpecHelper::~InterestInSpecHelper() = default;
+
+void
+InterestInSpecHelper::add_take_spec(const PackageDepSpec & spec)
+{
+ _imp->take_specs.push_back(spec);
+}
+
+void
+InterestInSpecHelper::add_take_from_spec(const PackageDepSpec & spec)
+{
+ _imp->take_from_specs.push_back(spec);
+}
+
+void
+InterestInSpecHelper::add_ignore_spec(const PackageDepSpec & spec)
+{
+ _imp->ignore_specs.push_back(spec);
+}
+
+void
+InterestInSpecHelper::add_ignore_from_spec(const PackageDepSpec & spec)
+{
+ _imp->ignore_from_specs.push_back(spec);
+}
+
+void
+InterestInSpecHelper::add_no_blockers_from_spec(const PackageDepSpec & spec)
+{
+ _imp->no_blockers_from_specs.insert(spec);
+}
+
+void
+InterestInSpecHelper::add_no_dependencies_from_spec(const PackageDepSpec & spec)
+{
+ _imp->no_dependencies_from_specs.insert(spec);
+}
+
+void
+InterestInSpecHelper::set_follow_installed_dependencies(const bool b)
+{
+ _imp->follow_installed_dependencies = b;
+}
+
+void
+InterestInSpecHelper::set_follow_installed_build_dependencies(const bool b)
+{
+ _imp->follow_installed_build_dependencies = b;
+}
+
+void
+InterestInSpecHelper::set_take_suggestions(const Tribool v)
+{
+ _imp->take_suggestions = v;
+}
+
+void
+InterestInSpecHelper::set_take_recommendations(const Tribool v)
+{
+ _imp->take_recommendations = v;
+}
+
+namespace
+{
+ bool ignore_dep_from(
+ const Environment * const env,
+ const PackageDepSpecCollection & no_blockers_from_specs,
+ const PackageDepSpecCollection & no_dependencies_from_specs,
+ const std::shared_ptr<const PackageID> & id,
+ const bool is_block)
+ {
+ const auto & list(is_block ? no_blockers_from_specs : no_dependencies_from_specs);
+
+ return list.match_any(env, id, { });
+ }
+
+ struct CareAboutDepFnVisitor
+ {
+ const Environment * const env;
+ const PackageDepSpecCollection & no_blockers_from_specs;
+ const PackageDepSpecCollection & no_dependencies_from_specs;
+ const bool follow_installed_build_dependencies;
+ const bool follow_installed_dependencies;
+ const SanitisedDependency dep;
+
+ bool visit(const ExistingNoChangeDecision & decision) const
+ {
+ if (ignore_dep_from(env, no_blockers_from_specs, no_dependencies_from_specs, decision.existing_id(), dep.spec().if_block()))
+ return false;
+
+ if (! is_enabled_dep(dep))
+ return false;
+
+ if (! follow_installed_build_dependencies)
+ if (is_just_build_dep(dep))
+ return false;
+ if (! follow_installed_dependencies)
+ if (! is_compiled_against_dep(dep))
+ return false;
+
+ if (is_suggestion(dep) || is_recommendation(dep))
+ {
+ /* we only take a suggestion or recommendation for an existing
+ * package if it's already met. for now, we ignore suggested
+ * and recommended blocks no matter what. */
+ if (dep.spec().if_block())
+ return false;
+
+ const std::shared_ptr<const PackageIDSequence> installed_ids(
+ (*env)[selection::SomeArbitraryVersion(
+ generator::Matches(*dep.spec().if_package(), { }) |
+ filter::InstalledAtRoot(FSEntry("/")))]);
+ if (installed_ids->empty())
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visit(const NothingNoChangeDecision &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "NothingNoChangeDecision shouldn't have deps");
+ }
+
+ bool visit(const UnableToMakeDecision &) const
+ {
+ /* might've gone from a sensible decision to unable later on */
+ return false;
+ }
+
+ bool visit(const RemoveDecision &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "RemoveDecision shouldn't have deps");
+ }
+
+ bool visit(const BreakDecision &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "BreakDecision shouldn't have deps");
+ }
+
+ bool visit(const ChangesToMakeDecision & decision) const
+ {
+ if (ignore_dep_from(env, no_blockers_from_specs, no_dependencies_from_specs, decision.origin_id(), dep.spec().if_block()))
+ return false;
+
+ if (is_enabled_dep(dep))
+ return true;
+
+ return false;
+ }
+ };
+}
+
+SpecInterest
+InterestInSpecHelper::operator() (
+ const std::shared_ptr<const Resolution> & resolution,
+ const SanitisedDependency & dep) const
+{
+ CareAboutDepFnVisitor v{_imp->env, _imp->no_blockers_from_specs, _imp->no_dependencies_from_specs,
+ _imp->follow_installed_build_dependencies, _imp->follow_installed_dependencies, dep};
+
+ if (resolution->decision()->accept_returning<bool>(v))
+ {
+ bool suggestion(is_suggestion(dep)), recommendation(is_recommendation(dep));
+
+ if (! (suggestion || recommendation))
+ return si_take;
+
+ for (auto l(_imp->take_specs.begin()), l_end(_imp->take_specs.end()) ;
+ l != l_end ; ++l)
+ {
+ PackageDepSpec spec(*dep.spec().if_package());
+ if (match_qpns(*_imp->env, *l, *spec.package_ptr()))
+ return si_take;
+ }
+
+ for (auto l(_imp->take_from_specs.begin()), l_end(_imp->take_from_specs.end()) ;
+ l != l_end ; ++l)
+ {
+ if (match_qpns(*_imp->env, *l, resolution->resolvent().package()))
+ return si_take;
+ }
+
+ for (auto l(_imp->ignore_specs.begin()), l_end(_imp->ignore_specs.end()) ;
+ l != l_end ; ++l)
+ {
+ PackageDepSpec spec(*dep.spec().if_package());
+ if (match_qpns(*_imp->env, *l, *spec.package_ptr()))
+ return si_ignore;
+ }
+
+ for (auto l(_imp->ignore_from_specs.begin()), l_end(_imp->ignore_from_specs.end()) ;
+ l != l_end ; ++l)
+ {
+ if (match_qpns(*_imp->env, *l, resolution->resolvent().package()))
+ return si_ignore;
+ }
+
+ if (suggestion)
+ {
+ if (_imp->take_suggestions.is_true())
+ return si_take;
+ else if (_imp->take_suggestions.is_false())
+ return si_ignore;
+ }
+
+ if (recommendation)
+ {
+ if (_imp->take_recommendations.is_true())
+ return si_take;
+ else if (_imp->take_recommendations.is_false())
+ return si_ignore;
+ }
+
+ /* we also take suggestions and recommendations that have already been installed */
+ if (dep.spec().if_package())
+ {
+ const std::shared_ptr<const PackageIDSequence> installed_ids(
+ (*_imp->env)[selection::SomeArbitraryVersion(
+ generator::Matches(*dep.spec().if_package(), { }) |
+ filter::InstalledAtRoot(FSEntry("/")))]);
+ if (! installed_ids->empty())
+ return si_take;
+ }
+
+ return si_untaken;
+ }
+ else
+ return si_ignore;
+}
+
+template class Pimp<InterestInSpecHelper>;
+
diff --git a/paludis/resolver/interest_in_spec_helper.hh b/paludis/resolver/interest_in_spec_helper.hh
new file mode 100644
index 0000000..636d21f
--- /dev/null
+++ b/paludis/resolver/interest_in_spec_helper.hh
@@ -0,0 +1,68 @@
+/* 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_INTEREST_IN_SPEC_HELPER_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_INTEREST_IN_SPEC_HELPER_HH 1
+
+#include <paludis/resolver/interest_in_spec_helper-fwd.hh>
+#include <paludis/resolver/resolution-fwd.hh>
+#include <paludis/resolver/sanitised_dependencies-fwd.hh>
+#include <paludis/resolver/resolver_functions-fwd.hh>
+#include <paludis/util/pimp.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/util/tribool-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
+#include <paludis/environment-fwd.hh>
+#include <memory>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ class PALUDIS_VISIBLE InterestInSpecHelper :
+ private Pimp<InterestInSpecHelper>
+ {
+ public:
+ explicit InterestInSpecHelper(const Environment * const);
+ ~InterestInSpecHelper();
+
+ void add_take_spec(const PackageDepSpec &);
+ void add_take_from_spec(const PackageDepSpec &);
+ void add_ignore_spec(const PackageDepSpec &);
+ void add_ignore_from_spec(const PackageDepSpec &);
+ void add_no_blockers_from_spec(const PackageDepSpec &);
+ void add_no_dependencies_from_spec(const PackageDepSpec &);
+
+ void set_follow_installed_dependencies(const bool);
+ void set_follow_installed_build_dependencies(const bool);
+
+ void set_take_suggestions(const Tribool);
+ void set_take_recommendations(const Tribool);
+
+ SpecInterest operator() (
+ const std::shared_ptr<const Resolution> &,
+ const SanitisedDependency &) const;
+ };
+ }
+
+ extern template class Pimp<resolver::InterestInSpecHelper>;
+}
+
+#endif
diff --git a/src/clients/cave/match_qpns.hh b/paludis/resolver/match_qpns-fwd.hh
index d17fbea..a7e5a17 100644
--- a/src/clients/cave/match_qpns.hh
+++ b/paludis/resolver/match_qpns-fwd.hh
@@ -17,8 +17,8 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_SRC_CLIENTS_CAVE_MATCH_QPNS_HH
-#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_MATCH_QPNS_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_MATCH_QPNS_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_MATCH_QPNS_FWD_HH 1
#include <paludis/util/attributes.hh>
#include <paludis/dep_spec-fwd.hh>
@@ -27,7 +27,7 @@
namespace paludis
{
- namespace cave
+ namespace resolver
{
bool match_qpns(
const Environment & env,
diff --git a/src/clients/cave/match_qpns.cc b/paludis/resolver/match_qpns.cc
index 884400c..6ad2892 100644
--- a/src/clients/cave/match_qpns.cc
+++ b/paludis/resolver/match_qpns.cc
@@ -17,7 +17,7 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "match_qpns.hh"
+#include <paludis/resolver/match_qpns.hh>
#include <paludis/dep_spec.hh>
#include <paludis/environment.hh>
#include <paludis/package_dep_spec_properties.hh>
@@ -25,11 +25,11 @@
#include <paludis/util/make_named_values.hh>
using namespace paludis;
-using namespace cave;
+using namespace paludis::resolver;
// The 's' is silent...
bool
-paludis::cave::match_qpns(
+paludis::resolver::match_qpns(
const Environment &,
const PackageDepSpec & spec,
const QualifiedPackageName & package)
diff --git a/paludis/resolver/match_qpns.hh b/paludis/resolver/match_qpns.hh
new file mode 100644
index 0000000..3ec0293
--- /dev/null
+++ b/paludis/resolver/match_qpns.hh
@@ -0,0 +1,30 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Mike Kelly
+ *
+ * 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_MATCH_QPNS_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_MATCH_QPNS_HH 1
+
+#include <paludis/resolver/match_qpns-fwd.hh>
+
+namespace paludis
+{
+
+}
+
+#endif
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index 5cfcd2b..baed130 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -133,16 +133,6 @@ namespace
#endif
}
-SpecInterest
-paludis::resolver::resolver_test::interest_in_spec_fn(
- const std::shared_ptr<const Resolution> &, const SanitisedDependency & dep)
-{
- if (is_suggestion(dep))
- return si_untaken;
- else
- return si_take;
-}
-
std::pair<UseExisting, bool>
paludis::resolver::resolver_test::get_use_existing_nothing_fn(
const std::shared_ptr<const Resolution> &,
@@ -165,6 +155,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),
+ interest_in_spec_helper(&env),
make_destination_filtered_generator_helper(&env),
make_origin_filtered_generator_helper(&env),
make_unmaskable_filter_helper(&env),
@@ -211,6 +202,9 @@ ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s,
env.package_database()->add_repository(0, RepositoryFactory::get_instance()->create(&env, installed_virtuals_repo_keys));
#endif
+ interest_in_spec_helper.set_follow_installed_dependencies(true);
+ interest_in_spec_helper.set_follow_installed_build_dependencies(true);
+
make_unmaskable_filter_helper.set_override_masks(false);
}
@@ -234,7 +228,7 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
n::get_resolvents_for_fn() = std::bind(&get_resolvents_for_fn, &env, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),
n::get_use_existing_nothing_fn() = &get_use_existing_nothing_fn,
- n::interest_in_spec_fn() = &interest_in_spec_fn,
+ n::interest_in_spec_fn() = std::cref(interest_in_spec_helper),
n::make_destination_filtered_generator_fn() = std::cref(make_destination_filtered_generator_helper),
n::make_origin_filtered_generator_fn() = std::cref(make_origin_filtered_generator_helper),
n::make_unmaskable_filter_fn() = std::cref(make_unmaskable_filter_helper),
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index e2a8a10..70d4d8a 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/interest_in_spec_helper.hh>
#include <paludis/resolver/make_destination_filtered_generator_helper.hh>
#include <paludis/resolver/make_origin_filtered_generator_helper.hh>
#include <paludis/resolver/make_unmaskable_filter_helper.hh>
@@ -81,10 +82,6 @@ namespace paludis
typedef std::map<Resolvent, std::shared_ptr<Constraints> > InitialConstraints;
- SpecInterest interest_in_spec_fn(
- const std::shared_ptr<const Resolution> &,
- const SanitisedDependency &);
-
const std::shared_ptr<Constraints> initial_constraints_for_fn(
const InitialConstraints & initial_constraints,
const Resolvent & resolvent);
@@ -116,6 +113,7 @@ namespace paludis
GetConstraintsForPurgeHelper get_constraints_for_purge_helper;
GetConstraintsForViaBinaryHelper get_constraints_for_via_binary_helper;
GetDestinationTypesForErrorHelper get_destination_types_for_error_helper;
+ InterestInSpecHelper interest_in_spec_helper;
MakeDestinationFilteredGeneratorHelper make_destination_filtered_generator_helper;
MakeOriginFilteredGeneratorHelper make_origin_filtered_generator_helper;
MakeUnmaskableFilterHelper make_unmaskable_filter_helper;
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index ad45fb0..ed28ce1 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -155,7 +155,6 @@ libcave_a_SOURCES = \
formats.cc formats.hh \
script_command.cc script_command.hh \
select_format_for_spec.cc select_format_for_spec.hh \
- match_qpns.cc match_qpns.hh \
owner_common.cc owner_common.hh \
resolve_common.cc resolve_common.hh \
resume_data.cc resume_data.hh
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index 8ab480b..5963331 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -23,7 +23,6 @@
#include "command_command_line.hh"
#include "formats.hh"
#include "colour_formatter.hh"
-#include "match_qpns.hh"
#include <paludis/args/do_help.hh>
#include <paludis/util/safe_ifstream.hh>
#include <paludis/util/system.hh>
@@ -56,6 +55,7 @@
#include <paludis/resolver/required_confirmations.hh>
#include <paludis/resolver/orderer_notes.hh>
#include <paludis/resolver/change_by_resolvent.hh>
+#include <paludis/resolver/match_qpns.hh>
#include <paludis/package_id.hh>
#include <paludis/version_spec.hh>
#include <paludis/metadata_key.hh>
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index c7e9885..bf1edde 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -24,7 +24,6 @@
#include "cmd_execute_resolution.hh"
#include "exceptions.hh"
#include "command_command_line.hh"
-#include "match_qpns.hh"
#include <paludis/util/mutex.hh>
#include <paludis/util/stringify.hh>
@@ -63,6 +62,7 @@
#include <paludis/resolver/decisions.hh>
#include <paludis/resolver/change_by_resolvent.hh>
#include <paludis/resolver/labels_classifier.hh>
+#include <paludis/resolver/match_qpns.hh>
#include <paludis/resolver/allow_choice_changes_helper.hh>
#include <paludis/resolver/allowed_to_remove_helper.hh>
@@ -74,6 +74,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/interest_in_spec_helper.hh>
#include <paludis/resolver/make_destination_filtered_generator_helper.hh>
#include <paludis/resolver/make_origin_filtered_generator_helper.hh>
#include <paludis/resolver/make_unmaskable_filter_helper.hh>
@@ -748,197 +749,6 @@ namespace
return result;
}
- bool ignore_dep_from(
- const Environment * const env,
- const ResolveCommandLineResolutionOptions &,
- const PackageDepSpecList & no_blockers_from,
- const PackageDepSpecList & no_dependencies_from,
- const std::shared_ptr<const PackageID> & id,
- const bool is_block)
- {
- const PackageDepSpecList & list(is_block ? no_blockers_from : no_dependencies_from);
-
- for (PackageDepSpecList::const_iterator l(list.begin()), l_end(list.end()) ;
- l != l_end ; ++l)
- if (match_package(*env, *l, *id, { }))
- return true;
-
- return false;
- }
-
- struct CareAboutDepFnVisitor
- {
- const Environment * const env;
- const ResolveCommandLineResolutionOptions & resolution_options;
- const PackageDepSpecList & no_blockers_from;
- const PackageDepSpecList & no_dependencies_from;
- const SanitisedDependency dep;
-
- CareAboutDepFnVisitor(const Environment * const e,
- const ResolveCommandLineResolutionOptions & c,
- const PackageDepSpecList & b,
- const PackageDepSpecList & f,
- const SanitisedDependency & d) :
- env(e),
- resolution_options(c),
- no_blockers_from(b),
- no_dependencies_from(f),
- dep(d)
- {
- }
-
- bool visit(const ExistingNoChangeDecision & decision) const
- {
- if (ignore_dep_from(env, resolution_options, no_blockers_from, no_dependencies_from,
- decision.existing_id(), bool(dep.spec().if_block())))
- return false;
-
- if (! is_enabled_dep(dep))
- return false;
-
- if (! resolution_options.a_follow_installed_build_dependencies.specified())
- if (is_just_build_dep(dep))
- return false;
- if (resolution_options.a_no_follow_installed_dependencies.specified())
- if (! is_compiled_against_dep(dep))
- return false;
-
- if (is_suggestion(dep) || is_recommendation(dep))
- {
- /* we only take a suggestion or recommendation for an existing
- * package if it's already met. for now, we ignore suggested
- * and recommended blocks no matter what. */
- if (dep.spec().if_block())
- return false;
-
- const std::shared_ptr<const PackageIDSequence> installed_ids(
- (*env)[selection::SomeArbitraryVersion(
- generator::Matches(*dep.spec().if_package(), { }) |
- filter::InstalledAtRoot(FSEntry("/")))]);
- if (installed_ids->empty())
- return false;
- }
-
- return true;
- }
-
- bool visit(const NothingNoChangeDecision &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "NothingNoChangeDecision shouldn't have deps");
- }
-
- bool visit(const UnableToMakeDecision &) const
- {
- /* might've gone from a sensible decision to unable later on */
- return false;
- }
-
- bool visit(const RemoveDecision &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "RemoveDecision shouldn't have deps");
- }
-
- bool visit(const BreakDecision &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "BreakDecision shouldn't have deps");
- }
-
- bool visit(const ChangesToMakeDecision & decision) const
- {
- if (ignore_dep_from(env, resolution_options, no_blockers_from,
- no_dependencies_from, decision.origin_id(), bool(dep.spec().if_block())))
- return false;
-
- if (is_enabled_dep(dep))
- return true;
-
- return false;
- }
- };
-
- SpecInterest interest_in_spec_fn(
- const Environment * const env,
- const ResolveCommandLineResolutionOptions & resolution_options,
- const PackageDepSpecList & take,
- const PackageDepSpecList & take_from,
- const PackageDepSpecList & ignore,
- const PackageDepSpecList & ignore_from,
- const PackageDepSpecList & no_blockers_from,
- const PackageDepSpecList & no_dependencies_from,
- const std::shared_ptr<const Resolution> & resolution,
- const SanitisedDependency & dep)
- {
- CareAboutDepFnVisitor v(env, resolution_options, no_blockers_from, no_dependencies_from, dep);
- if (resolution->decision()->accept_returning<bool>(v))
- {
- bool suggestion(is_suggestion(dep)), recommendation(is_recommendation(dep));
-
- if (! (suggestion || recommendation))
- return si_take;
-
- for (PackageDepSpecList::const_iterator l(take.begin()), l_end(take.end()) ;
- l != l_end ; ++l)
- {
- PackageDepSpec spec(*dep.spec().if_package());
- if (match_qpns(*env, *l, *spec.package_ptr()))
- return si_take;
- }
-
- for (PackageDepSpecList::const_iterator l(take_from.begin()), l_end(take_from.end()) ;
- l != l_end ; ++l)
- {
- if (match_qpns(*env, *l, resolution->resolvent().package()))
- return si_take;
- }
-
- for (PackageDepSpecList::const_iterator l(ignore.begin()), l_end(ignore.end()) ;
- l != l_end ; ++l)
- {
- PackageDepSpec spec(*dep.spec().if_package());
- if (match_qpns(*env, *l, *spec.package_ptr()))
- return si_ignore;
- }
-
- for (PackageDepSpecList::const_iterator l(ignore_from.begin()), l_end(ignore_from.end()) ;
- l != l_end ; ++l)
- {
- if (match_qpns(*env, *l, resolution->resolvent().package()))
- return si_ignore;
- }
-
- if (suggestion)
- {
- if (resolution_options.a_suggestions.argument() == "take")
- return si_take;
- else if (resolution_options.a_suggestions.argument() == "ignore")
- return si_ignore;
- }
-
- if (recommendation)
- {
- if (resolution_options.a_recommendations.argument() == "take")
- return si_take;
- else if (resolution_options.a_recommendations.argument() == "ignore")
- return si_ignore;
- }
-
- /* we also take suggestions and recommendations that have already been installed */
- if (dep.spec().if_package())
- {
- const std::shared_ptr<const PackageIDSequence> installed_ids(
- (*env)[selection::SomeArbitraryVersion(
- generator::Matches(*dep.spec().if_package(), { }) |
- filter::InstalledAtRoot(FSEntry("/")))]);
- if (! installed_ids->empty())
- return si_take;
- }
-
- return si_untaken;
- }
- else
- return si_ignore;
- }
-
Filter make_destination_filter_fn(const Resolvent & resolvent)
{
switch (resolvent.destination_type())
@@ -1324,7 +1134,7 @@ paludis::cave::resolve_common(
int retcode(0);
InitialConstraints initial_constraints;
- PackageDepSpecList with, without, take, take_from, ignore, ignore_from, no_dependencies_from, no_blockers_from;
+ PackageDepSpecList with, without;
for (args::StringSetArg::ConstIterator i(resolution_options.a_without.begin_args()),
i_end(resolution_options.a_without.end_args()) ;
@@ -1338,42 +1148,6 @@ paludis::cave::resolve_common(
with.push_back(parse_user_package_dep_spec(*i, env.get(),
{ updso_allow_wildcards }));
- for (args::StringSetArg::ConstIterator i(resolution_options.a_take.begin_args()),
- i_end(resolution_options.a_take.end_args()) ;
- i != i_end ; ++i)
- take.push_back(parse_user_package_dep_spec(*i, env.get(),
- { updso_allow_wildcards }));
-
- for (args::StringSetArg::ConstIterator i(resolution_options.a_take_from.begin_args()),
- i_end(resolution_options.a_take_from.end_args()) ;
- i != i_end ; ++i)
- take_from.push_back(parse_user_package_dep_spec(*i, env.get(),
- { updso_allow_wildcards }));
-
- for (args::StringSetArg::ConstIterator i(resolution_options.a_ignore.begin_args()),
- i_end(resolution_options.a_ignore.end_args()) ;
- i != i_end ; ++i)
- ignore.push_back(parse_user_package_dep_spec(*i, env.get(),
- { updso_allow_wildcards }));
-
- for (args::StringSetArg::ConstIterator i(resolution_options.a_ignore_from.begin_args()),
- i_end(resolution_options.a_ignore_from.end_args()) ;
- i != i_end ; ++i)
- ignore_from.push_back(parse_user_package_dep_spec(*i, env.get(),
- { updso_allow_wildcards }));
-
- for (args::StringSetArg::ConstIterator i(resolution_options.a_no_dependencies_from.begin_args()),
- i_end(resolution_options.a_no_dependencies_from.end_args()) ;
- i != i_end ; ++i)
- no_dependencies_from.push_back(parse_user_package_dep_spec(*i, env.get(),
- { updso_allow_wildcards }));
-
- for (args::StringSetArg::ConstIterator i(resolution_options.a_no_blockers_from.begin_args()),
- i_end(resolution_options.a_no_blockers_from.end_args()) ;
- i != i_end ; ++i)
- no_blockers_from.push_back(parse_user_package_dep_spec(*i, env.get(),
- { updso_allow_wildcards }));
-
std::shared_ptr<Generator> binary_destinations;
for (PackageDatabase::RepositoryConstIterator r(env->package_database()->begin_repositories()),
r_end(env->package_database()->end_repositories()) ;
@@ -1534,6 +1308,60 @@ paludis::cave::resolve_common(
i != i_end ; ++i)
remove_if_dependent_helper.add_remove_if_dependent_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+ InterestInSpecHelper interest_in_spec_helper(env.get());
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_take.begin_args()),
+ i_end(resolution_options.a_take.end_args()) ;
+ i != i_end ; ++i)
+ interest_in_spec_helper.add_take_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_take_from.begin_args()),
+ i_end(resolution_options.a_take_from.end_args()) ;
+ i != i_end ; ++i)
+ interest_in_spec_helper.add_take_from_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_ignore.begin_args()),
+ i_end(resolution_options.a_ignore.end_args()) ;
+ i != i_end ; ++i)
+ interest_in_spec_helper.add_ignore_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_ignore_from.begin_args()),
+ i_end(resolution_options.a_ignore_from.end_args()) ;
+ i != i_end ; ++i)
+ interest_in_spec_helper.add_ignore_from_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_no_dependencies_from.begin_args()),
+ i_end(resolution_options.a_no_dependencies_from.end_args()) ;
+ i != i_end ; ++i)
+ interest_in_spec_helper.add_no_dependencies_from_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_no_blockers_from.begin_args()),
+ i_end(resolution_options.a_no_blockers_from.end_args()) ;
+ i != i_end ; ++i)
+ interest_in_spec_helper.add_no_blockers_from_spec(parse_user_package_dep_spec(*i, env.get(), { updso_allow_wildcards }));
+
+ interest_in_spec_helper.set_follow_installed_dependencies(! resolution_options.a_no_follow_installed_dependencies.specified());
+ interest_in_spec_helper.set_follow_installed_build_dependencies(resolution_options.a_follow_installed_build_dependencies.specified());
+
+ if (resolution_options.a_suggestions.argument() == "take")
+ interest_in_spec_helper.set_take_suggestions(true);
+ else if (resolution_options.a_suggestions.argument() == "display")
+ interest_in_spec_helper.set_take_suggestions(indeterminate);
+ else if (resolution_options.a_suggestions.argument() == "ignore")
+ interest_in_spec_helper.set_take_suggestions(false);
+ else
+ throw args::DoHelp("Don't understand argument '" + resolution_options.a_suggestions.argument() + "' to '--"
+ + resolution_options.a_suggestions.long_name() + "'");
+
+ if (resolution_options.a_recommendations.argument() == "take")
+ interest_in_spec_helper.set_take_recommendations(true);
+ else if (resolution_options.a_recommendations.argument() == "display")
+ interest_in_spec_helper.set_take_recommendations(indeterminate);
+ else if (resolution_options.a_recommendations.argument() == "ignore")
+ interest_in_spec_helper.set_take_recommendations(false);
+ else
+ throw args::DoHelp("Don't understand argument '" + resolution_options.a_recommendations.argument() + "' to '--"
+ + resolution_options.a_recommendations.long_name() + "'");
+
ResolverFunctions resolver_functions(make_named_values<ResolverFunctions>(
n::allow_choice_changes_fn() = std::cref(allow_choice_changes_helper),
n::allowed_to_remove_fn() = std::cref(allowed_to_remove_helper),
@@ -1552,10 +1380,7 @@ paludis::cave::resolve_common(
env.get(), std::cref(resolution_options), _1, _2, _3, DestinationTypes()),
n::get_use_existing_nothing_fn() = std::bind(&use_existing_nothing_fn,
env.get(), std::cref(resolution_options), std::cref(without), std::cref(with), _1, _2, _3),
- n::interest_in_spec_fn() = std::bind(&interest_in_spec_fn,
- env.get(), std::cref(resolution_options), std::cref(take), std::cref(take_from),
- std::cref(ignore), std::cref(ignore_from), std::cref(no_blockers_from),
- std::cref(no_dependencies_from), _1, _2),
+ n::interest_in_spec_fn() = std::cref(interest_in_spec_helper),
n::make_destination_filtered_generator_fn() = std::cref(make_destination_filtered_generator_helper),
n::make_origin_filtered_generator_fn() = std::cref(make_origin_filtered_generator_helper),
n::make_unmaskable_filter_fn() = std::cref(make_unmaskable_filter_helper),