aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-08-04 14:13:29 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-08-04 14:13:29 +0100
commitdc07a4ad8233149f651e6e7530f18780269eb469 (patch)
treecf2987945764267c9e98716f79e7ec105c257581
parent664af4f02614b2e89b5cb91178ee8bdb7881ba6f (diff)
downloadpaludis-dc07a4ad8233149f651e6e7530f18780269eb469.tar.gz
paludis-dc07a4ad8233149f651e6e7530f18780269eb469.tar.xz
explain, dump
-rw-r--r--paludis/resolver/resolver.cc32
-rw-r--r--paludis/resolver/resolver.hh7
-rw-r--r--src/clients/cave/cmd_resolve.cc143
3 files changed, 148 insertions, 34 deletions
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index 5076faf..1362363 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -942,30 +942,16 @@ Resolver::end() const
return ConstIterator(_imp->ordered_resolutions.end());
}
-void
-Resolver::dump(std::ostream & s, const bool show_deps) const
+Resolver::ResolutionsByQPN_SConstIterator
+Resolver::begin_resolutions_by_qpn_s() const
{
- s << "Resolutions by QPN:S:" << std::endl;
- for (ResolutionsByQPN_SMap::const_iterator i(_imp->resolutions_by_qpn_s.begin()),
- i_end(_imp->resolutions_by_qpn_s.end()) ;
- i != i_end ; ++i)
- {
- s << " [*] " << std::left << std::setw(30) << i->first << " " << *i->second << std::endl;
- if (show_deps)
- for (SanitisedDependencies::ConstIterator d(i->second->sanitised_dependencies()->begin()),
- d_end(i->second->sanitised_dependencies()->end()) ;
- d != d_end ; ++d)
- s << " -> " << *d << std::endl;
- }
-
- s << std::endl;
+ return ResolutionsByQPN_SConstIterator(_imp->resolutions_by_qpn_s.begin());
+}
- s << "Ordered Resolutions:" << std::endl;
- for (OrderedResolutionsList::const_iterator i(_imp->ordered_resolutions.begin()),
- i_end(_imp->ordered_resolutions.end()) ;
- i != i_end ; ++i)
- s << " [*] " << **i << std::endl;
- s << std::endl;
+Resolver::ResolutionsByQPN_SConstIterator
+Resolver::end_resolutions_by_qpn_s() const
+{
+ return ResolutionsByQPN_SConstIterator(_imp->resolutions_by_qpn_s.end());
}
int
@@ -1136,4 +1122,6 @@ Resolver::_find_cycle(const QPN_S & start_qpn_s, const int ignorable_pass) const
}
template class WrappedForwardIterator<Resolver::ConstIteratorTag, const std::tr1::shared_ptr<const Resolution> >;
+template class WrappedForwardIterator<Resolver::ResolutionsByQPN_SConstIteratorTag,
+ const std::pair<const QPN_S, std::tr1::shared_ptr<Resolution> > >;
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index f353ae5..ff722e4 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -160,7 +160,6 @@ namespace paludis
void add_target(const SetName &);
void resolve();
- void dump(std::ostream &, const bool deps) const;
struct ConstIteratorTag;
typedef WrappedForwardIterator<ConstIteratorTag,
@@ -168,6 +167,12 @@ namespace paludis
ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ struct ResolutionsByQPN_SConstIteratorTag;
+ typedef WrappedForwardIterator<ResolutionsByQPN_SConstIteratorTag,
+ const std::pair<const QPN_S, std::tr1::shared_ptr<Resolution> > > ResolutionsByQPN_SConstIterator;
+ ResolutionsByQPN_SConstIterator begin_resolutions_by_qpn_s() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ResolutionsByQPN_SConstIterator end_resolutions_by_qpn_s() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
int find_any_score(const QPN_S &, const SanitisedDependency &) const;
};
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index a2b15c6..aa121d3 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -36,6 +36,7 @@
#include <paludis/resolver/qpn_s.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
+#include <paludis/resolver/destinations.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/generator.hh>
@@ -45,6 +46,7 @@
#include <paludis/version_spec.hh>
#include <paludis/metadata_key.hh>
#include <paludis/environment.hh>
+#include <paludis/match_package.hh>
#include <algorithm>
#include <iostream>
@@ -107,8 +109,8 @@ namespace
// args::EnumArg a_show_option_descriptions;
// args::EnumArg a_show_descriptions;
-// args::ArgsGroup g_explanations;
-// args::StringSetArg a_explain;
+ args::ArgsGroup g_explanations;
+ args::StringSetArg a_explain;
// args::ArgsGroup g_phase_options;
// args::StringSetArg a_skip_phase;
@@ -220,13 +222,13 @@ namespace
// ("all", "Show for all packages"),
// "new"
// ),
-//
-// g_explanations(this, "Explanations", "Options requesting the resolver explain a particular decision "
-// "that it made"),
-// a_explain(&g_explanations, "explain", '\0', "Explain why the resolver made a particular decision. The "
-// "argument is a package dependency specification, so --explain dev-libs/boost or --explain qt:3"
-// " or even --explain '*/*' (although --dump is a better way of getting highly noisy debug output)."),
-//
+
+ g_explanations(this, "Explanations", "Options requesting the resolver explain a particular decision "
+ "that it made"),
+ a_explain(&g_explanations, "explain", '\0', "Explain why the resolver made a particular decision. The "
+ "argument is a package dependency specification, so --explain dev-libs/boost or --explain qt:3"
+ " or even --explain '*/*' (although --dump is a better way of getting highly noisy debug output)."),
+
// g_phase_options(this, "Phase Options", "Options controlling which phases to execute. No sanity checking "
// "is done, allowing you to shoot as many feet off as you desire. Phase names do not have the "
// "src_, pkg_ or builtin_ prefix, so 'init', 'preinst', 'unpack', 'merge', 'strip' etc."),
@@ -478,6 +480,107 @@ namespace
std::cout << std::endl;
}
+ struct ReasonDisplayer
+ {
+ void visit(const TargetReason &)
+ {
+ std::cout << "it is a target";
+ }
+
+ void visit(const DependencyReason & reason)
+ {
+ std::cout << "of dependency " << reason.sanitised_dependency() << " from " << reason.qpn_s();
+ }
+
+ void visit(const PresetReason &)
+ {
+ std::cout << "of a preset";
+ }
+
+ void visit(const SetReason & reason)
+ {
+ std::cout << "of set " << reason.set_name() << ", which is because ";
+ reason.reason_for_set()->accept(*this);
+ }
+ };
+
+ void display_explanations(
+ const std::tr1::shared_ptr<Environment> & env,
+ const std::tr1::shared_ptr<Resolver> & resolver,
+ const ResolveCommandLine & cmdline)
+ {
+ Context context("When displaying explanations:");
+
+ if (cmdline.a_explain.begin_args() == cmdline.a_explain.end_args())
+ return;
+
+ std::cout << "Explaining requested decisions:" << std::endl << std::endl;
+
+ for (args::StringSetArg::ConstIterator i(cmdline.a_explain.begin_args()), i_end(cmdline.a_explain.end_args()) ;
+ i != i_end ; ++i)
+ {
+ PackageDepSpec spec(parse_user_package_dep_spec(*i, env.get(), UserPackageDepSpecOptions() + updso_allow_wildcards));
+ for (Resolver::ResolutionsByQPN_SConstIterator r(resolver->begin_resolutions_by_qpn_s()),
+ r_end(resolver->end_resolutions_by_qpn_s()) ;
+ r != r_end ; ++r)
+ {
+ if (! match_package(*env, spec, *r->second->decision()->package_id(), MatchPackageOptions()))
+ continue;
+
+ std::cout << "For " << r->first << ":" << std::endl;
+ std::cout << " The following constraints were in action:" << std::endl;
+ for (Constraints::ConstIterator c(r->second->constraints()->begin()),
+ c_end(r->second->constraints()->end()) ;
+ c != c_end ; ++c)
+ {
+ std::cout << " * " << (*c)->spec();
+ switch ((*c)->use_installed())
+ {
+ case ui_if_same:
+ std::cout << ", use installed if same";
+ break;
+ case ui_never:
+ std::cout << ", never using installed";
+ break;
+ case ui_only_if_transient:
+ std::cout << ", using installed only if transient";
+ break;
+ case ui_if_same_version:
+ std::cout << ", use installed if same version";
+ break;
+ case ui_if_possible:
+ std::cout << ", use installed if possible";
+ break;
+
+ case last_ui:
+ break;
+ }
+
+ if ((*c)->to_destination_slash())
+ std::cout << ", installing to /";
+
+ std::cout << std::endl;
+ std::cout << " because ";
+ ReasonDisplayer v;
+ (*c)->reason()->accept(v);
+ std::cout << std::endl;
+ }
+ std::cout << " The decision made was:" << std::endl;
+ std::cout << " Use " << *r->second->decision()->package_id() << std::endl;
+ if (r->second->destinations()->slash())
+ {
+ std::cout << " Install to / using repository " << r->second->destinations()->slash()->repository() << std::endl;
+ if (! r->second->destinations()->slash()->replacing()->empty())
+ for (PackageIDSequence::ConstIterator x(r->second->destinations()->slash()->replacing()->begin()),
+ x_end(r->second->destinations()->slash()->replacing()->end()) ;
+ x != x_end ; ++x)
+ std::cout << " Replacing " << **x << std::endl;
+ }
+ std::cout << std::endl;
+ }
+ }
+ }
+
void dump_if_requested(
const std::tr1::shared_ptr<Environment> &,
const std::tr1::shared_ptr<Resolver> & resolver,
@@ -485,8 +588,25 @@ namespace
{
Context context("When dumping the resolver:");
- if (cmdline.a_dump.specified())
- resolver->dump(std::cerr, cmdline.a_dump_dependencies.specified());
+ if (! cmdline.a_dump.specified())
+ return;
+
+ std::cout << "Dumping resolutions by QPN:S:" << std::endl << std::endl;
+
+ for (Resolver::ResolutionsByQPN_SConstIterator c(resolver->begin_resolutions_by_qpn_s()),
+ c_end(resolver->end_resolutions_by_qpn_s()) ;
+ c != c_end ; ++c)
+ {
+ std::cout << c->first << std::endl;
+ std::cout << " = " << *c->second << std::endl;
+ if (cmdline.a_dump_dependencies.specified())
+ for (SanitisedDependencies::ConstIterator d(c->second->sanitised_dependencies()->begin()),
+ d_end(c->second->sanitised_dependencies()->end()) ;
+ d != d_end ; ++d)
+ std::cout << " -> " << *d << std::endl;
+ }
+
+ std::cout << std::endl;
}
UseInstalled use_installed_from_cmdline(const args::EnumArg & a, const bool is_set)
@@ -1004,6 +1124,7 @@ ResolveCommand::run(
}
display_resolution(env, resolver, cmdline);
+ display_explanations(env, resolver, cmdline);
}
catch (...)
{