aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-31 10:07:38 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-31 10:07:38 +0100
commita3c6fb2529026c256987712e5068efb617a9e44f (patch)
tree50503f46a02da8a2b3e7bdaea07297bad2f40e17
parent511a47f4b65b57ddecd69bde38751ebfb2ce3453 (diff)
downloadpaludis-a3c6fb2529026c256987712e5068efb617a9e44f.tar.gz
paludis-a3c6fb2529026c256987712e5068efb617a9e44f.tar.xz
Handle :* deps properly
Fixes: ticket:941
-rw-r--r--paludis/resolver/decider.cc66
-rw-r--r--paludis/resolver/decider.hh4
-rw-r--r--paludis/resolver/resolver_TEST_purges.cc48
3 files changed, 105 insertions, 13 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index d1db285..b6bf420 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -235,7 +235,7 @@ Decider::_resolve_dependents()
continue;
const std::shared_ptr<const ChangeByResolventSequence> dependent_upon(_dependent_upon(
- *s, changing.first, changing.second));
+ *s, changing.first, changing.second, staying));
if (dependent_upon->empty())
continue;
@@ -286,21 +286,43 @@ namespace
return i.package_id();
}
+ template <typename S_>
+ const std::shared_ptr<const PackageID> best_eventual(
+ const Environment * const env,
+ const PackageDepSpec & spec,
+ const S_ & seq)
+ {
+ std::shared_ptr<const PackageID> result;
+
+ for (auto i(seq->begin()), i_end(seq->end()) ;
+ i != i_end ; ++i)
+ {
+ if ((! result) || dependent_checker_id(*i)->version() >= result->version())
+ if (match_package(*env, spec, *dependent_checker_id(*i), { }))
+ result = dependent_checker_id(*i);
+ }
+
+ return result;
+ }
+
template <typename C_>
struct DependentChecker
{
const Environment * const env;
const std::shared_ptr<const C_> going_away;
const std::shared_ptr<const C_> newly_available;
+ const std::shared_ptr<const PackageIDSequence> not_changing_slots;
const std::shared_ptr<C_> result;
DependentChecker(
const Environment * const e,
const std::shared_ptr<const C_> & g,
- const std::shared_ptr<const C_> & n) :
+ const std::shared_ptr<const C_> & n,
+ const std::shared_ptr<const PackageIDSequence> & s) :
env(e),
going_away(g),
newly_available(n),
+ not_changing_slots(s),
result(std::make_shared<C_>())
{
}
@@ -316,14 +338,27 @@ namespace
for (typename C_::ConstIterator g(going_away->begin()), g_end(going_away->end()) ;
g != g_end ; ++g)
{
- if (! match_package(*env, *s.spec(), *dependent_checker_id(*g), { }))
+ PartiallyMadePackageDepSpec part_spec(*s.spec());
+ if (s.spec()->slot_requirement_ptr() && simple_visitor_cast<const SlotAnyUnlockedRequirement>(
+ *s.spec()->slot_requirement_ptr()))
+ {
+ auto best_eventual_id(best_eventual(env, *s.spec(), newly_available));
+ if (! best_eventual_id)
+ best_eventual_id = best_eventual(env, *s.spec(), not_changing_slots);
+ if (best_eventual_id && best_eventual_id->slot_key())
+ part_spec.slot_requirement(std::make_shared<ELikeSlotExactRequirement>(best_eventual_id->slot_key()->value(), false));
+ }
+
+ PackageDepSpec spec(part_spec);
+
+ if (! match_package(*env, spec, *dependent_checker_id(*g), { }))
continue;
bool any(false);
for (typename C_::ConstIterator n(newly_available->begin()), n_end(newly_available->end()) ;
n != n_end ; ++n)
{
- if (match_package(*env, *s.spec(), *dependent_checker_id(*n), { }))
+ if (match_package(*env, spec, *dependent_checker_id(*n), { }))
{
any = true;
break;
@@ -373,9 +408,10 @@ const std::shared_ptr<const ChangeByResolventSequence>
Decider::_dependent_upon(
const std::shared_ptr<const PackageID> & id,
const std::shared_ptr<const ChangeByResolventSequence> & going_away,
- const std::shared_ptr<const ChangeByResolventSequence> & staying) const
+ const std::shared_ptr<const ChangeByResolventSequence> & staying,
+ const std::shared_ptr<const PackageIDSequence> & not_changing_slots) const
{
- DependentChecker<ChangeByResolventSequence> c(_imp->env, going_away, staying);
+ DependentChecker<ChangeByResolventSequence> c(_imp->env, going_away, staying, not_changing_slots);
if (id->dependencies_key())
id->dependencies_key()->value()->root()->accept(c);
else
@@ -1946,7 +1982,7 @@ Decider::purge()
i_seq->push_back(*i);
for (auto u(unused->begin()), u_end(unused->end()) ;
u != u_end ; ++u)
- if ((*u)->supports_action(SupportsActionTest<UninstallAction>()) && ! _collect_depped_upon(*u, i_seq)->empty())
+ if ((*u)->supports_action(SupportsActionTest<UninstallAction>()) && ! _collect_depped_upon(*u, i_seq, have_now_seq)->empty())
used_to_use->push_back(make_named_values<ChangeByResolvent>(
n::package_id() = *u,
n::resolvent() = Resolvent(*u, dt_install_to_slash)
@@ -2169,13 +2205,16 @@ Decider::_resolve_purges()
const std::shared_ptr<PackageIDSequence> newly_unused_seq(std::make_shared<PackageIDSequence>());
std::copy(newly_unused->begin(), newly_unused->end(), newly_unused_seq->back_inserter());
+ const std::shared_ptr<PackageIDSequence> have_now_minus_going_away_seq(std::make_shared<PackageIDSequence>());
+ std::copy(have_now_minus_going_away->begin(), have_now_minus_going_away->end(), have_now_minus_going_away_seq->back_inserter());
+
const std::shared_ptr<PackageIDSet> used_by_unchanging(std::make_shared<PackageIDSet>());
for (PackageIDSet::ConstIterator u(have_now_minus_going_away->begin()), u_end(have_now_minus_going_away->end()) ;
u != u_end ; ++u)
{
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
- const std::shared_ptr<const PackageIDSet> used(_collect_depped_upon(*u, newly_unused_seq));
+ const std::shared_ptr<const PackageIDSet> used(_collect_depped_upon(*u, newly_unused_seq, have_now_minus_going_away_seq));
std::copy(used->begin(), used->end(), used_by_unchanging->inserter());
}
@@ -2206,7 +2245,8 @@ Decider::_resolve_purges()
star_i_set->push_back(*i);
for (ChangeByResolventSequence::ConstIterator g(going_away_newly_available.first->begin()), g_end(going_away_newly_available.first->end()) ;
g != g_end ; ++g)
- if (g->package_id()->supports_action(SupportsActionTest<UninstallAction>()) && ! _collect_depped_upon(g->package_id(), star_i_set)->empty())
+ if (g->package_id()->supports_action(SupportsActionTest<UninstallAction>()) &&
+ ! _collect_depped_upon(g->package_id(), star_i_set, have_now_minus_going_away_seq)->empty())
used_to_use->push_back(*g);
Resolvent resolvent(*i, dt_install_to_slash);
@@ -2261,7 +2301,8 @@ Decider::_accumulate_deps_and_provides(
done->insert(*i);
- const std::shared_ptr<const PackageIDSet> depped_upon(_collect_depped_upon(*i, will_eventually_have));
+ const std::shared_ptr<const PackageIDSet> depped_upon(_collect_depped_upon(
+ *i, will_eventually_have, std::make_shared<PackageIDSequence>()));
std::copy(depped_upon->begin(), depped_upon->end(), result->inserter());
const std::shared_ptr<const PackageIDSet> provided(_collect_provided(*i));
@@ -2278,9 +2319,10 @@ Decider::_accumulate_deps_and_provides(
const std::shared_ptr<const PackageIDSet>
Decider::_collect_depped_upon(
const std::shared_ptr<const PackageID> & id,
- const std::shared_ptr<const PackageIDSequence> & candidates) const
+ const std::shared_ptr<const PackageIDSequence> & candidates,
+ const std::shared_ptr<const PackageIDSequence> & not_changing_slots) const
{
- DependentChecker<PackageIDSequence> c(_imp->env, candidates, std::make_shared<PackageIDSequence>());
+ DependentChecker<PackageIDSequence> c(_imp->env, candidates, std::make_shared<PackageIDSequence>(), not_changing_slots);
if (id->dependencies_key())
id->dependencies_key()->value()->root()->accept(c);
else
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index 616f3ef..9031e7b 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -248,7 +248,8 @@ namespace paludis
const std::shared_ptr<const ChangeByResolventSequence> _dependent_upon(
const std::shared_ptr<const PackageID> &,
const std::shared_ptr<const ChangeByResolventSequence> &,
- const std::shared_ptr<const ChangeByResolventSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::shared_ptr<const ChangeByResolventSequence> &,
+ const std::shared_ptr<const PackageIDSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
void _confirm(const std::shared_ptr<const Resolution> & resolution);
@@ -261,6 +262,7 @@ namespace paludis
const std::shared_ptr<const PackageIDSet> _collect_depped_upon(
const std::shared_ptr<const PackageID> &,
+ const std::shared_ptr<const PackageIDSequence> &,
const std::shared_ptr<const PackageIDSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
const std::shared_ptr<const PackageIDSet> _collect_provided(
diff --git a/paludis/resolver/resolver_TEST_purges.cc b/paludis/resolver/resolver_TEST_purges.cc
index 82aa074..7cb87cc 100644
--- a/paludis/resolver/resolver_TEST_purges.cc
+++ b/paludis/resolver/resolver_TEST_purges.cc
@@ -33,6 +33,7 @@
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
#include <paludis/util/make_shared_copy.hh>
+#include <paludis/util/return_literal_function.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -122,5 +123,52 @@ namespace test_cases
);
}
} test_purges;
+
+ struct TestStarSlotPurges : ResolverPurgesTestCase
+ {
+ TestStarSlotPurges() :
+ ResolverPurgesTestCase("star slot purges")
+ {
+ install("star-slot-purges", "target", "1")->set_slot(SlotName("1"));
+ install("star-slot-purges", "target", "2")->set_slot(SlotName("2"));
+
+ install("star-slot-purges", "uses", "1")->build_dependencies_key()->set_from_string("star-slot-purges/target:*");
+
+ allowed_to_remove_names->insert(QualifiedPackageName("star-slot-purges/target"));
+ }
+
+ virtual ResolverFunctions get_resolver_functions(InitialConstraints & initial_constraints)
+ {
+ ResolverFunctions result(ResolverPurgesTestCase::get_resolver_functions(initial_constraints));
+ result.get_use_existing_fn() = std::bind(&use_existing_if_possible_except_target, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3);
+ result.confirm_fn() = std::bind(return_literal_function(false));
+ return result;
+ }
+
+ void run()
+ {
+ std::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
+ "!star-slot-purges/target:1",
+ parse_user_package_dep_spec("star-slot-purges/target:1", &env, { }),
+ false)));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("star-slot-purges/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unorderable_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_star_slot_purges;
}