aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-19 21:05:09 +0100
committerAvatar David Leverton <levertond@googlemail.com> 2010-06-19 21:26:34 +0100
commit5efc327d2ad2c0f858936c5fd1ca183680252b83 (patch)
tree651abc5ab17bf9f06b0cb859c47545e2f260edcf
parent01a45de28ed301c2a70e333f95059284bf4bd216 (diff)
downloadpaludis-5efc327d2ad2c0f858936c5fd1ca183680252b83.tar.gz
paludis-5efc327d2ad2c0f858936c5fd1ca183680252b83.tar.xz
Better permit-uninstall magic
-rw-r--r--paludis/resolver/decider.cc15
-rw-r--r--paludis/resolver/decider.hh7
-rw-r--r--paludis/resolver/resolver_functions.hh1
-rw-r--r--paludis/resolver/resolver_test.cc3
-rw-r--r--paludis/resolver/resolver_test.hh1
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.cc3
-rw-r--r--src/clients/cave/resolve_common.cc42
7 files changed, 56 insertions, 16 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index 698c3d1..0f3c3dd 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -1409,7 +1409,7 @@ 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 (resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolution->resolvent()))
+ if (resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolution))
return make_shared_ptr(new RemoveDecision(
resolution->resolvent(),
_installed_ids(resolution->resolvent()),
@@ -1572,20 +1572,23 @@ Decider::_find_existing_id_for(const std::tr1::shared_ptr<const Resolution> & re
}
bool
-Decider::_installed_but_allowed_to_remove(const Resolvent & resolvent) const
+Decider::_installed_but_allowed_to_remove(const std::tr1::shared_ptr<const Resolution> & resolution) const
{
- const std::tr1::shared_ptr<const PackageIDSequence> ids(_installed_ids(resolvent));
+ const std::tr1::shared_ptr<const PackageIDSequence> ids(_installed_ids(resolution->resolvent()));
if (ids->empty())
return false;
return ids->end() == std::find_if(ids->begin(), ids->end(),
- std::tr1::bind(std::logical_not<bool>(), std::tr1::bind(&Decider::_allowed_to_remove, this, std::tr1::placeholders::_1)));
+ std::tr1::bind(std::logical_not<bool>(), std::tr1::bind(&Decider::_allowed_to_remove,
+ this, resolution, std::tr1::placeholders::_1)));
}
bool
-Decider::_allowed_to_remove(const std::tr1::shared_ptr<const PackageID> & id) const
+Decider::_allowed_to_remove(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const PackageID> & id) const
{
- return id->supports_action(SupportsActionTest<UninstallAction>()) && _imp->fns.allowed_to_remove_fn()(id);
+ return id->supports_action(SupportsActionTest<UninstallAction>()) && _imp->fns.allowed_to_remove_fn()(resolution, id);
}
bool
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index 5ba94a7..69ddc8d 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -190,12 +190,15 @@ namespace paludis
bool _already_met(const SanitisedDependency &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- bool _installed_but_allowed_to_remove(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool _installed_but_allowed_to_remove(
+ const std::tr1::shared_ptr<const Resolution> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
const std::tr1::shared_ptr<const PackageIDSequence> _installed_ids(
const Resolvent & resolvent) const PALUDIS_ATTRIBUTE((warn_unused_result));
- bool _allowed_to_remove(const std::tr1::shared_ptr<const PackageID> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool _allowed_to_remove(
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
bool _remove_if_dependent(const std::tr1::shared_ptr<const PackageID> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index b75b0a2..15049a1 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -62,6 +62,7 @@ namespace paludis
namespace resolver
{
typedef std::tr1::function<bool (
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &
)> AllowedToRemoveFunction;
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index f9240d8..511de35 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -242,6 +242,7 @@ paludis::resolver::resolver_test::find_repository_for_fn(
bool
paludis::resolver::resolver_test::allowed_to_remove_fn(
const std::tr1::shared_ptr<const QualifiedPackageNameSet> & s,
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> & i)
{
return s->end() != s->find(i->name());
@@ -360,7 +361,7 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
{
return make_named_values<ResolverFunctions>(
n::allowed_to_remove_fn() = std::tr1::bind(&allowed_to_remove_fn,
- allowed_to_remove_names, std::tr1::placeholders::_1),
+ allowed_to_remove_names, std::tr1::placeholders::_1, std::tr1::placeholders::_2),
n::confirm_fn() = &confirm_fn,
n::find_repository_for_fn() = std::tr1::bind(&find_repository_for_fn,
&env, std::tr1::placeholders::_1, std::tr1::placeholders::_2),
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index 2fc41bc..af2ddec 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -95,6 +95,7 @@ namespace paludis
bool allowed_to_remove_fn(
const std::tr1::shared_ptr<const QualifiedPackageNameSet> &,
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &);
bool remove_if_dependent_fn(
diff --git a/src/clients/cave/cmd_resolve_cmdline.cc b/src/clients/cave/cmd_resolve_cmdline.cc
index a942c05..91958f6 100644
--- a/src/clients/cave/cmd_resolve_cmdline.cc
+++ b/src/clients/cave/cmd_resolve_cmdline.cc
@@ -81,8 +81,7 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
a_remove_if_dependent(&g_dependent_options, "remove-if-dependent", 'r',
"Remove dependent packages that might be broken by other changes if those packages match "
"the specified specification. May be specified multiple times. Use '*/*' to remove all "
- "dependent packages that might be broken, recursively. Does not imply --permit-uninstall, "
- "which must also be specified."),
+ "dependent packages that might be broken, recursively."),
a_less_restrictive_remove_blockers(&g_dependent_options, "less-restrictive-remove-blockers", 'l',
"Use less restrictive blockers for packages matching the supplied specification if that "
"package is to be removed by --remove-if-dependent. May be specified multiple times. "
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index ca4d3b9..166f3a2 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -347,7 +347,6 @@ namespace
const std::tr1::shared_ptr<Resolver> & resolver,
const ResolveCommandLineResolutionOptions &,
const std::tr1::shared_ptr<const Sequence<std::string> > & targets,
- PackageDepSpecList & allowed_to_remove_specs,
bool & is_set)
{
Context context("When adding targets from commandline:");
@@ -369,7 +368,6 @@ namespace
seen_packages = true;
PackageDepSpec s(parse_user_package_dep_spec(p->substr(1), env.get(), UserPackageDepSpecOptions()));
resolver->add_target(BlockDepSpec(*p, s, false));
- allowed_to_remove_specs.push_back(s);
}
else
{
@@ -995,11 +993,46 @@ namespace
return false;
}
+ struct AllowedToRemoveVisitor
+ {
+ bool visit(const DependentReason &) const
+ {
+ return true;
+ }
+
+ bool visit(const TargetReason &) const
+ {
+ return true;
+ }
+
+ bool visit(const DependencyReason &) 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 allowed_to_remove_fn(
const Environment * const env,
const PackageDepSpecList & list,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> & i)
{
+ for (Constraints::ConstIterator c(resolution->constraints()->begin()),
+ c_end(resolution->constraints()->end()) ;
+ c != c_end ; ++c)
+ if ((*c)->reason()->accept_returning<bool>(AllowedToRemoveVisitor()))
+ return true;
+
return match_any(env, list, i);
}
@@ -1642,7 +1675,7 @@ paludis::cave::resolve_common(
ResolverFunctions resolver_functions(make_named_values<ResolverFunctions>(
n::allowed_to_remove_fn() = std::tr1::bind(&allowed_to_remove_fn,
- env.get(), std::tr1::cref(allowed_to_remove_specs), _1),
+ env.get(), std::tr1::cref(allowed_to_remove_specs), _1, _2),
n::confirm_fn() = std::tr1::bind(&confirm_fn,
env.get(), std::tr1::cref(resolution_options), std::tr1::cref(permit_downgrade),
std::tr1::cref(permit_old_version), std::tr1::cref(allowed_to_break_specs),
@@ -1688,8 +1721,7 @@ paludis::cave::resolve_common(
{
try
{
- add_resolver_targets(env, resolver, resolution_options, targets,
- allowed_to_remove_specs, is_set);
+ add_resolver_targets(env, resolver, resolution_options, targets, is_set);
resolver->resolve();
break;
}