aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-17 22:14:46 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-17 22:14:46 +0100
commit6643fc956c40883558ed4f83de8417dadbe24d1d (patch)
treed093c2d44ba62652e33b97c7df930ec8d109a59f
parent0ff303c60e44d2c46d9435443eac08e24a984821 (diff)
downloadpaludis-6643fc956c40883558ed4f83de8417dadbe24d1d.tar.gz
paludis-6643fc956c40883558ed4f83de8417dadbe24d1d.tar.xz
UI for unsafe uninstalls
Fixes: ticket:850
-rw-r--r--.gitignore1
-rw-r--r--paludis/resolver/Makefile.am20
-rw-r--r--paludis/resolver/decider.cc145
-rw-r--r--paludis/resolver/decider.hh6
-rw-r--r--paludis/resolver/decision-fwd.hh2
-rw-r--r--paludis/resolver/decision.cc124
-rw-r--r--paludis/resolver/decision.hh53
-rw-r--r--paludis/resolver/decisions.cc3
-rw-r--r--paludis/resolver/decisions.hh3
-rw-r--r--paludis/resolver/orderer.cc9
-rw-r--r--paludis/resolver/required_confirmations-fwd.hh1
-rw-r--r--paludis/resolver/required_confirmations.cc16
-rw-r--r--paludis/resolver/required_confirmations.hh13
-rw-r--r--paludis/resolver/resolved.cc6
-rw-r--r--paludis/resolver/resolved.hh4
-rw-r--r--paludis/resolver/resolver.cc2
-rw-r--r--paludis/resolver/resolver_TEST_any.cc8
-rw-r--r--paludis/resolver/resolver_TEST_blockers.cc12
-rw-r--r--paludis/resolver/resolver_TEST_continue_on_failure.cc2
-rw-r--r--paludis/resolver/resolver_TEST_cycles.cc8
-rw-r--r--paludis/resolver/resolver_TEST_errors.cc2
-rw-r--r--paludis/resolver/resolver_TEST_serialisation.cc2
-rw-r--r--paludis/resolver/resolver_TEST_simple.cc8
-rw-r--r--paludis/resolver/resolver_TEST_suggestions.cc6
-rw-r--r--paludis/resolver/resolver_TEST_uninstalls.cc156
-rwxr-xr-xpaludis/resolver/resolver_TEST_uninstalls_cleanup.sh9
-rwxr-xr-xpaludis/resolver/resolver_TEST_uninstalls_setup.sh18
-rw-r--r--paludis/resolver/resolver_TEST_virtuals.cc4
-rw-r--r--paludis/resolver/resolver_functions.hh6
-rw-r--r--paludis/resolver/resolver_test.cc47
-rw-r--r--paludis/resolver/resolver_test.hh10
-rw-r--r--paludis/resolver/sanitised_dependencies.cc15
-rw-r--r--src/clients/cave/cmd_display_resolution.cc64
-rw-r--r--src/clients/cave/cmd_resolve_dump.cc5
-rw-r--r--src/clients/cave/resolve_common.cc48
35 files changed, 694 insertions, 144 deletions
diff --git a/.gitignore b/.gitignore
index db321be..c3e0076 100644
--- a/.gitignore
+++ b/.gitignore
@@ -332,6 +332,7 @@ paludis-*.*.*.tar.bz2
/paludis/resolver/resolver_TEST_serialisation
/paludis/resolver/resolver_TEST_simple
/paludis/resolver/resolver_TEST_suggestions
+/paludis/resolver/resolver_TEST_uninstalls
/paludis/resolver/resolver_TEST_virtuals
/paludis/selection_TEST
/paludis/set_file_TEST
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index 7ef1706..660c5aa 100644
--- a/paludis/resolver/Makefile.am
+++ b/paludis/resolver/Makefile.am
@@ -108,11 +108,12 @@ TESTS = \
resolver_TEST_any \
resolver_TEST_errors \
resolver_TEST_continue_on_failure \
+ resolver_TEST_uninstalls \
$(virtuals_tests)
endif
-
check_PROGRAMS = $(TESTS)
+
check_SCRIPTS = \
resolver_TEST_blockers_setup.sh resolver_TEST_blockers_cleanup.sh \
resolver_TEST_cycles_setup.sh resolver_TEST_cycles_cleanup.sh \
@@ -122,7 +123,9 @@ check_SCRIPTS = \
resolver_TEST_virtuals_setup.sh resolver_TEST_virtuals_cleanup.sh \
resolver_TEST_any_setup.sh resolver_TEST_any_cleanup.sh \
resolver_TEST_errors_setup.sh resolver_TEST_errors_cleanup.sh \
- resolver_TEST_continue_on_failure_setup.sh resolver_TEST_continue_on_failure_cleanup.sh
+ resolver_TEST_continue_on_failure_setup.sh resolver_TEST_continue_on_failure_cleanup.sh \
+ resolver_TEST_uninstalls_setup.sh resolver_TEST_uninstalls_cleanup.sh
+
check_LIBRARIES = libpaludisresolvertest.a
libpaludisresolvertest_a_SOURCES = \
@@ -246,6 +249,19 @@ resolver_TEST_continue_on_failure_LDADD = \
resolver_TEST_continue_on_failure_CXXFLAGS = $(AM_CXXFLAGS) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+resolver_TEST_uninstalls_SOURCES = resolver_TEST_uninstalls.cc
+
+resolver_TEST_uninstalls_LDADD = \
+ libpaludisresolvertest.a \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ $(top_builddir)/paludis/libpaludis_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/libpaludisutil_@PALUDIS_PC_SLOT@.la \
+ libpaludisresolver.a \
+ $(DYNAMIC_LD_LIBS)
+
+resolver_TEST_uninstalls_CXXFLAGS = $(AM_CXXFLAGS) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+
use_existing-se.hh : use_existing.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/use_existing.se > $@ ; then rm -f $@ ; exit 1 ; fi
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index 8d00177..22756ca 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -157,33 +157,32 @@ Decider::_resolve_dependents()
{
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
- if (_allowed_to_break(*s))
- continue;
-
const std::tr1::shared_ptr<const PackageIDSequence> dependent_upon(_dependent_upon(
*s, changing.first, changing.second));
if (dependent_upon->empty())
continue;
- if (_remove_if_dependent(*s))
- {
- Resolvent resolvent(*s, dt_install_to_slash);
+ Resolvent resolvent(*s, dt_install_to_slash);
+ bool remove(_remove_if_dependent(*s));
- /* we've changed things if we've not already done anything for this resolvent */
- if (_imp->resolutions_by_resolvent->end() == _imp->resolutions_by_resolvent->find(resolvent))
- changed = true;
+ /* we've changed things if we've not already done anything for this
+ * resolvent, but only if we're going to remove it rather than mark it
+ * as broken */
+ if (remove && _imp->resolutions_by_resolvent->end() == _imp->resolutions_by_resolvent->find(resolvent))
+ changed = true;
- const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
- const std::tr1::shared_ptr<const ConstraintSequence> constraints(_make_constraints_for_dependent(
- resolution, *s, dependent_upon));
- for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
- c != c_end ; ++c)
- _apply_resolution_constraint(resolution, *c);
- }
- else
- {
- throw InternalError(PALUDIS_HERE, "unsafe " + stringify(**s));
- }
+ const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
+ const std::tr1::shared_ptr<const ConstraintSequence> constraints(_make_constraints_for_dependent(
+ resolution, *s, dependent_upon));
+ for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
+ c != c_end ; ++c)
+ _apply_resolution_constraint(resolution, *c);
+
+ if ((! remove) && (! resolution->decision()))
+ resolution->decision() = make_shared_ptr(new BreakDecision(
+ resolvent,
+ *s,
+ true));
}
return changed;
@@ -327,6 +326,10 @@ namespace
void visit(const UnableToMakeDecision &)
{
}
+
+ void visit(const BreakDecision &)
+ {
+ }
};
}
@@ -418,6 +421,10 @@ namespace
{
}
+ void visit(BreakDecision &)
+ {
+ }
+
void visit(ChangesToMakeDecision & decision)
{
if (! decision.destination())
@@ -727,6 +734,11 @@ namespace
{
return constraint.nothing_is_fine_too();
}
+
+ bool visit(const BreakDecision &) const
+ {
+ return true;
+ }
};
struct CheckUseExistingVisitor
@@ -787,6 +799,11 @@ namespace
{
return true;
}
+
+ bool visit(const BreakDecision &) const
+ {
+ return true;
+ }
};
}
@@ -853,6 +870,11 @@ namespace
{
restart();
}
+
+ void visit(const BreakDecision &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "why are we trying to go from a BreakDecision to something else?");
+ }
};
}
@@ -971,6 +993,11 @@ namespace
else
return make_null_shared_ptr();
}
+
+ const std::tr1::shared_ptr<const PackageID> visit(const BreakDecision &) const
+ {
+ return make_null_shared_ptr();
+ }
};
}
@@ -1053,39 +1080,11 @@ Decider::_initial_constraints_for(const Resolvent & r) const
return _imp->fns.get_initial_constraints_for_fn()(r);
}
-namespace
-{
- struct ChosenIDVisitor
- {
- const std::tr1::shared_ptr<const PackageID> visit(const ChangesToMakeDecision & decision) const
- {
- return decision.origin_id();
- }
-
- const std::tr1::shared_ptr<const PackageID> visit(const ExistingNoChangeDecision & decision) const
- {
- return decision.existing_id();
- }
-
- const std::tr1::shared_ptr<const PackageID> visit(const NothingNoChangeDecision &) const
- {
- return make_null_shared_ptr();
- }
-
- const std::tr1::shared_ptr<const PackageID> visit(const UnableToMakeDecision &) const
- {
- return make_null_shared_ptr();
- }
-
- const std::tr1::shared_ptr<const PackageID> visit(const RemoveDecision &) const
- {
- return make_null_shared_ptr();
- }
- };
-}
-
std::pair<AnyChildScore, OperatorScore>
-Decider::find_any_score(const std::tr1::shared_ptr<const Resolution> & our_resolution, const SanitisedDependency & dep) const
+Decider::find_any_score(
+ const std::tr1::shared_ptr<const Resolution> & our_resolution,
+ const std::tr1::shared_ptr<const PackageID> & our_id,
+ const SanitisedDependency & dep) const
{
Context context("When working out whether we'd like '" + stringify(dep.spec()) + "' because of '"
+ stringify(our_resolution->resolvent()) + "':");
@@ -1188,12 +1187,8 @@ Decider::find_any_score(const std::tr1::shared_ptr<const Resolution> & our_resol
return std::make_pair(acs_wrong_options_installed, operator_bias);
}
- const std::tr1::shared_ptr<const PackageID> id(
- our_resolution->decision()->accept_returning<std::tr1::shared_ptr<const PackageID> >(ChosenIDVisitor()));
- if (! id)
- throw InternalError(PALUDIS_HERE, "resolver bug: why don't we have an id?");
-
- const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(id, our_resolution->resolvent(), dep, _already_met(dep)));
+ const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(
+ our_id, our_resolution->resolvent(), dep, _already_met(dep)));
const std::tr1::shared_ptr<const Resolvents> resolvents(_get_resolvents_for(spec, reason));
/* next: will already be installing */
@@ -1595,12 +1590,6 @@ Decider::_allowed_to_remove(const std::tr1::shared_ptr<const PackageID> & id) co
}
bool
-Decider::_allowed_to_break(const std::tr1::shared_ptr<const PackageID> & id) const
-{
- return _imp->fns.allowed_to_break_fn()(id);
-}
-
-bool
Decider::_remove_if_dependent(const std::tr1::shared_ptr<const PackageID> & id) const
{
return _imp->fns.remove_if_dependent_fn()(id);
@@ -1803,21 +1792,29 @@ Decider::_confirm(
const std::tr1::shared_ptr<const Resolution> & resolution)
{
ChangesToMakeDecision * const changes_to_make_decision(simple_visitor_cast<ChangesToMakeDecision>(*resolution->decision()));
- if (! changes_to_make_decision)
- return;
+ BreakDecision * const break_decision(simple_visitor_cast<BreakDecision>(*resolution->decision()));
- if (! changes_to_make_decision->best())
+ if (changes_to_make_decision)
{
- const std::tr1::shared_ptr<RequiredConfirmation> c(new NotBestConfirmation);
- if (! _imp->fns.confirm_fn()(resolution, c))
- changes_to_make_decision->add_required_confirmation(c);
- }
+ if (! changes_to_make_decision->best())
+ {
+ const std::tr1::shared_ptr<RequiredConfirmation> c(new NotBestConfirmation);
+ if (! _imp->fns.confirm_fn()(resolution, c))
+ changes_to_make_decision->add_required_confirmation(c);
+ }
- if (ct_downgrade == changes_to_make_decision->change_type())
+ if (ct_downgrade == changes_to_make_decision->change_type())
+ {
+ const std::tr1::shared_ptr<DowngradeConfirmation> c(new DowngradeConfirmation);
+ if (! _imp->fns.confirm_fn()(resolution, c))
+ changes_to_make_decision->add_required_confirmation(c);
+ }
+ }
+ else if (break_decision)
{
- const std::tr1::shared_ptr<DowngradeConfirmation> c(new DowngradeConfirmation);
+ const std::tr1::shared_ptr<BreakConfirmation> c(new BreakConfirmation);
if (! _imp->fns.confirm_fn()(resolution, c))
- changes_to_make_decision->add_required_confirmation(c);
+ break_decision->add_required_confirmation(c);
}
}
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index ff9d161..5ba94a7 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -197,8 +197,6 @@ namespace paludis
bool _allowed_to_remove(const std::tr1::shared_ptr<const PackageID> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- bool _allowed_to_break(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));
const std::pair<
@@ -226,7 +224,9 @@ namespace paludis
void add_target_with_reason(const PackageOrBlockDepSpec &, const std::tr1::shared_ptr<const Reason> &);
std::pair<AnyChildScore, OperatorScore> find_any_score(
- const std::tr1::shared_ptr<const Resolution> &, const SanitisedDependency &) const;
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const SanitisedDependency &) const;
const std::tr1::shared_ptr<const RewrittenSpec> rewrite_if_special(const PackageOrBlockDepSpec &,
const std::tr1::shared_ptr<const Resolvent> & maybe_from) const;
diff --git a/paludis/resolver/decision-fwd.hh b/paludis/resolver/decision-fwd.hh
index 0f4a3ae..3e1ce58 100644
--- a/paludis/resolver/decision-fwd.hh
+++ b/paludis/resolver/decision-fwd.hh
@@ -28,6 +28,7 @@ namespace paludis
namespace resolver
{
class Decision;
+ class ConfirmableDecision;
class ChangeOrRemoveDecision;
class NothingNoChangeDecision;
@@ -35,6 +36,7 @@ namespace paludis
class UnableToMakeDecision;
class ChangesToMakeDecision;
class RemoveDecision;
+ class BreakDecision;
}
}
diff --git a/paludis/resolver/decision.cc b/paludis/resolver/decision.cc
index ac3e3ba..183f06c 100644
--- a/paludis/resolver/decision.cc
+++ b/paludis/resolver/decision.cc
@@ -76,6 +76,29 @@ Decision::deserialise(Deserialisation & d)
{
return RemoveDecision::deserialise(d);
}
+ else if (d.class_name() == "BreakDecision")
+ {
+ return BreakDecision::deserialise(d);
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
+}
+
+const std::tr1::shared_ptr<ConfirmableDecision>
+ConfirmableDecision::deserialise(Deserialisation & d)
+{
+ if (d.class_name() == "ChangesToMakeDecision")
+ {
+ return ChangesToMakeDecision::deserialise(d);
+ }
+ else if (d.class_name() == "RemoveDecision")
+ {
+ return RemoveDecision::deserialise(d);
+ }
+ else if (d.class_name() == "BreakDecision")
+ {
+ return BreakDecision::deserialise(d);
+ }
else
throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
}
@@ -573,9 +596,110 @@ RemoveDecision::serialise(Serialiser & s) const
;
}
+namespace paludis
+{
+ template <>
+ struct Implementation<BreakDecision>
+ {
+ const Resolvent resolvent;
+ const std::tr1::shared_ptr<const PackageID> existing_id;
+ const bool taken;
+ std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
+
+ Implementation(const Resolvent & l,
+ const std::tr1::shared_ptr<const PackageID> & e,
+ const bool t) :
+ resolvent(l),
+ existing_id(e),
+ taken(t)
+ {
+ }
+ };
+}
+
+BreakDecision::BreakDecision(const Resolvent & l, const std::tr1::shared_ptr<const PackageID> & e, const bool t) :
+ PrivateImplementationPattern<BreakDecision>(new Implementation<BreakDecision>(
+ l, e, t))
+{
+}
+
+#ifdef PALUDIS_HAVE_DEFAULT_DELETED
+BreakDecision::~BreakDecision() = default;
+#else
+BreakDecision::~BreakDecision()
+{
+}
+#endif
+
+const std::tr1::shared_ptr<const PackageID>
+BreakDecision::existing_id() const
+{
+ return _imp->existing_id;
+}
+
+const Resolvent
+BreakDecision::resolvent() const
+{
+ return _imp->resolvent;
+}
+
+bool
+BreakDecision::taken() const
+{
+ return _imp->taken;
+}
+
+const std::tr1::shared_ptr<const RequiredConfirmations>
+BreakDecision::required_confirmations_if_any() const
+{
+ return _imp->required_confirmations;
+}
+
+void
+BreakDecision::add_required_confirmation(const std::tr1::shared_ptr<const RequiredConfirmation> & r)
+{
+ if (! _imp->required_confirmations)
+ _imp->required_confirmations.reset(new RequiredConfirmations);
+ _imp->required_confirmations->push_back(r);
+}
+
+void
+BreakDecision::serialise(Serialiser & s) const
+{
+ s.object("BreakDecision")
+ .member(SerialiserFlags<serialise::might_be_null>(), "existing_id", existing_id())
+ .member(SerialiserFlags<>(), "taken", taken())
+ .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "required_confirmations_if_any", required_confirmations_if_any())
+ ;
+}
+
+const std::tr1::shared_ptr<BreakDecision>
+BreakDecision::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "BreakDecision");
+ std::tr1::shared_ptr<BreakDecision> result(new BreakDecision(
+ v.member<Resolvent>("resolvent"),
+ v.member<std::tr1::shared_ptr<const PackageID> >("existing_id"),
+ v.member<bool>("taken")
+ ));
+
+ {
+ const std::tr1::shared_ptr<Deserialisation> dn(v.find_remove_member("required_confirmations_if_any"));
+ if (! dn->null())
+ {
+ Deserialisator vv(*dn, "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->add_required_confirmation(vv.member<std::tr1::shared_ptr<RequiredConfirmation> >(stringify(n)));
+ }
+ }
+
+ return result;
+}
+
template class PrivateImplementationPattern<NothingNoChangeDecision>;
template class PrivateImplementationPattern<ExistingNoChangeDecision>;
template class PrivateImplementationPattern<ChangesToMakeDecision>;
template class PrivateImplementationPattern<UnableToMakeDecision>;
template class PrivateImplementationPattern<RemoveDecision>;
+template class PrivateImplementationPattern<BreakDecision>;
diff --git a/paludis/resolver/decision.hh b/paludis/resolver/decision.hh
index f17d37d..e83c384 100644
--- a/paludis/resolver/decision.hh
+++ b/paludis/resolver/decision.hh
@@ -39,7 +39,7 @@ namespace paludis
class PALUDIS_VISIBLE Decision :
public virtual DeclareAbstractAcceptMethods<Decision, MakeTypeList<
NothingNoChangeDecision, ExistingNoChangeDecision, ChangesToMakeDecision,
- RemoveDecision, UnableToMakeDecision>::Type>
+ RemoveDecision, UnableToMakeDecision, BreakDecision>::Type>
{
public:
virtual ~Decision() = 0;
@@ -98,21 +98,29 @@ namespace paludis
virtual void serialise(Serialiser &) const;
};
- class PALUDIS_VISIBLE ChangeOrRemoveDecision :
+ class PALUDIS_VISIBLE ConfirmableDecision :
public Decision
{
public:
- static const std::tr1::shared_ptr<ChangeOrRemoveDecision> deserialise(
+ static const std::tr1::shared_ptr<ConfirmableDecision> deserialise(
Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations_if_any() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+ virtual const std::tr1::shared_ptr<const RequiredConfirmations>
+ required_confirmations_if_any() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+ };
+
+ class PALUDIS_VISIBLE ChangeOrRemoveDecision :
+ public ConfirmableDecision
+ {
+ public:
+ static const std::tr1::shared_ptr<ChangeOrRemoveDecision> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
class PALUDIS_VISIBLE ChangesToMakeDecision :
public ChangeOrRemoveDecision,
public ImplementAcceptMethods<Decision, ChangesToMakeDecision>,
- private PrivateImplementationPattern<ChangesToMakeDecision>,
- public std::tr1::enable_shared_from_this<ChangesToMakeDecision>
+ private PrivateImplementationPattern<ChangesToMakeDecision>
{
public:
ChangesToMakeDecision(
@@ -155,8 +163,7 @@ namespace paludis
class PALUDIS_VISIBLE RemoveDecision :
public ChangeOrRemoveDecision,
public ImplementAcceptMethods<Decision, RemoveDecision>,
- private PrivateImplementationPattern<RemoveDecision>,
- public std::tr1::enable_shared_from_this<RemoveDecision>
+ private PrivateImplementationPattern<RemoveDecision>
{
public:
RemoveDecision(
@@ -183,8 +190,7 @@ namespace paludis
class PALUDIS_VISIBLE UnableToMakeDecision :
public Decision,
public ImplementAcceptMethods<Decision, UnableToMakeDecision>,
- private PrivateImplementationPattern<UnableToMakeDecision>,
- public std::tr1::enable_shared_from_this<UnableToMakeDecision>
+ private PrivateImplementationPattern<UnableToMakeDecision>
{
public:
UnableToMakeDecision(
@@ -203,6 +209,32 @@ namespace paludis
static const std::tr1::shared_ptr<UnableToMakeDecision> deserialise(
Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
+
+ class PALUDIS_VISIBLE BreakDecision :
+ public ConfirmableDecision,
+ public ImplementAcceptMethods<Decision, BreakDecision>,
+ private PrivateImplementationPattern<BreakDecision>
+ {
+ public:
+ BreakDecision(
+ const Resolvent &,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const bool taken);
+ ~BreakDecision();
+
+ const std::tr1::shared_ptr<const PackageID> existing_id() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual const Resolvent resolvent() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual bool taken() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations_if_any() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void add_required_confirmation(const std::tr1::shared_ptr<const RequiredConfirmation> &);
+
+ virtual void serialise(Serialiser &) const;
+
+ static const std::tr1::shared_ptr<BreakDecision> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
}
#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
@@ -211,6 +243,7 @@ namespace paludis
extern template class PrivateImplementationPattern<resolver::ChangesToMakeDecision>;
extern template class PrivateImplementationPattern<resolver::UnableToMakeDecision>;
extern template class PrivateImplementationPattern<resolver::RemoveDecision>;
+ extern template class PrivateImplementationPattern<resolver::BreakDecision>;
#endif
}
diff --git a/paludis/resolver/decisions.cc b/paludis/resolver/decisions.cc
index c247ce9..5942b86 100644
--- a/paludis/resolver/decisions.cc
+++ b/paludis/resolver/decisions.cc
@@ -196,6 +196,7 @@ Decisions<Decision_, Notes_>::deserialise(Deserialisation & d)
template class Decisions<UnableToMakeDecision>;
template class Decisions<ChangesToMakeDecision>;
template class Decisions<ChangeOrRemoveDecision>;
+template class Decisions<ConfirmableDecision>;
template class Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> >;
template class WrappedForwardIterator<Decisions<UnableToMakeDecision>::ConstIteratorTag,
@@ -204,6 +205,8 @@ template class WrappedForwardIterator<Decisions<ChangesToMakeDecision>::ConstIte
const std::tr1::shared_ptr<const ChangesToMakeDecision> >;
template class WrappedForwardIterator<Decisions<ChangeOrRemoveDecision>::ConstIteratorTag,
const std::tr1::shared_ptr<const ChangeOrRemoveDecision> >;
+template class WrappedForwardIterator<Decisions<ConfirmableDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const ConfirmableDecision> >;
template class WrappedForwardIterator<Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> >::ConstIteratorTag,
const std::pair<
std::tr1::shared_ptr<const ChangeOrRemoveDecision>,
diff --git a/paludis/resolver/decisions.hh b/paludis/resolver/decisions.hh
index 432bcbe..65139b5 100644
--- a/paludis/resolver/decisions.hh
+++ b/paludis/resolver/decisions.hh
@@ -82,6 +82,7 @@ namespace paludis
extern template class Decisions<UnableToMakeDecision>;
extern template class Decisions<ChangesToMakeDecision>;
extern template class Decisions<ChangeOrRemoveDecision>;
+ extern template class Decisions<ConfirmableDecision>;
extern template class Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> >;
#endif
}
@@ -93,6 +94,8 @@ namespace paludis
const std::tr1::shared_ptr<const resolver::ChangesToMakeDecision> >;
extern template class WrappedForwardIterator<resolver::Decisions<resolver::ChangeOrRemoveDecision>::ConstIteratorTag,
const std::tr1::shared_ptr<const resolver::ChangeOrRemoveDecision> >;
+ extern template class WrappedForwardIterator<resolver::Decisions<resolver::ConfirmableDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const resolver::ConfirmableDecision> >;
extern template class WrappedForwardIterator<resolver::Decisions<resolver::ChangeOrRemoveDecision,
std::tr1::shared_ptr<const resolver::OrdererNotes> >::ConstIteratorTag,
const std::pair<
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index a74c96b..cd6cbc4 100644
--- a/paludis/resolver/orderer.cc
+++ b/paludis/resolver/orderer.cc
@@ -162,6 +162,13 @@ namespace
else
throw InternalError(PALUDIS_HERE, "untaken RemoveDecision");
}
+
+ bool visit(const BreakDecision & d)
+ {
+ if (d.required_confirmations_if_any())
+ resolved->taken_unconfirmed_decisions()->cast_push_back(decision);
+ return false;
+ }
};
struct LabelsClassifier
@@ -551,7 +558,7 @@ Orderer::_schedule(
{
_imp->resolved->taken_change_or_remove_decisions()->push_back(d, n);
if (d->required_confirmations_if_any())
- _imp->resolved->taken_unconfirmed_change_or_remove_decisions()->push_back(d);
+ _imp->resolved->taken_unconfirmed_decisions()->push_back(d);
const ChangesToMakeDecision * const changes_to_make_decision(simple_visitor_cast<const ChangesToMakeDecision>(*d));
const RemoveDecision * const remove_decision(simple_visitor_cast<const RemoveDecision>(*d));
diff --git a/paludis/resolver/required_confirmations-fwd.hh b/paludis/resolver/required_confirmations-fwd.hh
index 2f8aabb..94c5d14 100644
--- a/paludis/resolver/required_confirmations-fwd.hh
+++ b/paludis/resolver/required_confirmations-fwd.hh
@@ -30,6 +30,7 @@ namespace paludis
struct RequiredConfirmation;
struct DowngradeConfirmation;
struct NotBestConfirmation;
+ struct BreakConfirmation;
typedef Sequence<std::tr1::shared_ptr<const RequiredConfirmation> > RequiredConfirmations;
}
diff --git a/paludis/resolver/required_confirmations.cc b/paludis/resolver/required_confirmations.cc
index ac0ad4a..1b2bbef 100644
--- a/paludis/resolver/required_confirmations.cc
+++ b/paludis/resolver/required_confirmations.cc
@@ -34,6 +34,8 @@ RequiredConfirmation::deserialise(Deserialisation & d)
return DowngradeConfirmation::deserialise(d);
else if (d.class_name() == "NotBestConfirmation")
return NotBestConfirmation::deserialise(d);
+ else if (d.class_name() == "BreakConfirmation")
+ return BreakConfirmation::deserialise(d);
else
throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
@@ -68,6 +70,20 @@ NotBestConfirmation::serialise(Serialiser & s) const
;
}
+const std::tr1::shared_ptr<BreakConfirmation>
+BreakConfirmation::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "BreakConfirmation");
+ return make_shared_ptr(new BreakConfirmation);
+}
+
+void
+BreakConfirmation::serialise(Serialiser & s) const
+{
+ s.object("BreakConfirmation")
+ ;
+}
+
template class Sequence<std::tr1::shared_ptr<const RequiredConfirmation> >;
template class WrappedForwardIterator<RequiredConfirmations::ConstIteratorTag, const std::tr1::shared_ptr<const RequiredConfirmation> >;
diff --git a/paludis/resolver/required_confirmations.hh b/paludis/resolver/required_confirmations.hh
index 7e8c517..0c508f3 100644
--- a/paludis/resolver/required_confirmations.hh
+++ b/paludis/resolver/required_confirmations.hh
@@ -32,7 +32,7 @@ namespace paludis
{
class PALUDIS_VISIBLE RequiredConfirmation :
public virtual DeclareAbstractAcceptMethods<RequiredConfirmation, MakeTypeList<
- DowngradeConfirmation, NotBestConfirmation>::Type>
+ DowngradeConfirmation, NotBestConfirmation, BreakConfirmation>::Type>
{
public:
virtual void serialise(Serialiser &) const = 0;
@@ -62,6 +62,17 @@ namespace paludis
virtual void serialise(Serialiser &) const;
};
+
+ class PALUDIS_VISIBLE BreakConfirmation :
+ public RequiredConfirmation,
+ public ImplementAcceptMethods<RequiredConfirmation, BreakConfirmation>
+ {
+ public:
+ static const std::tr1::shared_ptr<BreakConfirmation> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual void serialise(Serialiser &) const;
+ };
}
}
diff --git a/paludis/resolver/resolved.cc b/paludis/resolver/resolved.cc
index 61c28bf..f443668 100644
--- a/paludis/resolver/resolved.cc
+++ b/paludis/resolver/resolved.cc
@@ -38,7 +38,7 @@ Resolved::serialise(Serialiser & s) const
.member(SerialiserFlags<serialise::might_be_null>(), "resolutions_by_resolvent", resolutions_by_resolvent())
.member(SerialiserFlags<serialise::might_be_null>(), "taken_change_or_remove_decisions", taken_change_or_remove_decisions())
.member(SerialiserFlags<serialise::might_be_null>(), "taken_unable_to_make_decisions", taken_unable_to_make_decisions())
- .member(SerialiserFlags<serialise::might_be_null>(), "taken_unconfirmed_change_or_remove_decisions", taken_unconfirmed_change_or_remove_decisions())
+ .member(SerialiserFlags<serialise::might_be_null>(), "taken_unconfirmed_decisions", taken_unconfirmed_decisions())
.member(SerialiserFlags<serialise::might_be_null>(), "untaken_change_or_remove_decisions", untaken_change_or_remove_decisions())
.member(SerialiserFlags<serialise::might_be_null>(), "untaken_unable_to_make_decisions", untaken_unable_to_make_decisions())
;
@@ -60,8 +60,8 @@ Resolved::deserialise(Deserialisation & d)
v.member<std::tr1::shared_ptr<OrderedChangeOrRemoveDecisions> >("taken_change_or_remove_decisions"),
n::taken_unable_to_make_decisions() =
v.member<std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > >("taken_unable_to_make_decisions"),
- n::taken_unconfirmed_change_or_remove_decisions() =
- v.member<std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > >("taken_unconfirmed_change_or_remove_decisions"),
+ n::taken_unconfirmed_decisions() =
+ v.member<std::tr1::shared_ptr<Decisions<ConfirmableDecision> > >("taken_unconfirmed_decisions"),
n::untaken_change_or_remove_decisions() =
v.member<std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > >("untaken_change_or_remove_decisions"),
n::untaken_unable_to_make_decisions() =
diff --git a/paludis/resolver/resolved.hh b/paludis/resolver/resolved.hh
index 3f99214..191de6a 100644
--- a/paludis/resolver/resolved.hh
+++ b/paludis/resolver/resolved.hh
@@ -39,7 +39,7 @@ namespace paludis
typedef Name<struct resolutions_by_resolvent_name> resolutions_by_resolvent;
typedef Name<struct taken_change_or_remove_decisions_name> taken_change_or_remove_decisions;
typedef Name<struct taken_unable_to_make_decisions_name> taken_unable_to_make_decisions;
- typedef Name<struct taken_unconfirmed_change_or_remove_decisions_name> taken_unconfirmed_change_or_remove_decisions;
+ typedef Name<struct taken_unconfirmed_decisions_name> taken_unconfirmed_decisions;
typedef Name<struct untaken_change_or_remove_decisions_name> untaken_change_or_remove_decisions;
typedef Name<struct untaken_unable_to_make_decisions_name> untaken_unable_to_make_decisions;
}
@@ -53,7 +53,7 @@ namespace paludis
NamedValue<n::resolutions_by_resolvent, std::tr1::shared_ptr<ResolutionsByResolvent> > resolutions_by_resolvent;
NamedValue<n::taken_change_or_remove_decisions, std::tr1::shared_ptr<OrderedChangeOrRemoveDecisions> > taken_change_or_remove_decisions;
NamedValue<n::taken_unable_to_make_decisions, std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > > taken_unable_to_make_decisions;
- NamedValue<n::taken_unconfirmed_change_or_remove_decisions, std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > > taken_unconfirmed_change_or_remove_decisions;
+ NamedValue<n::taken_unconfirmed_decisions, std::tr1::shared_ptr<Decisions<ConfirmableDecision> > > taken_unconfirmed_decisions;
NamedValue<n::untaken_change_or_remove_decisions, std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > > untaken_change_or_remove_decisions;
NamedValue<n::untaken_unable_to_make_decisions, std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > > untaken_unable_to_make_decisions;
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index ccc0d3d..bf785bd 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -72,7 +72,7 @@ namespace paludis
n::resolutions_by_resolvent() = make_shared_ptr(new ResolutionsByResolvent),
n::taken_change_or_remove_decisions() = make_shared_ptr(new OrderedChangeOrRemoveDecisions),
n::taken_unable_to_make_decisions() = make_shared_ptr(new Decisions<UnableToMakeDecision>),
- n::taken_unconfirmed_change_or_remove_decisions() = make_shared_ptr(new Decisions<ChangeOrRemoveDecision>),
+ n::taken_unconfirmed_decisions() = make_shared_ptr(new Decisions<ConfirmableDecision>),
n::untaken_change_or_remove_decisions() = make_shared_ptr(new Decisions<ChangeOrRemoveDecision>),
n::untaken_unable_to_make_decisions() = make_shared_ptr(new Decisions<UnableToMakeDecision>)
))),
diff --git a/paludis/resolver/resolver_TEST_any.cc b/paludis/resolver/resolver_TEST_any.cc
index fa37066..25730f7 100644
--- a/paludis/resolver/resolver_TEST_any.cc
+++ b/paludis/resolver/resolver_TEST_any.cc
@@ -81,6 +81,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -108,6 +110,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -134,6 +138,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -196,6 +202,8 @@ namespace test_cases
n::taken_change_or_remove_decisions() = checks,
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_blockers.cc b/paludis/resolver/resolver_TEST_blockers.cc
index 3ea617f..ef9b3b5 100644
--- a/paludis/resolver/resolver_TEST_blockers.cc
+++ b/paludis/resolver/resolver_TEST_blockers.cc
@@ -88,6 +88,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -117,6 +119,8 @@ namespace test_cases
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.unable(QualifiedPackageName("unfixable/a-pkg"))
.finished()),
+ n::taken_unconfirmed_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()
@@ -147,6 +151,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -183,6 +189,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -221,6 +229,8 @@ namespace test_cases
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.unable(QualifiedPackageName("blocked-and-dep/both"))
.finished()),
+ n::taken_unconfirmed_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()
@@ -251,6 +261,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_continue_on_failure.cc b/paludis/resolver/resolver_TEST_continue_on_failure.cc
index 597d693..e301b0c 100644
--- a/paludis/resolver/resolver_TEST_continue_on_failure.cc
+++ b/paludis/resolver/resolver_TEST_continue_on_failure.cc
@@ -127,6 +127,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_cycles.cc b/paludis/resolver/resolver_TEST_cycles.cc
index 1597be5..b1db400 100644
--- a/paludis/resolver/resolver_TEST_cycles.cc
+++ b/paludis/resolver/resolver_TEST_cycles.cc
@@ -101,6 +101,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -128,6 +130,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -153,6 +157,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -223,6 +229,8 @@ namespace test_cases
n::taken_change_or_remove_decisions() = checks,
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_errors.cc b/paludis/resolver/resolver_TEST_errors.cc
index 7c0ce0b..c7eee35 100644
--- a/paludis/resolver/resolver_TEST_errors.cc
+++ b/paludis/resolver/resolver_TEST_errors.cc
@@ -81,6 +81,8 @@ namespace test_cases
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.unable(QualifiedPackageName("unable-to-decide-then-more/pkg-a"))
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_serialisation.cc b/paludis/resolver/resolver_TEST_serialisation.cc
index 2b0c7e8..9637e2b 100644
--- a/paludis/resolver/resolver_TEST_serialisation.cc
+++ b/paludis/resolver/resolver_TEST_serialisation.cc
@@ -94,6 +94,8 @@ namespace test_cases
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.unable(QualifiedPackageName("serialisation/error"))
.finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
.change(QualifiedPackageName("serialisation/suggestion"))
.finished()),
diff --git a/paludis/resolver/resolver_TEST_simple.cc b/paludis/resolver/resolver_TEST_simple.cc
index b96865d..6361465 100644
--- a/paludis/resolver/resolver_TEST_simple.cc
+++ b/paludis/resolver/resolver_TEST_simple.cc
@@ -78,6 +78,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -103,6 +105,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -128,6 +132,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -153,6 +159,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_suggestions.cc b/paludis/resolver/resolver_TEST_suggestions.cc
index 1fa93ee..e20eb00 100644
--- a/paludis/resolver/resolver_TEST_suggestions.cc
+++ b/paludis/resolver/resolver_TEST_suggestions.cc
@@ -79,6 +79,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
.change(QualifiedPackageName("suggestion/dep"))
.finished()),
@@ -102,6 +104,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -127,6 +131,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_TEST_uninstalls.cc b/paludis/resolver/resolver_TEST_uninstalls.cc
new file mode 100644
index 0000000..c5b7dfd
--- /dev/null
+++ b/paludis/resolver/resolver_TEST_uninstalls.cc
@@ -0,0 +1,156 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/resolver/resolver.hh>
+#include <paludis/resolver/resolver_functions.hh>
+#include <paludis/resolver/resolution.hh>
+#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/constraint.hh>
+#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/suggest_restart.hh>
+#include <paludis/resolver/required_confirmations.hh>
+#include <paludis/environments/test/test_environment.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/return_literal_function.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/repository_factory.hh>
+#include <paludis/package_database.hh>
+
+#include <paludis/resolver/resolver_test.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+
+#include <list>
+#include <tr1/functional>
+#include <algorithm>
+#include <map>
+
+using namespace paludis;
+using namespace paludis::resolver;
+using namespace paludis::resolver::resolver_test;
+using namespace test;
+
+namespace
+{
+ struct ResolverUninstallsTestCase : ResolverTestCase
+ {
+ ResolverUninstallsTestCase(const std::string & s) :
+ ResolverTestCase("uninstalls", s, "exheres-0", "exheres")
+ {
+ }
+ };
+}
+
+namespace test_cases
+{
+ struct TestUninstallBreaking : ResolverUninstallsTestCase
+ {
+ const bool allowed_to_remove;
+ const bool confirm;
+
+ TestUninstallBreaking(const bool ar, const bool c) :
+ ResolverUninstallsTestCase("uninstall breaking " + stringify(ar) + " " + stringify(c)),
+ allowed_to_remove(ar),
+ confirm(c)
+ {
+ install("breaking", "dep", "1")->run_dependencies_key()->set_from_string("breaking/target");
+ install("breaking", "target", "1");
+
+ allowed_to_remove_names->insert(QualifiedPackageName("breaking/target"));
+ if (allowed_to_remove)
+ {
+ remove_if_dependent_names->insert(QualifiedPackageName("breaking/dep"));
+ allowed_to_remove_names->insert(QualifiedPackageName("breaking/dep"));
+ }
+ }
+
+ virtual ResolverFunctions get_resolver_functions(InitialConstraints & initial_constraints)
+ {
+ ResolverFunctions result(ResolverUninstallsTestCase::get_resolver_functions(initial_constraints));
+ result.confirm_fn() = std::tr1::bind(return_literal_function(confirm));
+ return result;
+ }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
+ "!breaking/target",
+ parse_user_package_dep_spec("breaking/target", &env, UserPackageDepSpecOptions()),
+ false)));
+
+ if (allowed_to_remove)
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("breaking/dep"))
+ .remove(QualifiedPackageName("breaking/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_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())
+ );
+ else if (confirm)
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("breaking/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_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())
+ );
+ else
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("breaking/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .breaking(QualifiedPackageName("breaking/dep"))
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_uninstall_breaking_f_f(false, false),
+ test_uninstall_breaking_f_t(false, true),
+ test_uninstall_breaking_t_f(true, false),
+ test_uninstall_breaking_t_t(true, true);
+}
+
diff --git a/paludis/resolver/resolver_TEST_uninstalls_cleanup.sh b/paludis/resolver/resolver_TEST_uninstalls_cleanup.sh
new file mode 100755
index 0000000..672d41c
--- /dev/null
+++ b/paludis/resolver/resolver_TEST_uninstalls_cleanup.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d resolver_TEST_uninstalls_dir ] ; then
+ rm -fr resolver_TEST_uninstalls_dir
+else
+ true
+fi
+
diff --git a/paludis/resolver/resolver_TEST_uninstalls_setup.sh b/paludis/resolver/resolver_TEST_uninstalls_setup.sh
new file mode 100755
index 0000000..151bc6f
--- /dev/null
+++ b/paludis/resolver/resolver_TEST_uninstalls_setup.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir resolver_TEST_uninstalls_dir || exit 1
+cd resolver_TEST_uninstalls_dir || exit 1
+
+mkdir -p build
+mkdir -p distdir
+mkdir -p installed
+
+mkdir -p repo/{profiles/profile,metadata}
+
+cd repo
+echo "repo" > profiles/repo_name
+: > metadata/categories.conf
+
+cd ..
+
diff --git a/paludis/resolver/resolver_TEST_virtuals.cc b/paludis/resolver/resolver_TEST_virtuals.cc
index dfb20cb..abb90de 100644
--- a/paludis/resolver/resolver_TEST_virtuals.cc
+++ b/paludis/resolver/resolver_TEST_virtuals.cc
@@ -80,6 +80,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
@@ -102,6 +104,8 @@ namespace test_cases
.finished()),
n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
.finished()),
+ n::taken_unconfirmed_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()
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index 8ccc281..b75b0a2 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -45,7 +45,6 @@ namespace paludis
{
namespace n
{
- typedef Name<struct allowed_to_break_fn_name> allowed_to_break_fn;
typedef Name<struct allowed_to_remove_fn_name> allowed_to_remove_fn;
typedef Name<struct confirm_fn_name> confirm_fn;
typedef Name<struct find_repository_for_fn_name> find_repository_for_fn;
@@ -64,10 +63,6 @@ namespace paludis
{
typedef std::tr1::function<bool (
const std::tr1::shared_ptr<const PackageID> &
- )> AllowedToBreakFunction;
-
- typedef std::tr1::function<bool (
- const std::tr1::shared_ptr<const PackageID> &
)> AllowedToRemoveFunction;
typedef std::tr1::function<bool (
@@ -128,7 +123,6 @@ namespace paludis
struct ResolverFunctions
{
- NamedValue<n::allowed_to_break_fn, AllowedToBreakFunction> allowed_to_break_fn;
NamedValue<n::allowed_to_remove_fn, AllowedToRemoveFunction> allowed_to_remove_fn;
NamedValue<n::confirm_fn, ConfirmFunction> confirm_fn;
NamedValue<n::find_repository_for_fn, FindRepositoryForFunction> find_repository_for_fn;
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index 456a1f7..3b89000 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -240,14 +240,6 @@ paludis::resolver::resolver_test::find_repository_for_fn(
}
bool
-paludis::resolver::resolver_test::allowed_to_break_fn(
- const std::tr1::shared_ptr<const QualifiedPackageNameSet> & s,
- const std::tr1::shared_ptr<const PackageID> & i)
-{
- return s->end() != s->find(i->name());
-}
-
-bool
paludis::resolver::resolver_test::allowed_to_remove_fn(
const std::tr1::shared_ptr<const QualifiedPackageNameSet> & s,
const std::tr1::shared_ptr<const PackageID> & i)
@@ -319,7 +311,6 @@ paludis::resolver::resolver_test::get_constraints_for_dependent_fn(
ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s, const std::string & e,
const std::string & l) :
TestCase(s),
- allowed_to_break_names(new QualifiedPackageNameSet),
allowed_to_remove_names(new QualifiedPackageNameSet),
remove_if_dependent_names(new QualifiedPackageNameSet),
prefer_or_avoid_names(new Map<QualifiedPackageName, bool>)
@@ -368,8 +359,6 @@ ResolverFunctions
ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraints)
{
return make_named_values<ResolverFunctions>(
- n::allowed_to_break_fn() = std::tr1::bind(&allowed_to_break_fn,
- allowed_to_break_names, std::tr1::placeholders::_1),
n::allowed_to_remove_fn() = std::tr1::bind(&allowed_to_remove_fn,
allowed_to_remove_names, std::tr1::placeholders::_1),
n::confirm_fn() = &confirm_fn,
@@ -465,6 +454,7 @@ ResolverTestCase::check_resolved(
const std::tr1::shared_ptr<const Resolved> & resolved,
const NamedValue<n::taken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & taken_change_or_remove_decisions,
const NamedValue<n::taken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & taken_unable_to_make_decisions,
+ const NamedValue<n::taken_unconfirmed_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & taken_unconfirmed_decisions,
const NamedValue<n::untaken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & untaken_change_or_remove_decisions,
const NamedValue<n::untaken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & untaken_unable_to_make_decisions
)
@@ -480,6 +470,11 @@ ResolverTestCase::check_resolved(
}
{
+ TestMessageSuffix s("taken unconfirmed");
+ check_resolved_one(resolved->taken_unconfirmed_decisions(), taken_unconfirmed_decisions());
+ }
+
+ {
TestMessageSuffix s("untaken change or remove");
check_resolved_one(resolved->untaken_change_or_remove_decisions(), untaken_change_or_remove_decisions());
}
@@ -501,6 +496,16 @@ ResolverTestCase::DecisionChecks::finished()
}
ResolverTestCase::DecisionChecks &
+ResolverTestCase::DecisionChecks::breaking(const QualifiedPackageName & q)
+{
+ checks.push_back(std::make_pair(
+ std::tr1::bind(&check_breaking, q, std::tr1::placeholders::_1),
+ std::tr1::bind(&check_breaking_msg, q, std::tr1::placeholders::_1)
+ ));
+ return *this;
+}
+
+ResolverTestCase::DecisionChecks &
ResolverTestCase::DecisionChecks::change(const QualifiedPackageName & q)
{
checks.push_back(std::make_pair(
@@ -552,6 +557,15 @@ ResolverTestCase::DecisionChecks::check_change(const QualifiedPackageName & q, c
}
bool
+ResolverTestCase::DecisionChecks::check_breaking(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & d)
+{
+ if (! d)
+ return false;
+
+ return simple_visitor_cast<const BreakDecision>(*d) && d->resolvent().package() == q;
+}
+
+bool
ResolverTestCase::DecisionChecks::check_remove(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & d)
{
if (! d)
@@ -576,6 +590,12 @@ ResolverTestCase::DecisionChecks::check_change_msg(const QualifiedPackageName &
}
std::string
+ResolverTestCase::DecisionChecks::check_breaking_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r)
+{
+ return check_generic_msg("break " + stringify(q), r);
+}
+
+std::string
ResolverTestCase::DecisionChecks::check_remove_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r)
{
return check_generic_msg("remove " + stringify(q), r);
@@ -611,6 +631,11 @@ namespace
return "ExistingNoChangeDecision";
}
+ std::string visit(const BreakDecision &) const
+ {
+ return "BreakDecision";
+ }
+
std::string visit(const RemoveDecision &) const
{
return "RemoveDecision";
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index 4693ea7..411e752 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -93,10 +93,6 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const Reason> &);
- bool allowed_to_break_fn(
- const std::tr1::shared_ptr<const QualifiedPackageNameSet> &,
- const std::tr1::shared_ptr<const PackageID> &);
-
bool allowed_to_remove_fn(
const std::tr1::shared_ptr<const QualifiedPackageNameSet> &,
const std::tr1::shared_ptr<const PackageID> &);
@@ -118,7 +114,6 @@ namespace paludis
TestEnvironment env;
std::tr1::shared_ptr<Repository> repo, inst_repo;
std::tr1::shared_ptr<FakeInstalledRepository> fake_inst_repo;
- std::tr1::shared_ptr<QualifiedPackageNameSet> allowed_to_break_names;
std::tr1::shared_ptr<QualifiedPackageNameSet> allowed_to_remove_names;
std::tr1::shared_ptr<QualifiedPackageNameSet> remove_if_dependent_names;
std::tr1::shared_ptr<Map<QualifiedPackageName, bool> > prefer_or_avoid_names;
@@ -149,12 +144,16 @@ namespace paludis
static bool check_unable(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
static std::string check_unable_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
+ static bool check_breaking(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
+ static std::string check_breaking_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
+
static bool check_finished(const std::tr1::shared_ptr<const Decision> & r);
static std::string check_finished_msg(const std::tr1::shared_ptr<const Decision> & r);
DecisionChecks & change(const QualifiedPackageName & q);
DecisionChecks & remove(const QualifiedPackageName & q);
DecisionChecks & unable(const QualifiedPackageName & q);
+ DecisionChecks & breaking(const QualifiedPackageName & q);
DecisionChecks & finished();
};
@@ -167,6 +166,7 @@ namespace paludis
const std::tr1::shared_ptr<const Resolved> &,
const NamedValue<n::taken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
const NamedValue<n::taken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
+ const NamedValue<n::taken_unconfirmed_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
const NamedValue<n::untaken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
const NamedValue<n::untaken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &
);
diff --git a/paludis/resolver/sanitised_dependencies.cc b/paludis/resolver/sanitised_dependencies.cc
index 4cb4aca..8b3cd07 100644
--- a/paludis/resolver/sanitised_dependencies.cc
+++ b/paludis/resolver/sanitised_dependencies.cc
@@ -109,6 +109,7 @@ namespace
{
const Decider & decider;
const std::tr1::shared_ptr<const Resolution> our_resolution;
+ const std::tr1::shared_ptr<const PackageID> our_id;
const std::tr1::function<SanitisedDependency (const PackageOrBlockDepSpec &)> parent_make_sanitised;
bool super_complicated, nested;
@@ -119,9 +120,11 @@ namespace
bool seen_any;
AnyDepSpecChildHandler(const Decider & r, const std::tr1::shared_ptr<const Resolution> & q,
+ const std::tr1::shared_ptr<const PackageID> & o,
const std::tr1::function<SanitisedDependency (const PackageOrBlockDepSpec &)> & f) :
decider(r),
our_resolution(q),
+ our_id(o),
parent_make_sanitised(f),
super_complicated(false),
nested(false),
@@ -210,7 +213,7 @@ namespace
void visit(const DependencySpecTree::NodeType<AnyDepSpec>::Type & node)
{
- AnyDepSpecChildHandler h(decider, our_resolution, parent_make_sanitised);
+ AnyDepSpecChildHandler h(decider, our_resolution, our_id, parent_make_sanitised);
std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(h));
std::list<SanitisedDependency> l;
h.commit(
@@ -271,7 +274,7 @@ namespace
h != h_end ; ++h)
{
std::pair<AnyChildScore, OperatorScore> score(
- decider.find_any_score(our_resolution, make_sanitised(PackageOrBlockDepSpec(*h))));
+ decider.find_any_score(our_resolution, our_id, make_sanitised(PackageOrBlockDepSpec(*h))));
if (score < worst_score)
worst_score = score;
}
@@ -296,6 +299,7 @@ namespace
{
const Decider & decider;
const std::tr1::shared_ptr<const Resolution> our_resolution;
+ const std::tr1::shared_ptr<const PackageID> & our_id;
SanitisedDependencies & sanitised_dependencies;
const std::string raw_name;
const std::string human_name;
@@ -305,6 +309,7 @@ namespace
Finder(
const Decider & r,
const std::tr1::shared_ptr<const Resolution> & q,
+ const std::tr1::shared_ptr<const PackageID> & f,
SanitisedDependencies & s,
const std::tr1::shared_ptr<const DependenciesLabelSequence> & l,
const std::string & rn,
@@ -312,6 +317,7 @@ namespace
const std::string & a) :
decider(r),
our_resolution(q),
+ our_id(f),
sanitised_dependencies(s),
raw_name(rn),
human_name(hn),
@@ -386,7 +392,8 @@ namespace
original_specs_as_string = "|| (" + v.result + " )";
}
- AnyDepSpecChildHandler h(decider, our_resolution, std::tr1::bind(&Finder::make_sanitised, this, std::tr1::placeholders::_1));
+ AnyDepSpecChildHandler h(decider, our_resolution, our_id,
+ std::tr1::bind(&Finder::make_sanitised, this, std::tr1::placeholders::_1));
std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(h));
h.commit(
std::tr1::bind(&Finder::make_sanitised, this, std::tr1::placeholders::_1),
@@ -442,7 +449,7 @@ SanitisedDependencies::_populate_one(
{
Context context("When finding dependencies for '" + stringify(*id) + "' from key '" + ((*id).*pmf)()->raw_name() + "':");
- Finder f(decider, resolution, *this, ((*id).*pmf)()->initial_labels(), ((*id).*pmf)()->raw_name(),
+ Finder f(decider, resolution, id, *this, ((*id).*pmf)()->initial_labels(), ((*id).*pmf)()->raw_name(),
((*id).*pmf)()->human_name(), "");
((*id).*pmf)()->value()->root()->accept(f);
}
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index 07a24f5..7d6842c 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -235,6 +235,11 @@ namespace
return d.existing_id();
}
+ const std::tr1::shared_ptr<const PackageID> visit(const BreakDecision & d) const
+ {
+ return d.existing_id();
+ }
+
const std::tr1::shared_ptr<const PackageID> visit(const ChangesToMakeDecision & d) const
{
return d.origin_id();
@@ -387,6 +392,14 @@ namespace
else
cout << " No decision could be made, but none was necessary" << endl;
}
+
+ void visit(const BreakDecision & d) const
+ {
+ if (d.taken())
+ cout << " The decision made was to break " << *d.existing_id() << endl;
+ else
+ cout << " The decision made would be to break " << *d.existing_id() << endl;
+ }
};
void display_explanation_decision(const Decision & decision)
@@ -645,6 +658,11 @@ namespace
{
return "--permit-old-version";
}
+
+ std::string visit(const BreakConfirmation &) const
+ {
+ return "--uninstalls-may-break or --remove-if-dependent";
+ }
};
std::string stringify_confirmation(const RequiredConfirmation & c)
@@ -653,7 +671,7 @@ namespace
}
void display_confirmations(
- const ChangesToMakeDecision & decision)
+ const ConfirmableDecision & decision)
{
const std::tr1::shared_ptr<const RequiredConfirmations> r(decision.required_confirmations_if_any());
if (r && ! r->empty())
@@ -1090,18 +1108,37 @@ namespace
}
}
- std::pair<std::tr1::shared_ptr<const ChangeOrRemoveDecision>, std::tr1::shared_ptr<const OrdererNotes> >
- get_decision_and_notes(const std::tr1::shared_ptr<const ChangeOrRemoveDecision> & d)
+ std::pair<std::tr1::shared_ptr<const ConfirmableDecision>, std::tr1::shared_ptr<const OrdererNotes> >
+ get_decision_and_notes(const std::tr1::shared_ptr<const ConfirmableDecision> & d)
{
return std::make_pair(d, make_null_shared_ptr());
}
- std::pair<std::tr1::shared_ptr<const ChangeOrRemoveDecision>, std::tr1::shared_ptr<const OrdererNotes> >
- get_decision_and_notes(const std::pair<std::tr1::shared_ptr<const ChangeOrRemoveDecision>, std::tr1::shared_ptr<const OrdererNotes> > & d)
+ std::pair<std::tr1::shared_ptr<const ConfirmableDecision>, std::tr1::shared_ptr<const OrdererNotes> >
+ get_decision_and_notes(const std::pair<std::tr1::shared_ptr<const ConfirmableDecision>, std::tr1::shared_ptr<const OrdererNotes> > & d)
{
return d;
}
+ void display_one_break(
+ const std::tr1::shared_ptr<Environment> &,
+ const DisplayResolutionCommandLine &,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const BreakDecision & decision,
+ const bool more_annotations,
+ const bool untaken)
+ {
+ if (untaken)
+ cout << "(X) " << c::bold_red() << decision.resolvent().package() << c::normal() << " ";
+ else
+ cout << "X " << c::bold_red() << decision.resolvent().package() << c::normal() << " ";
+
+ cout << decision.existing_id()->canonical_form(idcf_no_name) << endl;
+ cout << " Will be broken by uninstalls:" << endl;
+ display_reasons(resolution, more_annotations);
+ display_confirmations(decision);
+ }
+
template <typename Decisions_>
void display_a_changes_and_removes(
const std::tr1::shared_ptr<Environment> & env,
@@ -1129,11 +1166,12 @@ namespace
any = true;
const std::pair<
- std::tr1::shared_ptr<const ChangeOrRemoveDecision>,
+ std::tr1::shared_ptr<const ConfirmableDecision>,
std::tr1::shared_ptr<const OrdererNotes> > star_i(get_decision_and_notes(*i));
const ChangesToMakeDecision * const changes_to_make_decision(simple_visitor_cast<const ChangesToMakeDecision>(*star_i.first));
const RemoveDecision * const remove_decision(simple_visitor_cast<const RemoveDecision>(*star_i.first));
+ const BreakDecision * const break_decision(simple_visitor_cast<const BreakDecision>(*star_i.first));
if (changes_to_make_decision)
{
display_one_installish(
@@ -1157,6 +1195,16 @@ namespace
more_annotations,
untaken);
}
+ else if (break_decision)
+ {
+ display_one_break(
+ env,
+ cmdline,
+ *resolved->resolutions_by_resolvent()->find(break_decision->resolvent()),
+ *break_decision,
+ more_annotations,
+ untaken);
+ }
else
throw InternalError(PALUDIS_HERE, "huh?");
}
@@ -1243,8 +1291,8 @@ namespace
const DisplayResolutionCommandLine & cmdline)
{
ChoicesToExplain ignore_choices_to_explain;
- if (! resolved->taken_unconfirmed_change_or_remove_decisions()->empty())
- display_a_changes_and_removes(env, resolved, resolved->taken_unconfirmed_change_or_remove_decisions(),
+ if (! resolved->taken_unconfirmed_decisions()->empty())
+ display_a_changes_and_removes(env, resolved, resolved->taken_unconfirmed_decisions(),
cmdline, ignore_choices_to_explain, true, true, false);
}
}
diff --git a/src/clients/cave/cmd_resolve_dump.cc b/src/clients/cave/cmd_resolve_dump.cc
index 0dd42a1..e914c03 100644
--- a/src/clients/cave/cmd_resolve_dump.cc
+++ b/src/clients/cave/cmd_resolve_dump.cc
@@ -100,6 +100,11 @@ namespace
+ " destination: " + stringify_if_not_null(d.destination())
+ ")";
}
+
+ const std::string visit(const BreakDecision & d) const
+ {
+ return "BreakDecision(taken: " + stringify(d.taken()) + " existing_id: " + stringify(*d.existing_id()) + ")";
+ }
};
std::ostream &
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index dd6ffa6..e640825 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -818,6 +818,11 @@ namespace
throw InternalError(PALUDIS_HERE, "RemoveDecision shouldn't have deps");
}
+ bool visit(const BreakDecision &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "BreakDecision shouldn't have deps");
+ }
+
bool visit(const ChangesToMakeDecision & decision) const
{
if (ignore_dep_from(env, resolution_options, no_blockers_from,
@@ -990,14 +995,6 @@ namespace
return false;
}
- bool allowed_to_break_fn(
- const Environment * const env,
- const PackageDepSpecList & list,
- const std::tr1::shared_ptr<const PackageID> & i)
- {
- return match_any(env, list, i);
- }
-
bool allowed_to_remove_fn(
const Environment * const env,
const PackageDepSpecList & list,
@@ -1060,6 +1057,11 @@ namespace
return decision.origin_id();
}
+ const std::tr1::shared_ptr<const PackageID> visit(const BreakDecision & decision) const
+ {
+ return decision.existing_id();
+ }
+
const std::tr1::shared_ptr<const PackageID> visit(const ExistingNoChangeDecision & decision) const
{
return decision.existing_id();
@@ -1087,17 +1089,20 @@ namespace
const ResolveCommandLineResolutionOptions & resolution_options;
const PackageDepSpecList & permit_downgrade;
const PackageDepSpecList & permit_old_version;
+ const PackageDepSpecList & allowed_to_break_specs;
const std::tr1::shared_ptr<const PackageID> id;
ConfirmFnVisitor(const Environment * const e,
const ResolveCommandLineResolutionOptions & r,
const PackageDepSpecList & d,
const PackageDepSpecList & o,
+ const PackageDepSpecList & a,
const std::tr1::shared_ptr<const PackageID> & i) :
env(e),
resolution_options(r),
permit_downgrade(d),
permit_old_version(o),
+ allowed_to_break_specs(a),
id(i)
{
}
@@ -1127,6 +1132,19 @@ namespace
return false;
}
+
+ bool visit(const BreakConfirmation &) const
+ {
+ if (id)
+ for (PackageDepSpecList::const_iterator l(allowed_to_break_specs.begin()), l_end(allowed_to_break_specs.end()) ;
+ l != l_end ; ++l)
+ {
+ if (match_package(*env, *l, *id, MatchPackageOptions()))
+ return true;
+ }
+
+ return false;
+ }
};
bool confirm_fn(
@@ -1134,10 +1152,11 @@ namespace
const ResolveCommandLineResolutionOptions & resolution_options,
const PackageDepSpecList & permit_downgrade,
const PackageDepSpecList & permit_old_version,
+ const PackageDepSpecList & allowed_to_break_specs,
const std::tr1::shared_ptr<const Resolution> & r,
const std::tr1::shared_ptr<const RequiredConfirmation> & c)
{
- return c->accept_returning<bool>(ConfirmFnVisitor(env, resolution_options, permit_downgrade, permit_old_version,
+ return c->accept_returning<bool>(ConfirmFnVisitor(env, resolution_options, permit_downgrade, permit_old_version, allowed_to_break_specs,
r->decision()->accept_returning<std::tr1::shared_ptr<const PackageID> >(ChosenIDVisitor())
));
}
@@ -1349,6 +1368,11 @@ namespace
return "remove_decision";
}
+ const std::string visit(const BreakDecision &) const
+ {
+ return "break_decision";
+ }
+
const std::string visit(const UnableToMakeDecision &) const
{
return "unable_to_make_decision";
@@ -1603,13 +1627,11 @@ paludis::cave::resolve_common(
using std::tr1::placeholders::_4;
ResolverFunctions resolver_functions(make_named_values<ResolverFunctions>(
- n::allowed_to_break_fn() = std::tr1::bind(&allowed_to_break_fn,
- env.get(), std::tr1::cref(allowed_to_break_specs), _1),
n::allowed_to_remove_fn() = std::tr1::bind(&allowed_to_remove_fn,
env.get(), std::tr1::cref(allowed_to_remove_specs), _1),
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), _1, _2),
+ std::tr1::cref(permit_old_version), std::tr1::cref(allowed_to_break_specs), _1, _2),
n::find_repository_for_fn() = std::tr1::bind(&find_repository_for_fn,
env.get(), std::tr1::cref(resolution_options), _1, _2),
n::get_constraints_for_dependent_fn() = std::tr1::bind(&get_constraints_for_dependent_fn,
@@ -1684,7 +1706,7 @@ paludis::cave::resolve_common(
if (! resolver->resolved()->taken_unable_to_make_decisions()->empty())
retcode |= 1;
- if (! resolver->resolved()->taken_unconfirmed_change_or_remove_decisions()->empty())
+ if (! resolver->resolved()->taken_unconfirmed_decisions()->empty())
retcode |= 3;
if (0 == retcode)