aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-23 15:35:53 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-23 15:35:53 +0100
commit8d1870f26c4fe3b34fb90d252722338b90c70fc4 (patch)
tree58119225a13e21c36c24d519e0fb195e5d0defe5
parent2e1e4f1f5145844ad26af14cd429f86a31978355 (diff)
downloadpaludis-8d1870f26c4fe3b34fb90d252722338b90c70fc4.tar.gz
paludis-8d1870f26c4fe3b34fb90d252722338b90c70fc4.tar.xz
more destinations
-rw-r--r--paludis/resolver/resolver.cc57
-rw-r--r--paludis/resolver/resolver.hh8
-rw-r--r--paludis/resolver/resolver_functions.hh26
-rw-r--r--paludis/resolver/resolver_test.cc28
-rw-r--r--paludis/resolver/resolver_test.hh7
-rw-r--r--src/clients/cave/cmd_resolve.cc57
6 files changed, 131 insertions, 52 deletions
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index 9e1e66e..fae5e11 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -201,16 +201,13 @@ Resolver::_make_destination_for(
return make_null_shared_ptr();
case dk_changes_to_make:
- switch (resolvent.destination_type())
{
- case dt_slash:
- return _make_slash_destination_for(resolvent, resolution);
- break;
-
- case last_dt:
- break;
+ const std::tr1::shared_ptr<const Repository> repo(_find_repository_for(resolvent, resolution));
+ return make_shared_ptr(new Destination(make_named_values<Destination>(
+ value_for<n::replacing>(_find_replacing(resolution->decision()->if_package_id(), repo)),
+ value_for<n::repository>(repo->name())
+ )));
}
- break;
case last_dk:
break;
@@ -219,42 +216,16 @@ Resolver::_make_destination_for(
throw InternalError(PALUDIS_HERE, "resolver bug: unhandled dt");
}
-const std::tr1::shared_ptr<Destination>
-Resolver::_make_slash_destination_for(
- const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Resolution> & resolution) const
+const std::tr1::shared_ptr<const Repository>
+Resolver::_find_repository_for(const Resolvent & resolvent, const std::tr1::shared_ptr<const Resolution> & resolution) const
{
- Context context("When finding / destination for '" + stringify(resolvent) + "':");
-
- if ((! resolution->decision()) || (! resolution->decision()->if_package_id()))
- throw InternalError(PALUDIS_HERE, "resolver bug: not decided yet");
-
- std::tr1::shared_ptr<const Repository> repo;
- for (PackageDatabase::RepositoryConstIterator r(_imp->env->package_database()->begin_repositories()),
- r_end(_imp->env->package_database()->end_repositories()) ;
- r != r_end ; ++r)
- {
- if ((! (*r)->installed_root_key()) || ((*r)->installed_root_key()->value() != FSEntry("/")))
- continue;
-
- if ((*r)->destination_interface() && (*r)->destination_interface()->is_suitable_destination_for(
- *resolution->decision()->if_package_id()))
- {
- if (repo)
- throw InternalError(PALUDIS_HERE, "unimplemented: multiple destinations, don't know which to take");
- else
- repo = *r;
- }
- }
-
- if (! repo)
- throw InternalError(PALUDIS_HERE, "unimplemented: no destinations" +
- stringify(*resolution->decision()->if_package_id()));
+ return _imp->fns.find_repository_for_fn()(resolvent, resolution);
+}
- return make_shared_ptr(new Destination(make_named_values<Destination>(
- value_for<n::replacing>(_find_replacing(resolution->decision()->if_package_id(), repo)),
- value_for<n::repository>(repo->name())
- )));
+Filter
+Resolver::_make_destination_filter(const Resolvent & resolvent) const
+{
+ return _imp->fns.make_destination_filter_fn()(resolvent);
}
const std::tr1::shared_ptr<const PackageIDSequence>
@@ -1472,7 +1443,7 @@ Resolver::_find_existing_id_for(const Resolvent & resolvent, const std::tr1::sha
const std::tr1::shared_ptr<const PackageIDSequence> ids((*_imp->env)[selection::AllVersionsSorted(
generator::Package(resolvent.package()) |
make_slot_filter(resolvent) |
- filter::InstalledAtRoot(FSEntry("/"))
+ _make_destination_filter(resolvent)
)]);
return _find_id_for_from(resolvent, resolution, ids).first;
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index c8fdea9..2d12d60 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -105,6 +105,10 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const Repository> &) const;
+ const std::tr1::shared_ptr<const Repository> _find_repository_for(
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &) const;
+
void _resolve_arrow(const Resolvent &, const std::tr1::shared_ptr<Resolution> &,
const std::tr1::shared_ptr<const Constraint> &);
@@ -117,9 +121,7 @@ namespace paludis
const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution) const;
- const std::tr1::shared_ptr<Destination> _make_slash_destination_for(
- const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Resolution> & resolution) const;
+ Filter _make_destination_filter(const Resolvent & resolvent) const;
void _decide(const Resolvent &, const std::tr1::shared_ptr<Resolution> & resolution);
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index 5b81d99..09cdf64 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -26,6 +26,7 @@
#include <paludis/resolver/resolvent-fwd.hh>
#include <paludis/resolver/reason-fwd.hh>
#include <paludis/util/named_value.hh>
+#include <paludis/filter-fwd.hh>
#include <tr1/functional>
namespace paludis
@@ -33,9 +34,11 @@ namespace paludis
namespace n
{
struct care_about_dep_fn;
+ struct find_repository_for_fn;
struct get_initial_constraints_for_fn;
struct get_resolvents_for_fn;
struct get_use_existing_fn;
+ struct make_destination_filter_fn;
struct take_dependency_fn;
}
@@ -47,6 +50,11 @@ namespace paludis
const SanitisedDependency &
)> CareAboutDepFunction;
+ typedef std::tr1::function<const std::tr1::shared_ptr<const Repository> (
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &
+ )> FindRepositoryForFunction;
+
typedef std::tr1::function<std::tr1::shared_ptr<Constraints> (
const Resolvent &
)> GetInitialConstraintsFunction;
@@ -56,24 +64,30 @@ namespace paludis
const std::tr1::shared_ptr<const Reason> &
)> GetResolventsForFunction;
- typedef std::tr1::function<bool (
- const Resolvent &,
- const SanitisedDependency &,
- const std::tr1::shared_ptr<const Reason> &
- )> TakeDependencyFunction;
-
typedef std::tr1::function<UseExisting (
const Resolvent &,
const PackageDepSpec &,
const std::tr1::shared_ptr<const Reason> &
)> GetUseExistingFunction;
+ typedef std::tr1::function<Filter (
+ const Resolvent &
+ )> MakeDestinationFilterFunction;
+
+ typedef std::tr1::function<bool (
+ const Resolvent &,
+ const SanitisedDependency &,
+ const std::tr1::shared_ptr<const Reason> &
+ )> TakeDependencyFunction;
+
struct ResolverFunctions
{
NamedValue<n::care_about_dep_fn, CareAboutDepFunction> care_about_dep_fn;
+ NamedValue<n::find_repository_for_fn, FindRepositoryForFunction> find_repository_for_fn;
NamedValue<n::get_initial_constraints_for_fn, GetInitialConstraintsFunction> get_initial_constraints_for_fn;
NamedValue<n::get_resolvents_for_fn, GetResolventsForFunction> get_resolvents_for_fn;
NamedValue<n::get_use_existing_fn, GetUseExistingFunction> get_use_existing_fn;
+ NamedValue<n::make_destination_filter_fn, MakeDestinationFilterFunction> make_destination_filter_fn;
NamedValue<n::take_dependency_fn, TakeDependencyFunction> take_dependency_fn;
};
}
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index 8978ac9..fb83ddc 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -38,6 +38,7 @@
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
#include <paludis/user_dep_spec.hh>
+#include <paludis/filter.hh>
#include <algorithm>
#include "config.h"
@@ -84,6 +85,21 @@ paludis::resolver::resolver_test::get_resolvents_for_fn(const PackageDepSpec & s
return result;
}
+Filter
+paludis::resolver::resolver_test::make_destination_filter_fn(const Resolvent & resolvent)
+{
+ switch (resolvent.destination_type())
+ {
+ case dt_slash:
+ return filter::InstalledAtRoot(FSEntry("/"));
+
+ case last_dt:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "unhandled dt");
+}
+
namespace
{
struct IsSuggestionVisitor
@@ -164,6 +180,15 @@ paludis::resolver::resolver_test::get_use_existing_fn(
return ue_never;
}
+const std::tr1::shared_ptr<const Repository>
+paludis::resolver::resolver_test::find_repository_for_fn(
+ const Environment * const env,
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &)
+{
+ return env->package_database()->fetch_repository(RepositoryName("installed"));
+}
+
ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s, const std::string & e,
const std::string & l) :
TestCase(s)
@@ -213,11 +238,14 @@ ResolverTestCase::get_resolutions(const PackageDepSpec & target)
{
Resolver resolver(&env, make_named_values<ResolverFunctions>(
value_for<n::care_about_dep_fn>(&care_about_dep_fn),
+ value_for<n::find_repository_for_fn>(std::tr1::bind(&find_repository_for_fn,
+ &env, std::tr1::placeholders::_1, std::tr1::placeholders::_2)),
value_for<n::get_initial_constraints_for_fn>(
std::tr1::bind(&initial_constraints_for_fn, std::tr1::ref(initial_constraints),
std::tr1::placeholders::_1)),
value_for<n::get_resolvents_for_fn>(&get_resolvents_for_fn),
value_for<n::get_use_existing_fn>(&get_use_existing_fn),
+ value_for<n::make_destination_filter_fn>(&make_destination_filter_fn),
value_for<n::take_dependency_fn>(&take_dependency_fn)
));
resolver.add_target(target);
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index e1c659f..2a13559 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -70,6 +70,13 @@ namespace paludis
const PackageDepSpec &,
const std::tr1::shared_ptr<const Reason> &);
+ const std::tr1::shared_ptr<const Repository> find_repository_for_fn(
+ const Environment * const,
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &);
+
+ Filter make_destination_filter_fn(const Resolvent &);
+
struct ResolverTestCase : test::TestCase
{
TestEnvironment env;
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index 3a8aa78..5deb4e6 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -52,6 +52,7 @@
#include <paludis/metadata_key.hh>
#include <paludis/environment.hh>
#include <paludis/match_package.hh>
+#include <paludis/package_database.hh>
#include <algorithm>
#include <iostream>
@@ -528,6 +529,59 @@ namespace
return true;
}
+ const std::tr1::shared_ptr<const Repository>
+ find_repository_for_fn(const Environment * const env,
+ const ResolveCommandLine &,
+ const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const Resolution> & resolution)
+ {
+ std::tr1::shared_ptr<const Repository> result;
+ for (PackageDatabase::RepositoryConstIterator r(env->package_database()->begin_repositories()),
+ r_end(env->package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ {
+ switch (resolvent.destination_type())
+ {
+ case dt_slash:
+ if ((! (*r)->installed_root_key()) || ((*r)->installed_root_key()->value() != FSEntry("/")))
+ continue;
+
+ case last_dt:
+ break;
+ }
+
+ if ((*r)->destination_interface() &&
+ (*r)->destination_interface()->is_suitable_destination_for(*resolution->decision()->if_package_id()))
+ {
+ if (result)
+ throw ConfigurationError("For '" + stringify(*resolution->decision()->if_package_id())
+ + "' with destination type " + stringify(resolvent.destination_type())
+ + ", don't know whether to install to ::" + stringify(result->name())
+ + " or ::" + stringify((*r)->name()));
+ else
+ result = *r;
+ }
+ }
+
+ if (! result)
+ throw ConfigurationError("No repository suitable for '" + stringify(*resolution->decision()->if_package_id())
+ + "' with destination type " + stringify(resolvent.destination_type()) + " has been configured");
+ return result;
+ }
+
+ Filter make_destination_filter_fn(const Resolvent & resolvent)
+ {
+ switch (resolvent.destination_type())
+ {
+ case dt_slash:
+ return filter::InstalledAtRoot(FSEntry("/"));
+
+ case last_dt:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "unhandled dt");
+ }
int display_resolution(
const std::tr1::shared_ptr<Environment> &,
@@ -693,12 +747,15 @@ ResolveCommand::run(
value_for<n::care_about_dep_fn>(std::tr1::bind(&care_about_dep_fn,
env.get(), std::tr1::cref(cmdline), std::tr1::placeholders::_1,
std::tr1::placeholders::_2, std::tr1::placeholders::_3)),
+ value_for<n::find_repository_for_fn>(std::tr1::bind(&find_repository_for_fn,
+ env.get(), std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2)),
value_for<n::get_initial_constraints_for_fn>(std::tr1::bind(&initial_constraints_for_fn,
env.get(), std::tr1::cref(cmdline), std::tr1::cref(initial_constraints), std::tr1::placeholders::_1)),
value_for<n::get_resolvents_for_fn>(std::tr1::bind(&get_resolvents_for_fn,
env.get(), std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2)),
value_for<n::get_use_existing_fn>(std::tr1::bind(&use_existing_fn,
std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2, std::tr1::placeholders::_3)),
+ value_for<n::make_destination_filter_fn>(&make_destination_filter_fn),
value_for<n::take_dependency_fn>(std::tr1::bind(&take_dependency_fn, env.get(),
std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2, std::tr1::placeholders::_3))