aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-23 20:02:37 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-23 20:02:37 +0100
commitb3088c2915041463e9ff8fed77e33559bfc29683 (patch)
treebb8275443b84b6c5f83d42d648e590416ecb66cc
parent322f4f6637e7dab4fcd1a99a807fe52093e6c3ce (diff)
downloadpaludis-b3088c2915041463e9ff8fed77e33559bfc29683.tar.gz
paludis-b3088c2915041463e9ff8fed77e33559bfc29683.tar.xz
start binaries
-rw-r--r--paludis/resolver/destination_types.se3
-rw-r--r--paludis/resolver/resolver.cc53
-rw-r--r--paludis/resolver/resolver.hh7
-rw-r--r--paludis/resolver/resolver_functions.hh17
-rw-r--r--paludis/resolver/resolver_test.cc25
-rw-r--r--paludis/resolver/resolver_test.hh8
-rw-r--r--src/clients/cave/cmd_display_resolution.cc37
-rw-r--r--src/clients/cave/cmd_execute_resolution.cc2
-rw-r--r--src/clients/cave/cmd_resolve.cc177
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.cc11
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.hh6
11 files changed, 255 insertions, 91 deletions
diff --git a/paludis/resolver/destination_types.se b/paludis/resolver/destination_types.se
index 0fa1bc9..15a35e8 100644
--- a/paludis/resolver/destination_types.se
+++ b/paludis/resolver/destination_types.se
@@ -6,7 +6,8 @@ make_enum_DestinationType()
prefix dt
namespace paludis::resolver
- key dt_slash "The / fs"
+ key dt_install_to_slash "Install to the / fs"
+ key dt_create_binary "Create a binary"
want_destringify
}
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index 0cf96a3..a7a1222 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -203,6 +203,11 @@ Resolver::_make_destination_for(
case dk_changes_to_make:
{
const std::tr1::shared_ptr<const Repository> repo(_find_repository_for(resolvent, resolution));
+ if ((! repo->destination_interface()) ||
+ (! repo->destination_interface()->is_suitable_destination_for(*resolution->decision()->if_package_id())))
+ throw InternalError(PALUDIS_HERE, stringify(repo->name()) + " is not a suitable destination for "
+ + stringify(*resolution->decision()->if_package_id()));
+
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())
@@ -222,10 +227,10 @@ Resolver::_find_repository_for(const Resolvent & resolvent, const std::tr1::shar
return _imp->fns.find_repository_for_fn()(resolvent, resolution);
}
-Filter
-Resolver::_make_destination_filter(const Resolvent & resolvent) const
+FilteredGenerator
+Resolver::_make_destination_filtered_generator(const Generator & g, const Resolvent & resolvent) const
{
- return _imp->fns.make_destination_filter_fn()(resolvent);
+ return _imp->fns.make_destination_filtered_generator_fn()(g, resolvent);
}
const std::tr1::shared_ptr<const PackageIDSequence>
@@ -381,7 +386,7 @@ Resolver::_make_constraints_from_target(
{
const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
- value_for<n::destination_type>(dt_slash),
+ value_for<n::destination_type>(resolvent.destination_type()),
value_for<n::nothing_is_fine_too>(false),
value_for<n::reason>(reason),
value_for<n::spec>(spec),
@@ -399,7 +404,7 @@ Resolver::_make_constraints_from_dependency(const Resolvent & resolvent, const S
if (dep.spec().if_package())
{
result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
- value_for<n::destination_type>(dt_slash),
+ value_for<n::destination_type>(resolvent.destination_type()),
value_for<n::nothing_is_fine_too>(false),
value_for<n::reason>(reason),
value_for<n::spec>(*dep.spec().if_package()),
@@ -416,14 +421,17 @@ Resolver::_make_constraints_from_dependency(const Resolvent & resolvent, const S
generator::Matches(dep.spec().if_block()->blocking(), MatchPackageOptions()) |
filter::InstalledAtRoot(FSEntry("/")))]);
- result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
- value_for<n::destination_type>(dt_slash),
- value_for<n::nothing_is_fine_too>(ids->empty()),
- value_for<n::reason>(reason),
- value_for<n::spec>(dep.spec()),
- value_for<n::untaken>(false),
- value_for<n::use_existing>(ue_if_possible)
- ))));
+ DestinationTypes destination_types(_get_destination_types_for_blocker(*dep.spec().if_block()));
+ for (EnumIterator<DestinationType> t, t_end(last_dt) ; t != t_end ; ++t)
+ if (destination_types[*t])
+ result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
+ value_for<n::destination_type>(*t),
+ value_for<n::nothing_is_fine_too>(ids->empty()),
+ value_for<n::reason>(reason),
+ value_for<n::spec>(dep.spec()),
+ value_for<n::untaken>(false),
+ value_for<n::use_existing>(ue_if_possible)
+ ))));
}
else
throw InternalError(PALUDIS_HERE, "resolver bug: huh? it's not a block and it's not a package");
@@ -535,14 +543,13 @@ Resolver::_suggest_restart_with(const Resolvent & resolvent,
const std::tr1::shared_ptr<const Decision> & decision) const
{
throw SuggestRestart(resolvent, resolution->decision(), constraint, decision,
- _make_constraint_for_preloading(resolvent, decision, constraint->destination_type()));
+ _make_constraint_for_preloading(resolvent, decision));
}
const std::tr1::shared_ptr<const Constraint>
Resolver::_make_constraint_for_preloading(
const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Decision> & d,
- const DestinationType t) const
+ const std::tr1::shared_ptr<const Decision> & d) const
{
const std::tr1::shared_ptr<PresetReason> reason(new PresetReason);
@@ -550,7 +557,7 @@ Resolver::_make_constraint_for_preloading(
throw InternalError(PALUDIS_HERE, "resolver bug: not decided. shouldn't happen.");
return make_shared_ptr(new Constraint(make_named_values<Constraint>(
- value_for<n::destination_type>(t),
+ value_for<n::destination_type>(resolvent.destination_type()),
value_for<n::nothing_is_fine_too>(false),
value_for<n::reason>(reason),
value_for<n::spec>(d->if_package_id()->uniquely_identifying_spec()),
@@ -1166,7 +1173,7 @@ Resolver::_get_resolvents_for_blocker(const BlockDepSpec & spec) const
const DestinationTypes
Resolver::_get_destination_types_for_blocker(const BlockDepSpec &) const
{
- return DestinationTypes() + dt_slash;
+ return DestinationTypes() + dt_install_to_slash;
}
const std::tr1::shared_ptr<const Resolvents>
@@ -1198,9 +1205,10 @@ Resolver::_get_resolvents_for(
}
const DestinationTypes
-Resolver::_get_destination_types_for(const PackageDepSpec &, const std::tr1::shared_ptr<const Reason> &) const
+Resolver::_get_destination_types_for(const PackageDepSpec & spec,
+ const std::tr1::shared_ptr<const Reason> & reason) const
{
- return DestinationTypes() + dt_slash;
+ return _imp->fns.get_destination_types_for_fn()(spec, reason);
}
const std::tr1::shared_ptr<const Resolvents>
@@ -1458,9 +1466,8 @@ const std::tr1::shared_ptr<const PackageID>
Resolver::_find_existing_id_for(const Resolvent & resolvent, const std::tr1::shared_ptr<const Resolution> & resolution) const
{
const std::tr1::shared_ptr<const PackageIDSequence> ids((*_imp->env)[selection::AllVersionsSorted(
- generator::Package(resolvent.package()) |
- make_slot_filter(resolvent) |
- _make_destination_filter(resolvent)
+ _make_destination_filtered_generator(generator::Package(resolvent.package()), resolvent) |
+ make_slot_filter(resolvent)
)]);
return _find_id_for_from(resolvent, resolution, ids).first;
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index 2d12d60..2e5ed2c 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -40,6 +40,8 @@
#include <paludis/environment-fwd.hh>
#include <paludis/repository-fwd.hh>
#include <paludis/spec_tree-fwd.hh>
+#include <paludis/filtered_generator-fwd.hh>
+#include <paludis/generator-fwd.hh>
#include <tr1/memory>
namespace paludis
@@ -98,8 +100,7 @@ namespace paludis
const std::tr1::shared_ptr<const Constraint> _make_constraint_for_preloading(
const Resolvent &,
- const std::tr1::shared_ptr<const Decision> & d,
- const DestinationType t) const;
+ const std::tr1::shared_ptr<const Decision> & d) const;
const std::tr1::shared_ptr<const PackageIDSequence> _find_replacing(
const std::tr1::shared_ptr<const PackageID> &,
@@ -121,7 +122,7 @@ namespace paludis
const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution) const;
- Filter _make_destination_filter(const Resolvent & resolvent) const;
+ FilteredGenerator _make_destination_filtered_generator(const Generator &, 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 09cdf64..86bbace 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -35,10 +35,11 @@ namespace paludis
{
struct care_about_dep_fn;
struct find_repository_for_fn;
+ struct get_destination_types_for_fn;
struct get_initial_constraints_for_fn;
struct get_resolvents_for_fn;
struct get_use_existing_fn;
- struct make_destination_filter_fn;
+ struct make_destination_filtered_generator_fn;
struct take_dependency_fn;
}
@@ -55,6 +56,11 @@ namespace paludis
const std::tr1::shared_ptr<const Resolution> &
)> FindRepositoryForFunction;
+ typedef std::tr1::function<DestinationTypes (
+ const PackageDepSpec &,
+ const std::tr1::shared_ptr<const Reason> &
+ )> GetDestinationTypesForFunction;
+
typedef std::tr1::function<std::tr1::shared_ptr<Constraints> (
const Resolvent &
)> GetInitialConstraintsFunction;
@@ -70,9 +76,10 @@ namespace paludis
const std::tr1::shared_ptr<const Reason> &
)> GetUseExistingFunction;
- typedef std::tr1::function<Filter (
+ typedef std::tr1::function<FilteredGenerator (
+ const Generator &,
const Resolvent &
- )> MakeDestinationFilterFunction;
+ )> MakeDestinationFilteredGeneratorFunction;
typedef std::tr1::function<bool (
const Resolvent &,
@@ -84,10 +91,12 @@ namespace paludis
{
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_destination_types_for_fn, GetDestinationTypesForFunction> get_destination_types_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::make_destination_filtered_generator_fn,
+ MakeDestinationFilteredGeneratorFunction> make_destination_filtered_generator_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 fb83ddc..518f228 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -39,6 +39,8 @@
#include <paludis/package_database.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/filter.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/generator.hh>
#include <algorithm>
#include "config.h"
@@ -81,17 +83,20 @@ paludis::resolver::resolver_test::get_resolvents_for_fn(const PackageDepSpec & s
const std::tr1::shared_ptr<const Reason> &)
{
std::tr1::shared_ptr<Resolvents> result(new Resolvents);
- result->push_back(Resolvent(spec, make_shared_ptr(new SlotName("0")), dt_slash));
+ result->push_back(Resolvent(spec, make_shared_ptr(new SlotName("0")), dt_install_to_slash));
return result;
}
-Filter
-paludis::resolver::resolver_test::make_destination_filter_fn(const Resolvent & resolvent)
+FilteredGenerator
+paludis::resolver::resolver_test::make_destination_filtered_generator_fn(const Generator & g, const Resolvent & resolvent)
{
switch (resolvent.destination_type())
{
- case dt_slash:
- return filter::InstalledAtRoot(FSEntry("/"));
+ case dt_install_to_slash:
+ return g | filter::InstalledAtRoot(FSEntry("/"));
+
+ case dt_create_binary:
+ throw InternalError(PALUDIS_HERE, "no dt_create_binary yet");
case last_dt:
break;
@@ -100,6 +105,13 @@ paludis::resolver::resolver_test::make_destination_filter_fn(const Resolvent & r
throw InternalError(PALUDIS_HERE, "unhandled dt");
}
+DestinationTypes
+paludis::resolver::resolver_test::get_destination_types_for_fn(const PackageDepSpec &,
+ const std::tr1::shared_ptr<const Reason> &)
+{
+ return DestinationTypes() + dt_install_to_slash;
+}
+
namespace
{
struct IsSuggestionVisitor
@@ -240,12 +252,13 @@ ResolverTestCase::get_resolutions(const PackageDepSpec & target)
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_destination_types_for_fn>(&get_destination_types_for_fn),
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::make_destination_filtered_generator_fn>(&make_destination_filtered_generator_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 2a13559..170b822 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -28,10 +28,13 @@
#include <paludis/resolver/use_existing-fwd.hh>
#include <paludis/resolver/resolutions-fwd.hh>
#include <paludis/resolver/decision-fwd.hh>
+#include <paludis/resolver/destination_types-fwd.hh>
#include <paludis/repositories/fake/fake_installed_repository.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/map-fwd.hh>
#include <paludis/dep_spec-fwd.hh>
+#include <paludis/filtered_generator-fwd.hh>
+#include <paludis/generator-fwd.hh>
#include <test/test_framework.hh>
#include <tr1/memory>
#include <string>
@@ -75,7 +78,10 @@ namespace paludis
const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &);
- Filter make_destination_filter_fn(const Resolvent &);
+ FilteredGenerator make_destination_filtered_generator_fn(const Generator &, const Resolvent &);
+
+ DestinationTypes get_destination_types_for_fn(const PackageDepSpec &,
+ const std::tr1::shared_ptr<const Reason> &);
struct ResolverTestCase : test::TestCase
{
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index b10c768..235bc14 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -223,9 +223,9 @@ namespace
const bool verbose)
{
if (resolution->resolvent().slot_name_or_null())
- cout << "[?] " << c::bold_red() << resolution->resolvent() << c::normal();
+ cout << "? ] " << c::bold_red() << resolution->resolvent() << c::normal();
else
- cout << "[?] " << c::bold_red() << resolution->resolvent().package() << c::normal();
+ cout << "? ] " << c::bold_red() << resolution->resolvent().package() << c::normal();
cout << " (no decision could be reached)" << endl;
display_reasons(resolution, verbose);
@@ -282,23 +282,38 @@ namespace
is_upgrade = is_upgrade && (! is_reinstall) && (! is_downgrade);
is_reinstall = is_reinstall && (! is_downgrade);
+ std::string destination_string(c::red() + "/" + c::normal());
+ switch ((*c)->resolvent().destination_type())
+ {
+ case dt_install_to_slash:
+ destination_string = "/";
+ break;
+
+ case dt_create_binary:
+ destination_string = "b";
+ break;
+
+ case last_dt:
+ break;
+ }
+
if (! (*c)->decision()->taken())
{
- cout << "[-] " << c::blue() << id->canonical_form(idcf_no_version);
+ cout << "-" << destination_string << "] " << c::blue() << id->canonical_form(idcf_no_version);
}
else if (is_new)
{
if (other_slots)
- cout << "[s] " << c::bold_blue() << id->canonical_form(idcf_no_version);
+ cout << "s" << destination_string << "] " << c::bold_blue() << id->canonical_form(idcf_no_version);
else
- cout << "[n] " << c::bold_blue() << id->canonical_form(idcf_no_version);
+ cout << "n" << destination_string << "] " << c::bold_blue() << id->canonical_form(idcf_no_version);
}
else if (is_upgrade)
- cout << "[u] " << c::blue() << id->canonical_form(idcf_no_version);
+ cout << "u" << destination_string << "] " << c::blue() << id->canonical_form(idcf_no_version);
else if (is_reinstall)
- cout << "[r] " << c::yellow() << id->canonical_form(idcf_no_version);
+ cout << "r" << destination_string << "] " << c::yellow() << id->canonical_form(idcf_no_version);
else if (is_downgrade)
- cout << "[d] " << c::bold_yellow() << id->canonical_form(idcf_no_version);
+ cout << "d" << destination_string << "] " << c::bold_yellow() << id->canonical_form(idcf_no_version);
else
throw InternalError(PALUDIS_HERE, "why did that happen?");
@@ -613,10 +628,14 @@ namespace
switch ((*c)->destination_type())
{
- case dt_slash:
+ case dt_install_to_slash:
std::cout << ", installing to /";
break;
+ case dt_create_binary:
+ std::cout << ", creating a binary";
+ break;
+
case last_dt:
break;
}
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc
index 9411f57..c4d3949 100644
--- a/src/clients/cave/cmd_execute_resolution.cc
+++ b/src/clients/cave/cmd_execute_resolution.cc
@@ -292,7 +292,7 @@ namespace
if (0 != retcode)
return retcode;
- if ((*c)->resolvent().destination_type() == dt_slash)
+ if ((*c)->resolvent().destination_type() == dt_install_to_slash)
{
retcode = do_install_slash(env, cmdline, *c, x, y);
if (0 != retcode)
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index 5888d08..63af523 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -29,6 +29,7 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/system.hh>
+#include <paludis/util/enum_iterator.hh>
#include <paludis/args/do_help.hh>
#include <paludis/args/escape.hh>
#include <paludis/resolver/resolver.hh>
@@ -68,18 +69,91 @@ using std::endl;
namespace
{
- Filter make_destination_filter(const DestinationType t)
+ struct DestinationTypesFinder
{
- switch (t)
+ const ResolveCommandLine & cmdline;
+
+ DestinationTypesFinder(const ResolveCommandLine & c) :
+ cmdline(c)
{
- case dt_slash:
- return filter::InstalledAtRoot(FSEntry("/"));
+ }
+
+ DestinationTypes visit(const TargetReason &) const
+ {
+ DestinationTypes result;
+
+ if (cmdline.resolution_options.a_create_binaries.specified())
+ result += dt_create_binary;
+ if (cmdline.resolution_options.a_install_to_root.specified())
+ result += dt_install_to_slash;
+
+ if (result.none())
+ result += dt_install_to_slash;
+
+ return result;
+ }
+
+ DestinationTypes visit(const DependencyReason &) const
+ {
+ return DestinationTypes() + dt_install_to_slash;
+ }
+
+ DestinationTypes visit(const PresetReason &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "not sure what to do here yet");
+ }
+
+ 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 ResolveCommandLine & cmdline,
+ const PackageDepSpec &,
+ const std::tr1::shared_ptr<const Reason> & reason)
+ {
+ DestinationTypesFinder f(cmdline);
+ return reason->accept_returning<DestinationTypes>(f);
+ }
+
+ FilteredGenerator make_destination_filtered_generator(
+ const Environment * const,
+ const ResolveCommandLine & cmdline,
+ const Generator & g,
+ const Resolvent & r)
+ {
+ switch (r.destination_type())
+ {
+ case dt_install_to_slash:
+ return g | filter::InstalledAtRoot(FSEntry("/"));
+
+ case dt_create_binary:
+ {
+ std::tr1::shared_ptr<Generator> generator;
+ for (args::StringSetArg::ConstIterator a(cmdline.resolution_options.a_create_binaries.begin_args()),
+ a_end(cmdline.resolution_options.a_create_binaries.end_args()) ;
+ a != a_end ; ++a)
+ {
+ if (! generator)
+ generator.reset(new generator::InRepository(RepositoryName(*a)));
+ else
+ generator.reset(new generator::Intersection(*generator, generator::InRepository(RepositoryName(*a))));
+ }
+
+ if (! generator)
+ throw args::DoHelp("No binary destinations were specified");
+ else
+ return g & *generator;
+ }
case last_dt:
break;
}
- throw InternalError(PALUDIS_HERE, stringify(t));
+ throw InternalError(PALUDIS_HERE, stringify(r.destination_type()));
}
void add_resolver_targets(
@@ -235,14 +309,14 @@ namespace
return false;
}
- bool installed_is_scm_older_than(const Environment * const env, const Resolvent & q, const int n)
+ bool installed_is_scm_older_than(const Environment * const env, const ResolveCommandLine & cmdline,
+ const Resolvent & q, const int n)
{
Context context("When working out whether '" + stringify(q) + "' has installed SCM packages:");
const std::tr1::shared_ptr<const PackageIDSequence> ids((*env)[selection::AllVersionsUnsorted(
- generator::Package(q.package()) |
- make_slot_filter(q) |
- make_destination_filter(q.destination_type())
+ make_destination_filtered_generator(env, cmdline, generator::Package(q.package()), q) |
+ make_slot_filter(q)
)]);
for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
@@ -265,10 +339,10 @@ namespace
const std::tr1::shared_ptr<Constraints> result(new Constraints);
int n(reinstall_scm_days(cmdline));
- if ((-1 != n) && installed_is_scm_older_than(env, resolvent, n))
+ if ((-1 != n) && installed_is_scm_older_than(env, cmdline, resolvent, n))
{
result->add(make_shared_ptr(new Constraint(make_named_values<Constraint>(
- value_for<n::destination_type>(dt_slash),
+ value_for<n::destination_type>(resolvent.destination_type()),
value_for<n::nothing_is_fine_too>(false),
value_for<n::reason>(make_shared_ptr(new PresetReason)),
value_for<n::spec>(make_package_dep_spec(PartiallyMadePackageDepSpecOptions()).package(resolvent.package())),
@@ -328,9 +402,8 @@ namespace
const PackageDepSpec & spec,
const std::tr1::shared_ptr<const Reason> & reason)
{
- std::tr1::shared_ptr<Resolvents> result(new Resolvents);
- std::tr1::shared_ptr<Resolvent> best;
- std::list<Resolvent> installed;
+ std::tr1::shared_ptr<PackageIDSequence> result_ids(new PackageIDSequence);
+ std::tr1::shared_ptr<const PackageID> best;
const std::tr1::shared_ptr<const PackageIDSequence> ids((*env)[selection::BestVersionOnly(
generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
@@ -338,46 +411,54 @@ namespace
filter::NotMasked())]);
if (! ids->empty())
- best = make_shared_ptr(new Resolvent(*ids->begin(), dt_slash));
+ best = *ids->begin();
const std::tr1::shared_ptr<const PackageIDSequence> installed_ids((*env)[selection::BestVersionInEachSlot(
generator::Matches(spec, MatchPackageOptions()) |
filter::InstalledAtRoot(FSEntry("/")))]);
- for (PackageIDSequence::ConstIterator i(installed_ids->begin()), i_end(installed_ids->end()) ;
- i != i_end ; ++i)
- installed.push_back(Resolvent(*i, dt_slash));
-
const args::EnumArg & arg(is_target(reason) ? cmdline.resolution_options.a_target_slots : cmdline.resolution_options.a_slots);
if (! best)
- std::copy(installed.begin(), installed.end(), result->back_inserter());
+ std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter());
else if (arg.argument() == "best-or-installed")
{
- if (installed.end() == std::find(installed.begin(), installed.end(), *best))
- result->push_back(*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);
else
- std::copy(installed.begin(), installed.end(), result->back_inserter());
+ std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter());
}
else if (arg.argument() == "installed-or-best")
{
- if (installed.empty())
- result->push_back(*best);
+ if (installed_ids->empty())
+ result_ids->push_back(best);
else
- std::copy(installed.begin(), installed.end(), result->back_inserter());
+ std::copy(installed_ids->begin(), installed_ids->end(), result_ids->back_inserter());
}
else if (arg.argument() == "all")
{
- if (installed.end() == std::find(installed.begin(), installed.end(), *best))
- result->push_back(*best);
- std::copy(installed.begin(), installed.end(), result->back_inserter());
+ 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 (arg.argument() == "best")
- result->push_back(*best);
+ result_ids->push_back(best);
else
throw args::DoHelp("Don't understand argument '" + arg.argument() + "' to '--"
+ arg.long_name() + "'");
+ std::tr1::shared_ptr<Resolvents> result(new 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(env, cmdline, spec, 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;
}
@@ -531,7 +612,7 @@ namespace
const std::tr1::shared_ptr<const Repository>
find_repository_for_fn(const Environment * const env,
- const ResolveCommandLine &,
+ const ResolveCommandLine & cmdline,
const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution)
{
@@ -542,9 +623,18 @@ namespace
{
switch (resolvent.destination_type())
{
- case dt_slash:
+ case dt_install_to_slash:
if ((! (*r)->installed_root_key()) || ((*r)->installed_root_key()->value() != FSEntry("/")))
continue;
+ break;
+
+ case dt_create_binary:
+ if (cmdline.resolution_options.a_create_binaries.end_args() == std::find(
+ cmdline.resolution_options.a_create_binaries.begin_args(),
+ cmdline.resolution_options.a_create_binaries.end_args(),
+ stringify((*r)->name())))
+ continue;
+ break;
case last_dt:
break;
@@ -573,9 +663,12 @@ namespace
{
switch (resolvent.destination_type())
{
- case dt_slash:
+ case dt_install_to_slash:
return filter::InstalledAtRoot(FSEntry("/"));
+ case dt_create_binary:
+ throw InternalError(PALUDIS_HERE, "no dt_create_binary yet");
+
case last_dt:
break;
}
@@ -703,7 +796,6 @@ namespace
}
}
-
bool
ResolveCommand::important() const
{
@@ -769,6 +861,18 @@ ResolveCommand::run(
cmdline.resolution_options.a_follow_installed_build_dependencies.set_specified(true);
}
+ if (cmdline.resolution_options.a_create_binaries.specified())
+ {
+ for (args::StringSetArg::ConstIterator a(cmdline.resolution_options.a_create_binaries.begin_args()),
+ a_end(cmdline.resolution_options.a_create_binaries.end_args()) ;
+ a != a_end ; ++a)
+ {
+ std::tr1::shared_ptr<const Repository> repo(env->package_database()->fetch_repository(RepositoryName(*a)));
+ if (repo->installed_root_key() || ! repo->destination_interface())
+ throw args::DoHelp("Repository '" + *a + "' not suitable for --" + cmdline.resolution_options.a_create_binaries.long_name());
+ }
+ }
+
int retcode(0);
InitialConstraints initial_constraints;
@@ -779,13 +883,16 @@ ResolveCommand::run(
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_destination_types_for_fn>(std::tr1::bind(&get_destination_types_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::make_destination_filtered_generator_fn>(std::tr1::bind(&make_destination_filtered_generator,
+ env.get(), std::tr1::cref(cmdline), std::tr1::placeholders::_1, std::tr1::placeholders::_2)),
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))
diff --git a/src/clients/cave/cmd_resolve_cmdline.cc b/src/clients/cave/cmd_resolve_cmdline.cc
index 1f5f48f..1a68c0d 100644
--- a/src/clients/cave/cmd_resolve_cmdline.cc
+++ b/src/clients/cave/cmd_resolve_cmdline.cc
@@ -161,13 +161,14 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
// "override it. For example, --fixed-preset cat/pkg::installed will force the resolver to use the installed "
// "cat/pkg, generating an error if it cannot."),
//
-// g_destination_options(this, "Destination Options", "Control to which destinations packages are installed. "
-// "If no options from this group are selected, install only to /. Otherwise, install to all of the "
-// "specified destinations, and install to / as necessary to satisfy build dependencies."),
+ g_destination_options(this, "Destination Options", "Control to which destinations packages are installed. "
+ "If no options from this group are selected, install only to /. Otherwise, install to all of the "
+ "specified destinations, and install to / as necessary to satisfy build dependencies."),
// a_fetch(&g_destination_options, "fetch", 'f', "Only fetch packages, do not install anything", true),
-// a_create_binaries(&g_destination_options, "create-binaries", '\0', "Create binary packages", true),
+ a_create_binaries(&g_destination_options, "create-binaries", 'b', "Create binary packages in the specified "
+ "repository. Specify multiple times if different binary destination types are required."),
// a_install_to_chroot(&g_destination_options, "install-to-chroot", '\0', "Install packages to the environment-configured chroot", true),
-// a_install_to_root(&g_destination_options, "install-to-root", '\0', "Install packages to /", true),
+ a_install_to_root(&g_destination_options, "install-to-root", '/', "Install packages to /", true),
g_dump_options(this, "Dump Options", "Dump the resolver's state to stdout after completion, or when an "
"error occurs. For debugging purposes; produces rather a lot of noise."),
diff --git a/src/clients/cave/cmd_resolve_cmdline.hh b/src/clients/cave/cmd_resolve_cmdline.hh
index e29bf25..1f638d9 100644
--- a/src/clients/cave/cmd_resolve_cmdline.hh
+++ b/src/clients/cave/cmd_resolve_cmdline.hh
@@ -83,11 +83,11 @@ namespace paludis
// args::StringSetArg a_soft_preset;
// args::StringSetArg a_fixed_preset;
- // args::ArgsGroup g_destination_options;
+ args::ArgsGroup g_destination_options;
// args::SwitchArg a_fetch;
- // args::SwitchArg a_create_binaries;
+ args::StringSetArg a_create_binaries;
// args::SwitchArg a_install_to_chroot;
- // args::SwitchArg a_install_to_root;
+ args::SwitchArg a_install_to_root;
// args::ArgsGroup g_interactivity_options;
// args::SwitchArg a_interactive;