aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-22 23:56:41 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-22 23:56:41 +0100
commit98720c3fccbdf3ef64c7dd2d7f88039f287e3f7d (patch)
tree2b81830e63c2b47998b495bf132a047395ca0bee
parentcb69a622e2fbb11afb908dbca2c5a9157566320d (diff)
downloadpaludis-98720c3fccbdf3ef64c7dd2d7f88039f287e3f7d.tar.gz
paludis-98720c3fccbdf3ef64c7dd2d7f88039f287e3f7d.tar.xz
Purge support
Fixes: ticket:888
-rw-r--r--paludis/resolver/decider.cc160
-rw-r--r--paludis/resolver/decider.hh16
-rw-r--r--paludis/resolver/resolver_functions.hh8
-rw-r--r--paludis/resolver/resolver_test.cc32
-rw-r--r--paludis/resolver/resolver_test.hh6
-rw-r--r--src/clients/cave/cmd_display_resolution.cc49
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.cc8
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.hh2
-rw-r--r--src/clients/cave/resolve_common.cc40
9 files changed, 312 insertions, 9 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index 809e305..54fa172 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -35,11 +35,13 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/wrapped_output_iterator.hh>
#include <paludis/util/enum_iterator.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/tribool.hh>
+#include <paludis/util/log.hh>
#include <paludis/environment.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/repository.hh>
@@ -1695,9 +1697,16 @@ Decider::resolve()
{
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Deciding"));
_resolve_decide_with_dependencies();
+
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding Dependents"));
- if (! _resolve_dependents())
- break;
+ if (_resolve_dependents())
+ continue;
+
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding Purgeables"));
+ if (_resolve_purges())
+ continue;
+
+ break;
}
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Confirming"));
@@ -1799,4 +1808,151 @@ Decider::_confirm(
resolution->decision()->accept(ConfirmVisitor(_imp->env, _imp->fns, resolution));
}
+bool
+Decider::_resolve_purges()
+{
+ Context context("When finding things to purge:");
+
+ const std::pair<
+ std::tr1::shared_ptr<const PackageIDSequence>,
+ std::tr1::shared_ptr<const PackageIDSequence> > going_away_newly_available(_collect_changing());
+
+ const std::tr1::shared_ptr<PackageIDSet> going_away(new PackageIDSet);
+ std::copy(going_away_newly_available.first->begin(), going_away_newly_available.first->end(), going_away->inserter());
+
+ const std::tr1::shared_ptr<PackageIDSet> newly_available(new PackageIDSet);
+ std::copy(going_away_newly_available.second->begin(), going_away_newly_available.second->end(), newly_available->inserter());
+
+ const std::tr1::shared_ptr<const PackageIDSet> have_now(_collect_installed());
+
+ const std::tr1::shared_ptr<PackageIDSet> have_now_minus_going_away(new PackageIDSet);
+ std::set_difference(have_now->begin(), have_now->end(),
+ going_away->begin(), going_away->end(), have_now_minus_going_away->inserter(), PackageIDSetComparator());
+
+ const std::tr1::shared_ptr<PackageIDSet> will_eventually_have_set(new PackageIDSet);
+ std::copy(have_now_minus_going_away->begin(), have_now_minus_going_away->end(), will_eventually_have_set->inserter());
+ std::copy(newly_available->begin(), newly_available->end(), will_eventually_have_set->inserter());
+
+ const std::tr1::shared_ptr<PackageIDSequence> will_eventually_have(new PackageIDSequence);
+ std::copy(will_eventually_have_set->begin(), will_eventually_have_set->end(), will_eventually_have->back_inserter());
+
+ const std::tr1::shared_ptr<const PackageIDSet> used_originally(_accumulate_deps(going_away, will_eventually_have));
+ const std::tr1::shared_ptr<const PackageIDSet> used_afterwards(_accumulate_deps(newly_available, will_eventually_have));
+
+ const std::tr1::shared_ptr<PackageIDSet> used_originally_and_not_going_away(new PackageIDSet);
+ std::set_difference(used_originally->begin(), used_originally->end(),
+ going_away->begin(), going_away->end(), used_originally_and_not_going_away->inserter(), PackageIDSetComparator());
+
+ const std::tr1::shared_ptr<PackageIDSet> newly_unused(new PackageIDSet);
+ std::set_difference(used_originally_and_not_going_away->begin(), used_originally_and_not_going_away->end(),
+ used_afterwards->begin(), used_afterwards->end(), newly_unused->inserter(), PackageIDSetComparator());
+
+ const std::tr1::shared_ptr<PackageIDSequence> newly_unused_seq(new PackageIDSequence);
+ std::copy(newly_unused->begin(), newly_unused->end(), newly_unused_seq->back_inserter());
+
+ const std::tr1::shared_ptr<PackageIDSet> used_by_unchanging(new PackageIDSet);
+ for (PackageIDSet::ConstIterator u(have_now_minus_going_away->begin()), u_end(have_now_minus_going_away->end()) ;
+ u != u_end ; ++u)
+ {
+ const std::tr1::shared_ptr<const PackageIDSet> used(_collect_depped_upon(*u, newly_unused_seq));
+ std::copy(used->begin(), used->end(), used_by_unchanging->inserter());
+ }
+
+ const std::tr1::shared_ptr<PackageIDSet> newly_really_unused(new PackageIDSet);
+ std::set_difference(newly_unused->begin(), newly_unused->end(),
+ used_by_unchanging->begin(), used_by_unchanging->end(), newly_really_unused->inserter(), PackageIDSetComparator());
+
+ if (newly_really_unused->empty())
+ return false;
+
+ for (PackageIDSet::ConstIterator i(newly_really_unused->begin()), i_end(newly_really_unused->end()) ;
+ i != i_end ; ++i)
+ {
+ const std::tr1::shared_ptr<PackageIDSequence> used_to_use(new PackageIDSequence), star_i_set(new PackageIDSequence);
+ star_i_set->push_back(*i);
+ for (PackageIDSet::ConstIterator g(going_away->begin()), g_end(going_away->end()) ;
+ g != g_end ; ++g)
+ if (! _collect_depped_upon(*g, star_i_set)->empty())
+ used_to_use->push_back(*g);
+
+ Resolvent resolvent(*i, dt_install_to_slash);
+ const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
+ const std::tr1::shared_ptr<const ConstraintSequence> constraints(_make_constraints_for_purge(resolution, *i, used_to_use));
+ for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
+ c != c_end ; ++c)
+ _apply_resolution_constraint(resolution, *c);
+ }
+
+ return true;
+}
+
+const std::tr1::shared_ptr<const PackageIDSet>
+Decider::_collect_installed() const
+{
+ const std::tr1::shared_ptr<const PackageIDSequence> q((*_imp->env)[selection::AllVersionsUnsorted(
+ generator::All() | filter::InstalledAtRoot(FSEntry("/")))]);
+ const std::tr1::shared_ptr<PackageIDSet> result(new PackageIDSet);
+
+ std::copy(q->begin(), q->end(), result->inserter());
+ return result;
+}
+
+const std::tr1::shared_ptr<const PackageIDSet>
+Decider::_accumulate_deps(
+ const std::tr1::shared_ptr<const PackageIDSet> & start,
+ const std::tr1::shared_ptr<const PackageIDSequence> & will_eventually_have) const
+{
+ const std::tr1::shared_ptr<PackageIDSet> result(new PackageIDSet), done(new PackageIDSet);
+ std::copy(start->begin(), start->end(), result->inserter());
+
+ while (result->size() > done->size())
+ {
+ const std::tr1::shared_ptr<PackageIDSet> more(new PackageIDSet);
+ std::set_difference(result->begin(), result->end(), done->begin(), done->end(), more->inserter(), PackageIDSetComparator());
+
+ for (PackageIDSet::ConstIterator i(more->begin()), i_end(more->end()) ;
+ i != i_end ; ++i)
+ {
+ done->insert(*i);
+ const std::tr1::shared_ptr<const PackageIDSet> depped_upon(_collect_depped_upon(*i, will_eventually_have));
+ std::copy(depped_upon->begin(), depped_upon->end(), result->inserter());
+ }
+ }
+
+ return result;
+}
+
+const std::tr1::shared_ptr<const PackageIDSet>
+Decider::_collect_depped_upon(
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & candidates) const
+{
+ DependentChecker c(_imp->env, candidates, make_shared_ptr(new PackageIDSequence));
+ if (id->dependencies_key())
+ id->dependencies_key()->value()->root()->accept(c);
+ else
+ {
+ if (id->build_dependencies_key())
+ id->build_dependencies_key()->value()->root()->accept(c);
+ if (id->run_dependencies_key())
+ id->run_dependencies_key()->value()->root()->accept(c);
+ if (id->post_dependencies_key())
+ id->post_dependencies_key()->value()->root()->accept(c);
+ if (id->suggested_dependencies_key())
+ id->suggested_dependencies_key()->value()->root()->accept(c);
+ }
+
+ const std::tr1::shared_ptr<PackageIDSet> result(new PackageIDSet);
+ std::copy(c.result->begin(), c.result->end(), result->inserter());
+ return result;
+}
+
+const std::tr1::shared_ptr<ConstraintSequence>
+Decider::_make_constraints_for_purge(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & r) const
+{
+ return _imp->fns.get_constraints_for_purge_fn()(resolution, id, r);
+}
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index 3e1a87e..cbdac4a 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -94,6 +94,11 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const PackageIDSequence> &) const;
+ const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_for_purge(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &) const;
+
void _apply_resolution_constraint(
const std::tr1::shared_ptr<Resolution> &,
const std::tr1::shared_ptr<const Constraint> &);
@@ -131,6 +136,7 @@ namespace paludis
void _resolve_decide_with_dependencies();
bool _resolve_dependents() PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool _resolve_purges() PALUDIS_ATTRIBUTE((warn_unused_result));
void _resolve_destinations();
void _resolve_confirmations();
@@ -217,6 +223,16 @@ namespace paludis
void _confirm(const std::tr1::shared_ptr<const Resolution> & resolution);
+ const std::tr1::shared_ptr<const PackageIDSet> _collect_installed() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ const std::tr1::shared_ptr<const PackageIDSet> _accumulate_deps(
+ const std::tr1::shared_ptr<const PackageIDSet> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ const std::tr1::shared_ptr<const PackageIDSet> _collect_depped_upon(
+ const std::tr1::shared_ptr<const PackageID> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
public:
Decider(const Environment * const,
const ResolverFunctions &,
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index 15049a1..16ddf81 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -49,6 +49,7 @@ namespace paludis
typedef Name<struct confirm_fn_name> confirm_fn;
typedef Name<struct find_repository_for_fn_name> find_repository_for_fn;
typedef Name<struct get_constraints_for_dependent_fn_name> get_constraints_for_dependent_fn;
+ typedef Name<struct get_constraints_for_purge_fn_name> get_constraints_for_purge_fn;
typedef Name<struct get_destination_types_for_fn_name> get_destination_types_for_fn;
typedef Name<struct get_initial_constraints_for_fn_name> get_initial_constraints_for_fn;
typedef Name<struct get_resolvents_for_fn_name> get_resolvents_for_fn;
@@ -82,6 +83,12 @@ namespace paludis
const std::tr1::shared_ptr<const PackageIDSequence> &
)> GetConstraintsForDependentFunction;
+ typedef std::tr1::function<std::tr1::shared_ptr<ConstraintSequence> (
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &
+ )> GetConstraintsForPurgeFunction;
+
typedef std::tr1::function<DestinationTypes (
const PackageDepSpec &,
const std::tr1::shared_ptr<const PackageID> &,
@@ -128,6 +135,7 @@ namespace paludis
NamedValue<n::confirm_fn, ConfirmFunction> confirm_fn;
NamedValue<n::find_repository_for_fn, FindRepositoryForFunction> find_repository_for_fn;
NamedValue<n::get_constraints_for_dependent_fn, GetConstraintsForDependentFunction> get_constraints_for_dependent_fn;
+ NamedValue<n::get_constraints_for_purge_fn, GetConstraintsForPurgeFunction> get_constraints_for_purge_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;
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index 511de35..8ad242d 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -309,6 +309,35 @@ paludis::resolver::resolver_test::get_constraints_for_dependent_fn(
return result;
}
+const std::tr1::shared_ptr<ConstraintSequence>
+paludis::resolver::resolver_test::get_constraints_for_purge_fn(
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & ids)
+{
+ const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
+
+ PartiallyMadePackageDepSpec partial_spec((PartiallyMadePackageDepSpecOptions()));
+ partial_spec.package(id->name());
+ if (id->slot_key())
+ partial_spec.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(
+ id->slot_key()->value(), false)));
+ PackageDepSpec spec(partial_spec);
+
+ const std::tr1::shared_ptr<WasUsedByReason> reason(new WasUsedByReason(ids));
+
+ result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
+ n::destination_type() = dt_install_to_slash,
+ n::nothing_is_fine_too() = true,
+ n::reason() = reason,
+ n::spec() = BlockDepSpec("!" + stringify(spec), spec, false),
+ n::untaken() = false,
+ n::use_existing() = ue_if_possible
+ ))));
+
+ return result;
+}
+
ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s, const std::string & e,
const std::string & l) :
TestCase(s),
@@ -366,8 +395,9 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
n::find_repository_for_fn() = std::tr1::bind(&find_repository_for_fn,
&env, std::tr1::placeholders::_1, std::tr1::placeholders::_2),
n::get_constraints_for_dependent_fn() = &get_constraints_for_dependent_fn,
+ n::get_constraints_for_purge_fn() = &get_constraints_for_purge_fn,
n::get_destination_types_for_fn() = &get_destination_types_for_fn,
- n::get_initial_constraints_for_fn() =
+ n::get_initial_constraints_for_fn() =
std::tr1::bind(&initial_constraints_for_fn, std::tr1::ref(initial_constraints),
std::tr1::placeholders::_1),
n::get_resolvents_for_fn() = &get_resolvents_for_fn,
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index af2ddec..8616f36 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -71,6 +71,12 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> & id,
const std::tr1::shared_ptr<const PackageIDSequence> & ids);
+ const std::tr1::shared_ptr<ConstraintSequence>
+ get_constraints_for_purge_fn(
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & ids);
+
std::tr1::shared_ptr<Resolvents> get_resolvents_for_fn(const PackageDepSpec & spec,
const std::tr1::shared_ptr<const SlotName> &,
const std::tr1::shared_ptr<const Reason> &);
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index 63257ae..b797c5c 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -690,6 +690,51 @@ namespace
join(indirect_iterator(r->begin()), indirect_iterator(r->end()), ", ", stringify_confirmation) << endl;
}
+ void display_untaken_change(
+ const ChangesToMakeDecision &)
+ {
+ cout << c::bold_green() << " Take using: " << c::normal() << "--take" << endl;
+ }
+
+ struct IsPurgeVisitor
+ {
+ bool visit(const TargetReason &) const
+ {
+ return false;
+ }
+
+ bool visit(const SetReason & r) const
+ {
+ return r.reason_for_set()->accept_returning<bool>(*this);
+ }
+
+ bool visit(const PresetReason &) const
+ {
+ return false;
+ }
+
+ bool visit(const DependencyReason &) const
+ {
+ return false;
+ }
+
+ bool visit(const DependentReason &) const
+ {
+ return false;
+ }
+
+ bool visit(const WasUsedByReason &) const
+ {
+ return true;
+ }
+ };
+
+ void display_untaken_remove(
+ const RemoveDecision &)
+ {
+ cout << c::bold_green() << " Take using: " << c::normal() << "--purge" << endl;
+ }
+
void display_one_installish(
const std::tr1::shared_ptr<Environment> & env,
const DisplayResolutionCommandLine & cmdline,
@@ -771,6 +816,8 @@ namespace
display_one_description(env, cmdline, decision.origin_id(), ! old_id);
display_choices(env, cmdline, decision.origin_id(), old_id, choices_to_explain);
display_reasons(resolution, more_annotations);
+ if (untaken)
+ display_untaken_change(decision);
if (confirmations)
display_confirmations(decision);
if (! notes.empty())
@@ -806,6 +853,8 @@ namespace
cout << endl;
display_reasons(resolution, more_annotations);
+ if (untaken)
+ display_untaken_remove(decision);
if (confirmations)
display_confirmations(decision);
if (! notes.empty())
diff --git a/src/clients/cave/cmd_resolve_cmdline.cc b/src/clients/cave/cmd_resolve_cmdline.cc
index 59053d6..0f66e48 100644
--- a/src/clients/cave/cmd_resolve_cmdline.cc
+++ b/src/clients/cave/cmd_resolve_cmdline.cc
@@ -66,10 +66,10 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
a_permit_old_version(&g_resolution_options, "permit-old-version", 'o', "Permit installs of versions matching the supplied "
"specification even if those versions are worse than the best visible version in the slot. Use '*/*' "
"to allow all worse versions to be installed."),
-// a_purge(&g_resolution_options, "purge", 'P',
-// "Purge packages matching the given specification, if they will no longer be used after "
-// "a resolution. Use '*/*' to accept all purges, but note that by doing so you are putting "
-// "a great deal of trust in package authors to get dependencies right."),
+ a_purge(&g_resolution_options, "purge", 'P',
+ "Purge packages matching the given specification, if they will no longer be used after "
+ "a resolution. Use '*/*' to accept all purges, but note that by doing so you are putting "
+ "a great deal of trust in package authors to get dependencies right."),
g_dependent_options(this, "Dependent Options", "Dependent options. A package is dependent if it "
"requires (or looks like it might require) a package which is being removed. By default, "
diff --git a/src/clients/cave/cmd_resolve_cmdline.hh b/src/clients/cave/cmd_resolve_cmdline.hh
index ef3e4a3..535ca12 100644
--- a/src/clients/cave/cmd_resolve_cmdline.hh
+++ b/src/clients/cave/cmd_resolve_cmdline.hh
@@ -46,7 +46,7 @@ namespace paludis
args::StringSetArg a_permit_uninstall;
args::StringSetArg a_permit_downgrade;
args::StringSetArg a_permit_old_version;
-// args::StringSetArg a_purge;
+ args::StringSetArg a_purge;
args::ArgsGroup g_dependent_options;
args::StringSetArg a_uninstalls_may_break;
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index 093d0c2..e3df2e7 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -1264,6 +1264,36 @@ namespace
return result;
}
+ const std::tr1::shared_ptr<ConstraintSequence> get_constraints_for_purge_fn(
+ const Environment * const env,
+ const PackageDepSpecList & list,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & ids)
+ {
+ const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
+
+ PartiallyMadePackageDepSpec partial_spec((PartiallyMadePackageDepSpecOptions()));
+ partial_spec.package(id->name());
+ if (id->slot_key())
+ partial_spec.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(
+ id->slot_key()->value(), false)));
+ PackageDepSpec spec(partial_spec);
+
+ const std::tr1::shared_ptr<WasUsedByReason> reason(new WasUsedByReason(ids));
+
+ result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
+ n::destination_type() = dt_install_to_slash,
+ n::nothing_is_fine_too() = true,
+ n::reason() = reason,
+ n::spec() = BlockDepSpec("!" + stringify(spec), spec, false),
+ n::untaken() = ! match_any(env, list, id),
+ n::use_existing() = ue_if_possible
+ ))));
+
+ return result;
+ }
+
void serialise_resolved(StringListStream & ser_stream, const Resolved & resolved)
{
Serialiser ser(ser_stream);
@@ -1545,7 +1575,7 @@ paludis::cave::resolve_common(
InitialConstraints initial_constraints;
PackageDepSpecList allowed_to_remove_specs, allowed_to_break_specs, remove_if_dependent_specs,
- less_restrictive_remove_blockers_specs, with, without,
+ less_restrictive_remove_blockers_specs, purge_specs, with, without,
permit_old_version, permit_downgrade, take, take_from, ignore, ignore_from,
favour, avoid, no_dependencies_from, no_blockers_from;
bool allowed_to_break_system(false);
@@ -1577,6 +1607,12 @@ paludis::cave::resolve_common(
less_restrictive_remove_blockers_specs.push_back(parse_user_package_dep_spec(*i, env.get(),
UserPackageDepSpecOptions() + updso_allow_wildcards));
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_purge.begin_args()),
+ i_end(resolution_options.a_purge.end_args()) ;
+ i != i_end ; ++i)
+ purge_specs.push_back(parse_user_package_dep_spec(*i, env.get(),
+ UserPackageDepSpecOptions() + updso_allow_wildcards));
+
for (args::StringSetArg::ConstIterator i(resolution_options.a_without.begin_args()),
i_end(resolution_options.a_without.end_args()) ;
i != i_end ; ++i)
@@ -1710,6 +1746,8 @@ paludis::cave::resolve_common(
env.get(), std::tr1::cref(resolution_options), _1, _2),
n::get_constraints_for_dependent_fn() = std::tr1::bind(&get_constraints_for_dependent_fn,
env.get(), std::tr1::cref(less_restrictive_remove_blockers_specs), _1, _2, _3),
+ n::get_constraints_for_purge_fn() = std::tr1::bind(&get_constraints_for_purge_fn,
+ env.get(), std::tr1::cref(purge_specs), _1, _2, _3),
n::get_destination_types_for_fn() = std::tr1::bind(&get_destination_types_for_fn,
env.get(), std::tr1::cref(resolution_options), _1, _2, _3),
n::get_initial_constraints_for_fn() = std::tr1::bind(&initial_constraints_for_fn,