aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-08-03 22:41:58 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-08-03 22:41:58 +0100
commit71bb352aeebbb7c8acaa3bb909607492b4e8af61 (patch)
tree6c23c97e76fd0bbe140a64c37ae6c741525dca72
parentd093ad94c0f353c9f267413fd7dfb4ed8a8a991f (diff)
downloadpaludis-71bb352aeebbb7c8acaa3bb909607492b4e8af61.tar.gz
paludis-71bb352aeebbb7c8acaa3bb909607492b4e8af61.tar.xz
implement slot options
-rw-r--r--paludis/resolver/qpn_s.cc12
-rw-r--r--paludis/resolver/qpn_s.hh3
-rw-r--r--src/clients/cave/cmd_resolve.cc84
3 files changed, 88 insertions, 11 deletions
diff --git a/paludis/resolver/qpn_s.cc b/paludis/resolver/qpn_s.cc
index 2bb5820..3e49967 100644
--- a/paludis/resolver/qpn_s.cc
+++ b/paludis/resolver/qpn_s.cc
@@ -108,6 +108,18 @@ QPN_S::operator< (const QPN_S & other) const
}
}
+bool
+QPN_S::operator== (const QPN_S & other) const
+{
+ if (! (package() == other.package()))
+ return false;
+
+ if (slot_name_or_null())
+ return other.slot_name_or_null() && *slot_name_or_null() == *other.slot_name_or_null();
+ else
+ return ! other.slot_name_or_null();
+}
+
std::ostream &
paludis::resolver::operator<< (std::ostream & s, const QPN_S & q)
{
diff --git a/paludis/resolver/qpn_s.hh b/paludis/resolver/qpn_s.hh
index cf7a21a..35af8dd 100644
--- a/paludis/resolver/qpn_s.hh
+++ b/paludis/resolver/qpn_s.hh
@@ -46,7 +46,7 @@ namespace paludis
public:
QPN_S(const QualifiedPackageName &, const std::tr1::shared_ptr<const SlotName> &);
QPN_S(const PackageDepSpec &, const std::tr1::shared_ptr<const SlotName> &);
- QPN_S(const std::tr1::shared_ptr<const PackageID> &);
+ explicit QPN_S(const std::tr1::shared_ptr<const PackageID> &);
QPN_S(const QPN_S &);
~QPN_S();
@@ -56,6 +56,7 @@ namespace paludis
Filter make_slot_filter() const PALUDIS_ATTRIBUTE((warn_unused_result));
bool operator< (const QPN_S & other) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool operator== (const QPN_S & other) const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index 794f3a3..5af8008 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -45,6 +45,7 @@
#include <paludis/metadata_key.hh>
#include <paludis/environment.hh>
+#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <map>
@@ -660,6 +661,35 @@ namespace
return i->second;
}
+ struct IsTargetVisitor
+ {
+ bool visit(const DependencyReason &) const
+ {
+ return false;
+ }
+
+ bool visit(const PresetReason &) const
+ {
+ return false;
+ }
+
+ bool visit(const TargetReason &) const
+ {
+ return true;
+ }
+
+ bool visit(const SetReason & r) const
+ {
+ return r.reason_for_set()->accept_returning<bool>(*this);
+ }
+ };
+
+ bool is_target(const std::tr1::shared_ptr<const Reason> & reason)
+ {
+ IsTargetVisitor v;
+ return reason->accept_returning<bool>(v);
+ }
+
struct SlotNameFinder
{
std::tr1::shared_ptr<SlotName> visit(const SlotExactRequirement & s)
@@ -679,8 +709,10 @@ namespace
};
const std::tr1::shared_ptr<QPN_S_Sequence>
- get_qpn_s_s_for_fn(const Environment * const env, const ResolveCommandLine &, const PackageDepSpec & spec,
- const std::tr1::shared_ptr<const Reason> &)
+ get_qpn_s_s_for_fn(const Environment * const env,
+ const ResolveCommandLine & cmdline,
+ const PackageDepSpec & spec,
+ const std::tr1::shared_ptr<const Reason> & reason)
{
std::tr1::shared_ptr<QPN_S_Sequence> result(new QPN_S_Sequence);
@@ -696,22 +728,54 @@ namespace
result->push_back(QPN_S(spec, exact_slot));
else
{
+ std::tr1::shared_ptr<QPN_S> best;
+ std::list<QPN_S> installed;
+
const std::tr1::shared_ptr<const PackageIDSequence> ids((*env)[selection::BestVersionOnly(
generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
filter::SupportsAction<InstallAction>() |
filter::NotMasked())]);
if (! ids->empty())
- result->push_back(QPN_S(*ids->begin()));
- else
- {
- const std::tr1::shared_ptr<const PackageIDSequence> installed_ids((*env)[selection::BestVersionOnly(
- generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
- filter::SupportsAction<InstalledAction>())]);
+ best = make_shared_ptr(new QPN_S(*ids->begin()));
+
+ const std::tr1::shared_ptr<const PackageIDSequence> installed_ids((*env)[selection::BestVersionInEachSlot(
+ generator::Matches(spec, MatchPackageOptions() + mpo_ignore_additional_requirements) |
+ filter::SupportsAction<InstalledAction>())]);
- if (! installed_ids->empty())
- result->push_back(QPN_S(*installed_ids->begin()));
+ for (PackageIDSequence::ConstIterator i(installed_ids->begin()), i_end(installed_ids->end()) ;
+ i != i_end ; ++i)
+ installed.push_back(QPN_S(*i));
+
+ const args::EnumArg & arg(is_target(reason) ? cmdline.a_target_slots : cmdline.a_slots);
+
+ if (! best)
+ std::copy(installed.begin(), installed.end(), result->back_inserter());
+ else if (arg.argument() == "best-or-installed")
+ {
+ if (installed.end() == std::find(installed.begin(), installed.end(), *best))
+ result->push_back(*best);
+ else
+ std::copy(installed.begin(), installed.end(), result->back_inserter());
+ }
+ else if (arg.argument() == "installed-or-best")
+ {
+ if (installed.empty())
+ result->push_back(*best);
+ else
+ std::copy(installed.begin(), installed.end(), result->back_inserter());
+ }
+ else if (arg.argument() == "all")
+ {
+ if (installed.end() == std::find(installed.begin(), installed.end(), *best))
+ result->push_back(*best);
+ std::copy(installed.begin(), installed.end(), result->back_inserter());
}
+ else if (arg.argument() == "best")
+ result->push_back(*best);
+ else
+ throw args::DoHelp("Don't understand argument '" + arg.argument() + "' to '--"
+ + arg.long_name() + "'");
}
return result;