aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-08 00:45:15 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-09-08 00:45:15 +0100
commit9b92b14983d6874d7f1192003c74688f60271268 (patch)
tree9e342b63a1542b60da3a06942eafba4b6d69913a
parent5aee8457e0ecc73e5c7f3b643f815b5237a6d972 (diff)
downloadpaludis-9b92b14983d6874d7f1192003c74688f60271268.tar.gz
paludis-9b92b14983d6874d7f1192003c74688f60271268.tar.xz
Start of some nicer error handling
-rw-r--r--paludis/resolver/Makefile.am11
-rw-r--r--paludis/resolver/decision-fwd.hh4
-rw-r--r--paludis/resolver/decision.cc11
-rw-r--r--paludis/resolver/decision.hh6
-rw-r--r--paludis/resolver/decision.se16
-rw-r--r--paludis/resolver/resolutions.cc8
-rw-r--r--paludis/resolver/resolutions.hh4
-rw-r--r--paludis/resolver/resolver.cc125
-rw-r--r--paludis/resolver/resolver.hh6
-rw-r--r--src/clients/cave/cmd_display_resolution.cc146
-rw-r--r--src/clients/cave/cmd_resolve.cc6
-rw-r--r--src/clients/cave/cmd_resolve_dump.cc6
12 files changed, 248 insertions, 101 deletions
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index 62f2333..7735ab6 100644
--- a/paludis/resolver/Makefile.am
+++ b/paludis/resolver/Makefile.am
@@ -1,11 +1,14 @@
CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda *.loT *.epicfail
MAINTAINERCLEANFILES = Makefile.in
DISTCLEANFILES = \
+ decision-se.hh decision-se.cc \
use_installed-se.hh use_installed-se.cc
AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
EXTRA_DIST = \
+ decision-se.hh decision-se.cc decision.se \
use_installed-se.hh use_installed-se.cc use_installed.se
BUILT_SOURCES = \
+ decision-se.hh decision-se.cc \
use_installed-se.hh use_installed-se.cc
TESTS =
@@ -13,7 +16,7 @@ TESTS =
noinst_HEADERS = \
arrow.hh arrow-fwd.hh \
constraint.hh constraint-fwd.hh \
- decision.hh decision-fwd.hh \
+ decision.hh decision-fwd.hh decision-se.hh \
destinations.hh destinations-fwd.hh \
qpn_s.hh qpn_s-fwd.hh \
reason.hh reason-fwd.hh \
@@ -72,3 +75,9 @@ use_installed-se.hh : use_installed.se $(top_srcdir)/misc/make_se.bash
use_installed-se.cc : use_installed.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/use_installed.se > $@ ; then rm -f $@ ; exit 1 ; fi
+decision-se.hh : decision.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/decision.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
+decision-se.cc : decision.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/decision.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
diff --git a/paludis/resolver/decision-fwd.hh b/paludis/resolver/decision-fwd.hh
index d18f247..9acc9c1 100644
--- a/paludis/resolver/decision-fwd.hh
+++ b/paludis/resolver/decision-fwd.hh
@@ -21,11 +21,15 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_DECISION_FWD_HH 1
#include <paludis/util/attributes.hh>
+#include <iosfwd>
namespace paludis
{
namespace resolver
{
+
+#include <paludis/resolver/decision-se.hh>
+
struct Decision;
}
}
diff --git a/paludis/resolver/decision.cc b/paludis/resolver/decision.cc
index 87b47d3..6229080 100644
--- a/paludis/resolver/decision.cc
+++ b/paludis/resolver/decision.cc
@@ -20,22 +20,24 @@
#include <paludis/resolver/decision.hh>
#include <paludis/resolver/serialise-impl.hh>
#include <paludis/util/make_named_values.hh>
+#include <paludis/util/stringify.hh>
#include <sstream>
using namespace paludis;
using namespace paludis::resolver;
+#include <paludis/resolver/decision-se.cc>
+
void
Decision::serialise(Serialiser & s) const
{
s.object("Decision")
.member(SerialiserFlags<serialise::might_be_null>(), "if_package_id", if_package_id())
.member(SerialiserFlags<>(), "is_best", is_best())
- .member(SerialiserFlags<>(), "is_installed", is_installed())
- .member(SerialiserFlags<>(), "is_nothing", is_nothing())
.member(SerialiserFlags<>(), "is_same", is_same())
.member(SerialiserFlags<>(), "is_same_version", is_same_version())
.member(SerialiserFlags<>(), "is_transient", is_transient())
+ .member(SerialiserFlags<>(), "kind", stringify(kind()))
;
}
@@ -46,11 +48,10 @@ Decision::deserialise(Deserialisation & d)
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(v.member<std::tr1::shared_ptr<const PackageID> >("if_package_id")),
value_for<n::is_best>(v.member<bool>("is_best")),
- value_for<n::is_installed>(v.member<bool>("is_installed")),
- value_for<n::is_nothing>(v.member<bool>("is_nothing")),
value_for<n::is_same>(v.member<bool>("is_same")),
value_for<n::is_same_version>(v.member<bool>("is_same_version")),
- value_for<n::is_transient>(v.member<bool>("is_transient"))
+ value_for<n::is_transient>(v.member<bool>("is_transient")),
+ value_for<n::kind>(destringify<DecisionKind>(v.member<std::string>("kind")))
)));
}
diff --git a/paludis/resolver/decision.hh b/paludis/resolver/decision.hh
index a0c6728..056d458 100644
--- a/paludis/resolver/decision.hh
+++ b/paludis/resolver/decision.hh
@@ -31,11 +31,10 @@ namespace paludis
{
struct if_package_id;
struct is_best;
- struct is_installed;
- struct is_nothing;
struct is_same;
struct is_same_version;
struct is_transient;
+ struct kind;
}
namespace resolver
@@ -44,11 +43,10 @@ namespace paludis
{
NamedValue<n::if_package_id, std::tr1::shared_ptr<const PackageID> > if_package_id;
NamedValue<n::is_best, bool> is_best;
- NamedValue<n::is_installed, bool> is_installed;
- NamedValue<n::is_nothing, bool> is_nothing;
NamedValue<n::is_same, bool> is_same;
NamedValue<n::is_same_version, bool> is_same_version;
NamedValue<n::is_transient, bool> is_transient;
+ NamedValue<n::kind, DecisionKind> kind;
void serialise(Serialiser &) const;
diff --git a/paludis/resolver/decision.se b/paludis/resolver/decision.se
new file mode 100644
index 0000000..a148a3d
--- /dev/null
+++ b/paludis/resolver/decision.se
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_DecisionKind()
+{
+ prefix dk
+ namespace paludis::resolver
+
+ key dk_installed "Installed package"
+ key dk_unable_to_decide "We couldn't decide. No if_package_id."
+ key dk_installable "Installable package"
+ key dk_nothing "We decided nothing"
+
+ want_destringify
+}
+
diff --git a/paludis/resolver/resolutions.cc b/paludis/resolver/resolutions.cc
index c0c2af1..aaf2938 100644
--- a/paludis/resolver/resolutions.cc
+++ b/paludis/resolver/resolutions.cc
@@ -65,6 +65,12 @@ Resolutions::end() const
return ConstIterator(_imp->resolutions.end());
}
+bool
+Resolutions::empty() const
+{
+ return begin() == end();
+}
+
void
Resolutions::serialise(Serialiser & s) const
{
@@ -89,6 +95,7 @@ ResolutionLists::serialise(Serialiser & s) const
{
s.object("ResolutionLists")
.member(SerialiserFlags<serialise::might_be_null>(), "all", all())
+ .member(SerialiserFlags<serialise::might_be_null>(), "errors", errors())
.member(SerialiserFlags<serialise::might_be_null>(), "ordered", ordered())
;
}
@@ -99,6 +106,7 @@ ResolutionLists::deserialise(Deserialisation & d)
Deserialisator v(d, "ResolutionLists");
return make_named_values<ResolutionLists>(
value_for<n::all>(v.member<std::tr1::shared_ptr<Resolutions> >("all")),
+ value_for<n::errors>(v.member<std::tr1::shared_ptr<Resolutions> >("errors")),
value_for<n::ordered>(v.member<std::tr1::shared_ptr<Resolutions> >("ordered"))
);
}
diff --git a/paludis/resolver/resolutions.hh b/paludis/resolver/resolutions.hh
index c57c4c8..695873f 100644
--- a/paludis/resolver/resolutions.hh
+++ b/paludis/resolver/resolutions.hh
@@ -33,6 +33,7 @@ namespace paludis
namespace n
{
struct all;
+ struct errors;
struct ordered;
}
@@ -41,6 +42,7 @@ namespace paludis
struct ResolutionLists
{
NamedValue<n::all, std::tr1::shared_ptr<Resolutions> > all;
+ NamedValue<n::errors, std::tr1::shared_ptr<Resolutions> > errors;
NamedValue<n::ordered, std::tr1::shared_ptr<Resolutions> > ordered;
void serialise(Serialiser &) const;
@@ -63,6 +65,8 @@ namespace paludis
ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool empty() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
void serialise(Serialiser &) const;
static const std::tr1::shared_ptr<Resolutions> deserialise(
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index f8d3b63..cbd2e86 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -79,6 +79,7 @@ namespace paludis
fns(f),
resolution_lists(new ResolutionLists(make_named_values<ResolutionLists>(
value_for<n::all>(new Resolutions),
+ value_for<n::errors>(new Resolutions),
value_for<n::ordered>(new Resolutions)
)))
{
@@ -127,8 +128,17 @@ Resolver::_resolve_dependencies()
done = false;
_decide(i->first, i->second);
- if (i->second->decision()->is_nothing())
- continue;
+ switch (i->second->decision()->kind())
+ {
+ case dk_installed:
+ case dk_installable:
+ break;
+
+ case dk_nothing:
+ case dk_unable_to_decide:
+ case last_dk:
+ continue;
+ }
_add_dependencies(i->first, i->second);
}
@@ -156,10 +166,19 @@ Resolver::_make_destinations_for(const QPN_S & qpn_s,
{
Context context("When finding destinations for '" + stringify(qpn_s) + "':");
- if (resolution->decision()->is_installed() || resolution->decision()->is_nothing())
- return make_shared_ptr(new Destinations(make_named_values<Destinations>(
- value_for<n::slash>(make_null_shared_ptr())
- )));
+ switch (resolution->decision()->kind())
+ {
+ case dk_installed:
+ case dk_nothing:
+ case dk_unable_to_decide:
+ return make_shared_ptr(new Destinations(make_named_values<Destinations>(
+ value_for<n::slash>(make_null_shared_ptr())
+ )));
+
+ case last_dk:
+ case dk_installable:
+ break;
+ }
bool requires_slash(resolution->constraints()->to_destination_slash());
@@ -433,7 +452,7 @@ Resolver::_verify_new_constraint(const QPN_S & qpn_s,
else
ok = constraint->nothing_is_fine_too();
- if (ok && resolution->decision()->is_installed())
+ if (ok && dk_installed == resolution->decision()->kind())
{
switch (constraint->use_installed())
{
@@ -495,7 +514,7 @@ Resolver::_made_wrong_decision(const QPN_S & qpn_s,
}
}
else
- _unable_to_decide(qpn_s, adapted_resolution);
+ throw InternalError(PALUDIS_HERE, "made decision, now can't make one");
}
void
@@ -536,7 +555,7 @@ Resolver::_decide(const QPN_S & qpn_s, const std::tr1::shared_ptr<Resolution> &
if (decision)
resolution->decision() = decision;
else
- _unable_to_decide(qpn_s, resolution);
+ resolution->decision() = _cannot_decide_for(qpn_s, resolution);
}
void
@@ -753,8 +772,24 @@ Resolver::_resolve_order()
for (ResolutionsByQPN_SMap::iterator i(_imp->resolutions_by_qpn_s.begin()), i_end(_imp->resolutions_by_qpn_s.end()) ;
i != i_end ; ++i)
- if (i->second->decision()->is_installed() || i->second->decision()->is_nothing())
- i->second->already_ordered() = true;
+ {
+ switch (i->second->decision()->kind())
+ {
+ case dk_installed:
+ case dk_nothing:
+ i->second->already_ordered() = true;
+ break;
+
+ case dk_unable_to_decide:
+ i->second->already_ordered() = true;
+ _imp->resolution_lists->errors()->append(i->second);
+ break;
+
+ case last_dk:
+ case dk_installable:
+ break;
+ }
+ }
while (! done)
{
@@ -829,14 +864,6 @@ Resolver::_do_order(const QPN_S &, const std::tr1::shared_ptr<Resolution> & reso
}
void
-Resolver::_unable_to_decide(
- const QPN_S &,
- const std::tr1::shared_ptr<const Resolution> &) const
-{
- throw InternalError(PALUDIS_HERE, "not implemented");
-}
-
-void
Resolver::_unable_to_order_more() const
{
std::cout << "Unable to order any of the following:" << std::endl;
@@ -1159,11 +1186,10 @@ Resolver::_try_to_find_decision_for(
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(make_null_shared_ptr()),
value_for<n::is_best>(false),
- value_for<n::is_installed>(false),
- value_for<n::is_nothing>(true),
value_for<n::is_same>(false),
value_for<n::is_same_version>(false),
- value_for<n::is_transient>(false)
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_nothing)
)));
}
else if (installable_id && ! installed_id)
@@ -1172,11 +1198,10 @@ Resolver::_try_to_find_decision_for(
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installable_id),
value_for<n::is_best>(best),
- value_for<n::is_installed>(false),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(false),
value_for<n::is_same_version>(false),
- value_for<n::is_transient>(false)
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_installable)
)));
}
else if (installed_id && ! installable_id)
@@ -1206,11 +1231,10 @@ Resolver::_try_to_find_decision_for(
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installed_id),
value_for<n::is_best>(false),
- value_for<n::is_installed>(true),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(true),
value_for<n::is_same_version>(true),
- value_for<n::is_transient>(is_transient)
+ value_for<n::is_transient>(is_transient),
+ value_for<n::kind>(dk_installed)
)));
}
else if ((! installed_id) && (! installable_id))
@@ -1233,11 +1257,10 @@ Resolver::_try_to_find_decision_for(
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installable_id),
value_for<n::is_best>(best),
- value_for<n::is_installed>(false),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(is_same),
value_for<n::is_same_version>(is_same_version),
- value_for<n::is_transient>(false)
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_installable)
)));
case ui_if_same:
@@ -1245,21 +1268,19 @@ Resolver::_try_to_find_decision_for(
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installed_id),
value_for<n::is_best>(false),
- value_for<n::is_installed>(true),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(is_same),
value_for<n::is_same_version>(is_same_version),
- value_for<n::is_transient>(false)
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_installed)
)));
else
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installable_id),
value_for<n::is_best>(best),
- value_for<n::is_installed>(false),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(is_same),
value_for<n::is_same_version>(is_same_version),
- value_for<n::is_transient>(is_transient)
+ value_for<n::is_transient>(is_transient),
+ value_for<n::kind>(dk_installable)
)));
case ui_if_same_version:
@@ -1267,32 +1288,29 @@ Resolver::_try_to_find_decision_for(
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installed_id),
value_for<n::is_best>(false),
- value_for<n::is_installed>(true),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(is_same),
value_for<n::is_same_version>(is_same_version),
- value_for<n::is_transient>(false)
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_installed)
)));
else
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installable_id),
value_for<n::is_best>(best),
- value_for<n::is_installed>(false),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(is_same),
value_for<n::is_same_version>(is_same_version),
- value_for<n::is_transient>(is_transient)
+ value_for<n::is_transient>(is_transient),
+ value_for<n::kind>(dk_installable)
)));
case ui_if_possible:
return make_shared_ptr(new Decision(make_named_values<Decision>(
value_for<n::if_package_id>(installed_id),
value_for<n::is_best>(false),
- value_for<n::is_installed>(true),
- value_for<n::is_nothing>(false),
value_for<n::is_same>(is_same),
value_for<n::is_same_version>(is_same_version),
- value_for<n::is_transient>(false)
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_installed)
)));
case last_ui:
@@ -1303,6 +1321,21 @@ Resolver::_try_to_find_decision_for(
throw InternalError(PALUDIS_HERE, "why did that happen?");
}
+const std::tr1::shared_ptr<Decision>
+Resolver::_cannot_decide_for(
+ const QPN_S &,
+ const std::tr1::shared_ptr<const Resolution> &) const
+{
+ return make_shared_ptr(new Decision(make_named_values<Decision>(
+ value_for<n::if_package_id>(make_null_shared_ptr()),
+ value_for<n::is_best>(false),
+ value_for<n::is_same>(false),
+ value_for<n::is_same_version>(false),
+ value_for<n::is_transient>(false),
+ value_for<n::kind>(dk_unable_to_decide)
+ )));
+}
+
const std::tr1::shared_ptr<const PackageID>
Resolver::_find_installed_id_for(const QPN_S & qpn_s, const std::tr1::shared_ptr<const Resolution> & resolution) const
{
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index 37e3fd7..1c057a3 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -114,6 +114,9 @@ namespace paludis
const std::tr1::shared_ptr<Decision> _try_to_find_decision_for(
const QPN_S &, const std::tr1::shared_ptr<const Resolution> & resolution) const;
+ const std::tr1::shared_ptr<Decision> _cannot_decide_for(
+ const QPN_S &, const std::tr1::shared_ptr<const Resolution> & resolution) const;
+
void _add_dependencies(const QPN_S & our_qpn_s, const std::tr1::shared_ptr<Resolution> & our_resolution);
bool _care_about_dependency_spec(const QPN_S &, const std::tr1::shared_ptr<const Resolution> &,
@@ -126,9 +129,6 @@ namespace paludis
void _do_order(const QPN_S &, const std::tr1::shared_ptr<Resolution> & resolution);
- void _unable_to_decide(const QPN_S &,
- const std::tr1::shared_ptr<const Resolution> &) const PALUDIS_ATTRIBUTE((noreturn));
-
void _unable_to_order_more() const PALUDIS_ATTRIBUTE((noreturn));
const std::tr1::shared_ptr<Constraints> _initial_constraints_for(const QPN_S &) const;
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index a721791..8ac62dc 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -96,13 +96,26 @@ namespace
struct ReasonNameGetter
{
+ const bool verbose;
+
+ ReasonNameGetter(const bool v) :
+ verbose(v)
+ {
+ }
+
std::pair<std::string, bool> visit(const DependencyReason & r) const
{
if (r.sanitised_dependency().spec().if_block())
return std::make_pair(stringify(r.from_id()->name()) + " blocker " +
stringify(*r.sanitised_dependency().spec().if_block()), true);
else
- return std::make_pair(stringify(r.from_id()->name()), false);
+ {
+ if (verbose)
+ return std::make_pair(stringify(*r.from_id()) + " dependency "
+ + stringify(*r.sanitised_dependency().spec().if_package()), false);
+ else
+ return std::make_pair(stringify(r.from_id()->name()), false);
+ }
}
std::pair<std::string, bool> visit(const TargetReason &) const
@@ -122,6 +135,68 @@ namespace
}
};
+ void display_reasons(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const bool verbose)
+ {
+ std::set<std::string> reason_names, special_reason_names;
+ for (Constraints::ConstIterator r(resolution->constraints()->begin()),
+ r_end(resolution->constraints()->end()) ;
+ r != r_end ; ++r)
+ {
+ ReasonNameGetter g(verbose);
+ std::pair<std::string, bool> s((*r)->reason()->accept_returning<std::pair<std::string, bool> >(g));
+ if (! s.first.empty())
+ {
+ if (s.second)
+ special_reason_names.insert(s.first);
+ else
+ reason_names.insert(s.first);
+ }
+ }
+
+ if ((! special_reason_names.empty()) || (! reason_names.empty()))
+ {
+ if (verbose)
+ {
+ cout << " Because of" << endl;
+ if (! special_reason_names.empty())
+ cout << " * " << c::bold_yellow() << join(special_reason_names.begin(),
+ special_reason_names.end(), c::normal() + "\n " + c::bold_yellow())
+ << c::normal() << endl;
+
+ if (! reason_names.empty())
+ cout << " * " << join(reason_names.begin(), reason_names.end(), "\n ")
+ << endl;
+ }
+ else
+ {
+ cout << " Because of ";
+
+ if (! special_reason_names.empty())
+ cout << c::bold_yellow() << join(special_reason_names.begin(), special_reason_names.end(), ", ")
+ << c::normal();
+
+ if (! reason_names.empty())
+ {
+ if (! special_reason_names.empty())
+ cout << ", ";
+
+ if (reason_names.size() > 4)
+ cout << join(reason_names.begin(), next(reason_names.begin(), 3), ", ")
+ << ", " << (reason_names.size() - 3) << " more";
+ else
+ cout << join(reason_names.begin(), reason_names.end(), ", ");
+ }
+
+ cout << endl;
+ }
+
+ if ((! resolution->decision()->is_best()) && resolution->decision()->kind() == dk_installable)
+ cout << c::bold_red() << " Which prevented selection of the best candidate" << c::normal() << endl;
+ }
+ }
+
void display_resolution(
const std::tr1::shared_ptr<Environment> &,
const ResolutionLists & lists,
@@ -129,6 +204,13 @@ namespace
{
Context context("When displaying chosen resolution:");
+ if (lists.ordered()->empty())
+ {
+ if (lists.errors()->empty())
+ cout << "There are no actions to carry out" << endl << endl;
+ return;
+ }
+
cout << "These are the actions I will take, in order:" << endl << endl;
for (Resolutions::ConstIterator c(lists.ordered()->begin()), c_end(lists.ordered()->end()) ;
@@ -323,48 +405,37 @@ namespace
if (id->short_description_key())
cout << " \"" << id->short_description_key()->value() << "\"" << endl;
- std::set<std::string> reason_names, special_reason_names;
- for (Constraints::ConstIterator r((*c)->constraints()->begin()),
- r_end((*c)->constraints()->end()) ;
- r != r_end ; ++r)
- {
- ReasonNameGetter g;
- std::pair<std::string, bool> s((*r)->reason()->accept_returning<std::pair<std::string, bool> >(g));
- if (! s.first.empty())
- {
- if (s.second)
- special_reason_names.insert(s.first);
- else
- reason_names.insert(s.first);
- }
- }
+ display_reasons(*c, false);
+ }
- if ((! special_reason_names.empty()) || (! reason_names.empty()))
- {
- cout << " Because of ";
+ cout << endl;
+ }
- if (! special_reason_names.empty())
- cout << c::bold_yellow() << join(special_reason_names.begin(), special_reason_names.end(), ", ")
- << c::normal();
+ void display_errors(
+ const std::tr1::shared_ptr<Environment> &,
+ const ResolutionLists & lists,
+ const DisplayResolutionCommandLine &)
+ {
+ Context context("When displaying errors for chosen resolution:");
- if (! reason_names.empty())
- {
- if (! special_reason_names.empty())
- cout << ", ";
+ if (lists.errors()->empty())
+ return;
- if (reason_names.size() > 4)
- cout << join(reason_names.begin(), next(reason_names.begin(), 3), ", ")
- << ", " << (reason_names.size() - 3) << " more";
- else
- cout << join(reason_names.begin(), reason_names.end(), ", ");
- }
+ cout << "I encountered the following errors:" << endl << endl;
+
+ for (Resolutions::ConstIterator c(lists.errors()->begin()), c_end(lists.errors()->end()) ;
+ c != c_end ; ++c)
+ {
+ if ((*c)->decision()->kind() != dk_unable_to_decide)
+ continue;
- if ((! (*c)->decision()->is_best()) && (! (*c)->decision()->is_nothing())
- && (! (*c)->decision()->is_installed()))
- cout << c::bold_red() << " which prevented selection of the best candidate" << c::normal();
+ if ((*c)->qpn_s().slot_name_or_null())
+ cout << "[?] " << c::bold_red() << (*c)->qpn_s() << c::normal();
+ else
+ cout << "[?] " << c::bold_red() << (*c)->qpn_s().package() << c::normal();
+ cout << " (no decision could be reached)" << endl;
- cout << endl;
- }
+ display_reasons(*c, true);
}
cout << endl;
@@ -519,6 +590,7 @@ DisplayResolutionCommand::run(
ResolutionLists lists(ResolutionLists::deserialise(deserialisation));
display_resolution(env, lists, cmdline);
+ display_errors(env, lists, cmdline);
display_explanations(env, lists, cmdline);
return 0;
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index c0e0fd0..36ace86 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -466,7 +466,7 @@ namespace
if (is_suggestion(dep))
return false;
- if (resolution->decision()->is_installed())
+ if (dk_installed == resolution->decision()->kind())
{
if (! cmdline.resolution_options.a_follow_installed_build_dependencies.specified())
if (is_just_build_dep(dep))
@@ -670,6 +670,10 @@ ResolveCommand::run(
dump_if_requested(env, resolver, cmdline);
retcode |= display_resolution(env, *resolver->resolution_lists(), cmdline);
+
+ if (! resolver->resolution_lists()->errors()->empty())
+ retcode |= 1;
+
if (0 == retcode)
perform_resolution(env, *resolver->resolution_lists(), cmdline);
}
diff --git a/src/clients/cave/cmd_resolve_dump.cc b/src/clients/cave/cmd_resolve_dump.cc
index f01fe03..e2c814d 100644
--- a/src/clients/cave/cmd_resolve_dump.cc
+++ b/src/clients/cave/cmd_resolve_dump.cc
@@ -47,6 +47,8 @@ namespace
ss << "Decision(";
+ ss << d.kind() << " ";
+
if (d.if_package_id())
ss << *d.if_package_id();
else
@@ -54,10 +56,6 @@ namespace
if (d.is_best())
ss << ", is best";
- if (d.is_installed())
- ss << ", is installed";
- if (d.is_nothing())
- ss << ", is nothing";
if (d.is_same())
ss << ", is same";
if (d.is_same_version())