diff options
author | 2013-09-08 09:26:50 +0100 | |
---|---|---|
committer | 2013-09-08 10:45:49 +0100 | |
commit | 95e268e27709a7489c77e0c2ae89d4b85849befe (patch) | |
tree | f21d1a697c5d50c51d4c6ca47fb4a69d5120e249 | |
parent | 9c877a1ab941ff8dfc42ced7fb688f00123c86e1 (diff) | |
download | paludis-95e268e27709a7489c77e0c2ae89d4b85849befe.tar.gz paludis-95e268e27709a7489c77e0c2ae89d4b85849befe.tar.xz |
Suggest uninstalls
-rw-r--r-- | paludis/resolver/decider.cc | 61 | ||||
-rw-r--r-- | paludis/resolver/decider.hh | 8 | ||||
-rw-r--r-- | paludis/resolver/resolver_TEST_blockers.cc | 27 |
3 files changed, 87 insertions, 9 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc index e5cf0a13a..64f9f1651 100644 --- a/paludis/resolver/decider.cc +++ b/paludis/resolver/decider.cc @@ -1545,12 +1545,21 @@ Decider::_try_to_find_decision_for( /* we can't stick with our existing id, if there is one, and we can't * fix it by installing things. this might be an error, or we might be * able to remove things. */ - if (try_removes_if_allowed && resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolution)) + if (try_removes_if_allowed && resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolution, false)) return std::make_shared<RemoveDecision>( resolution->resolvent(), _installed_ids(resolution), ! resolution->constraints()->all_untaken() ); + else if (try_removes_if_allowed && resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolution, true)) { + auto result = std::make_shared<RemoveDecision>( + resolution->resolvent(), + _installed_ids(resolution), + ! resolution->constraints()->all_untaken() + ); + result->add_required_confirmation(std::make_shared<UninstallConfirmation>()); + return result; + } else if (also_try_option_changes && ! try_option_changes_this_time) return _try_to_find_decision_for(resolution, true, true, also_try_masked, try_masked_this_time, try_removes_if_allowed); else if (also_try_masked && ! try_masked_this_time) @@ -1642,7 +1651,8 @@ Decider::_find_existing_id_for(const std::shared_ptr<const Resolution> & resolut } bool -Decider::_installed_but_allowed_to_remove(const std::shared_ptr<const Resolution> & resolution) const +Decider::_installed_but_allowed_to_remove(const std::shared_ptr<const Resolution> & resolution, + const bool with_confirmation) const { const std::shared_ptr<const PackageIDSequence> ids(_installed_ids(resolution)); if (ids->empty()) @@ -1650,15 +1660,56 @@ Decider::_installed_but_allowed_to_remove(const std::shared_ptr<const Resolution return ids->end() == std::find_if(ids->begin(), ids->end(), std::bind(std::logical_not<bool>(), std::bind(&Decider::_allowed_to_remove, - this, resolution, std::placeholders::_1))); + this, resolution, std::placeholders::_1, with_confirmation))); } bool Decider::_allowed_to_remove( const std::shared_ptr<const Resolution> & resolution, - const std::shared_ptr<const PackageID> & id) const + const std::shared_ptr<const PackageID> & id, + const bool with_confirmation) const { - return id->supports_action(SupportsActionTest<UninstallAction>()) && _imp->fns.allowed_to_remove_fn()(resolution, id); + if (! id->supports_action(SupportsActionTest<UninstallAction>())) + return false; + + if (with_confirmation) { + bool all = true, any = false; + for (auto & c : *resolution->constraints()) { + any = true; + if (! c->reason()->make_accept_returning( + [&] (const TargetReason &) { return false; }, + [&] (const DependencyReason & r) { + auto spec = r.sanitised_dependency().spec().if_block(); + if (spec) { + auto annotations = spec->maybe_annotations(); + if (annotations) { + for (auto & a : *annotations) { + switch (a.role()) { + case dsar_blocker_uninstall_blocked_before: return true; + case dsar_blocker_uninstall_blocked_after: return true; + default: break; + } + } + } + } + return false; + }, + [&] (const DependentReason &) { return false; }, + [&] (const WasUsedByReason &) { return false; }, + [&] (const PresetReason &) { return false; }, + [&] (const SetReason &) { return false; }, + [&] (const LikeOtherDestinationTypeReason &) { return false; }, + [&] (const ViaBinaryReason &) { return false; } + )) { + all = false; + break; + } + } + + return any && all; + } + else + return _imp->fns.allowed_to_remove_fn()(resolution, id); } const std::shared_ptr<const PackageIDSequence> diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh index 2216a3b0b..388aab004 100644 --- a/paludis/resolver/decider.hh +++ b/paludis/resolver/decider.hh @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2009, 2010, 2011 Ciaran McCreesh + * Copyright (c) 2009, 2010, 2011, 2013 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 @@ -210,14 +210,16 @@ namespace paludis const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result)); bool _installed_but_allowed_to_remove( - const std::shared_ptr<const Resolution> &) const PALUDIS_ATTRIBUTE((warn_unused_result)); + const std::shared_ptr<const Resolution> &, + const bool with_confirmation) const PALUDIS_ATTRIBUTE((warn_unused_result)); const std::shared_ptr<const PackageIDSequence> _installed_ids( const std::shared_ptr<const Resolution> &) const PALUDIS_ATTRIBUTE((warn_unused_result)); bool _allowed_to_remove( const std::shared_ptr<const Resolution> &, - const std::shared_ptr<const PackageID> &) const PALUDIS_ATTRIBUTE((warn_unused_result)); + const std::shared_ptr<const PackageID> &, + const bool with_confirmation) const PALUDIS_ATTRIBUTE((warn_unused_result)); const std::pair< std::shared_ptr<const ChangeByResolventSequence>, diff --git a/paludis/resolver/resolver_TEST_blockers.cc b/paludis/resolver/resolver_TEST_blockers.cc index c93f626a5..d1fd8ae84 100644 --- a/paludis/resolver/resolver_TEST_blockers.cc +++ b/paludis/resolver/resolver_TEST_blockers.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2009, 2010, 2011 Ciaran McCreesh + * Copyright (c) 2009, 2010, 2011, 2013 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 @@ -523,6 +523,31 @@ TEST_F(ResolverBlockersTestCase, UninstallBlockedAfter) ); } +TEST_F(ResolverBlockersTestCase, UninstallBlockedAfterImplicit) +{ + data->install("uninstall-blocked-after", "dep", "1"); + + std::shared_ptr<const Resolved> resolved(data->get_resolved("uninstall-blocked-after/target")); + + this->check_resolved(resolved, + n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks() + .change(QualifiedPackageName("uninstall-blocked-after/target")) + .remove(QualifiedPackageName("uninstall-blocked-after/dep")) + .finished()), + n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks() + .finished()), + n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks() + .remove(QualifiedPackageName("uninstall-blocked-after/dep")) + .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_F(ResolverBlockersTestCase, UninstallBlockedBefore) { data->install("uninstall-blocked-before", "dep", "1"); |