aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2013-09-08 09:26:50 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2013-09-08 10:45:49 +0100
commit95e268e27709a7489c77e0c2ae89d4b85849befe (patch)
treef21d1a697c5d50c51d4c6ca47fb4a69d5120e249
parent9c877a1ab941ff8dfc42ced7fb688f00123c86e1 (diff)
downloadpaludis-95e268e27709a7489c77e0c2ae89d4b85849befe.tar.gz
paludis-95e268e27709a7489c77e0c2ae89d4b85849befe.tar.xz
Suggest uninstalls
-rw-r--r--paludis/resolver/decider.cc61
-rw-r--r--paludis/resolver/decider.hh8
-rw-r--r--paludis/resolver/resolver_TEST_blockers.cc27
3 files changed, 87 insertions, 9 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index e5cf0a1..64f9f16 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 2216a3b..388aab0 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 c93f626..d1fd8ae 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");