aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2012-07-27 20:02:26 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2012-07-27 21:28:11 +0100
commit426a01ee4256e2c8fc9135a43a156846a6d593cc (patch)
tree6891265629214a4822008c12151252682bf799c0
parentccbd7c2b7cfb276c26dc3b0174f0ffaedee25529 (diff)
downloadpaludis-426a01ee4256e2c8fc9135a43a156846a6d593cc.tar.gz
paludis-426a01ee4256e2c8fc9135a43a156846a6d593cc.tar.xz
cave resolve --prefer-matching / --avoid-matching
-rw-r--r--paludis/resolver/decider.cc2
-rw-r--r--paludis/resolver/prefer_or_avoid_helper.cc55
-rw-r--r--paludis/resolver/prefer_or_avoid_helper.hh7
-rw-r--r--paludis/resolver/resolver_functions.hh2
-rw-r--r--src/clients/cave/resolve_cmdline.cc4
-rw-r--r--src/clients/cave/resolve_cmdline.hh2
-rw-r--r--src/clients/cave/resolve_common.cc12
7 files changed, 73 insertions, 11 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index edaed70..63e58e5 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -1235,7 +1235,7 @@ Decider::find_any_score(
/* explicit preferences come first */
if (spec.package_ptr())
{
- Tribool prefer_or_avoid(_imp->fns.prefer_or_avoid_fn()(*spec.package_ptr()));
+ Tribool prefer_or_avoid(_imp->fns.prefer_or_avoid_fn()(spec));
if (prefer_or_avoid.is_true())
return std::make_pair(is_block ? acs_avoid : acs_prefer, operator_bias);
else if (prefer_or_avoid.is_false())
diff --git a/paludis/resolver/prefer_or_avoid_helper.cc b/paludis/resolver/prefer_or_avoid_helper.cc
index 95fc31b..1cfa1d9 100644
--- a/paludis/resolver/prefer_or_avoid_helper.cc
+++ b/paludis/resolver/prefer_or_avoid_helper.cc
@@ -21,8 +21,13 @@
#include <paludis/util/pimp-impl.hh>
#include <paludis/util/hashes.hh>
#include <paludis/util/tribool.hh>
+#include <paludis/util/make_null_shared_ptr.hh>
+#include <paludis/util/options.hh>
#include <paludis/name.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/match_package.hh>
#include <unordered_set>
+#include <list>
using namespace paludis;
using namespace paludis::resolver;
@@ -35,6 +40,8 @@ namespace paludis
const Environment * const env;
std::unordered_set<QualifiedPackageName, Hash<QualifiedPackageName> > prefer_names;
std::unordered_set<QualifiedPackageName, Hash<QualifiedPackageName> > avoid_names;
+ std::list<std::shared_ptr<const PackageIDSequence> > prefer_matching;
+ std::list<std::shared_ptr<const PackageIDSequence> > avoid_matching;
Imp(const Environment * const e) :
env(e)
@@ -62,14 +69,52 @@ PreferOrAvoidHelper::add_avoid_name(const QualifiedPackageName & name)
_imp->avoid_names.insert(name);
}
+void
+PreferOrAvoidHelper::add_prefer_matching(const std::shared_ptr<const PackageIDSequence> & s)
+{
+ _imp->prefer_matching.push_back(s);
+}
+
+void
+PreferOrAvoidHelper::add_avoid_matching(const std::shared_ptr<const PackageIDSequence> & s)
+{
+ _imp->avoid_matching.push_back(s);
+}
+
Tribool
-PreferOrAvoidHelper::operator() (const QualifiedPackageName & n) const
+PreferOrAvoidHelper::operator() (const PackageDepSpec & s) const
{
- if (_imp->prefer_names.end() != _imp->prefer_names.find(n))
- return true;
+ if (s.package_ptr())
+ {
+ if (_imp->prefer_names.end() != _imp->prefer_names.find(*s.package_ptr()))
+ return true;
- if (_imp->avoid_names.end() != _imp->avoid_names.find(n))
- return false;
+ if (_imp->avoid_names.end() != _imp->avoid_names.find(*s.package_ptr()))
+ return false;
+ }
+
+ for (auto p(_imp->prefer_matching.begin()), p_end(_imp->prefer_matching.end()) ;
+ p != p_end ; ++p)
+ {
+ bool all(true);
+ for (auto q((*p)->begin()), q_end((*p)->end()) ; q != q_end ; ++q)
+ if (! match_package(*_imp->env, s, *q, make_null_shared_ptr(), { }))
+ {
+ all = false;
+ break;
+ }
+
+ if (all)
+ return true;
+ }
+
+ for (auto p(_imp->avoid_matching.begin()), p_end(_imp->avoid_matching.end()) ;
+ p != p_end ; ++p)
+ {
+ for (auto q((*p)->begin()), q_end((*p)->end()) ; q != q_end ; ++q)
+ if (match_package(*_imp->env, s, *q, make_null_shared_ptr(), { }))
+ return false;
+ }
return indeterminate;
}
diff --git a/paludis/resolver/prefer_or_avoid_helper.hh b/paludis/resolver/prefer_or_avoid_helper.hh
index d2e2bb6..7d1c6ea 100644
--- a/paludis/resolver/prefer_or_avoid_helper.hh
+++ b/paludis/resolver/prefer_or_avoid_helper.hh
@@ -27,6 +27,8 @@
#include <paludis/util/tribool-fwd.hh>
#include <paludis/name-fwd.hh>
#include <paludis/environment-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
#include <memory>
namespace paludis
@@ -45,7 +47,10 @@ namespace paludis
void add_prefer_name(const QualifiedPackageName &);
void add_avoid_name(const QualifiedPackageName &);
- Tribool operator() (const QualifiedPackageName &) const;
+ void add_prefer_matching(const std::shared_ptr<const PackageIDSequence> &);
+ void add_avoid_matching(const std::shared_ptr<const PackageIDSequence> &);
+
+ Tribool operator() (const PackageDepSpec &) const;
};
}
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index cbe8b0a..ebdeda4 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -182,7 +182,7 @@ namespace paludis
)> OrderEarlyFunction;
typedef std::function<Tribool (
- const QualifiedPackageName &
+ const PackageDepSpec &
)> PreferOrAvoidFunction;
typedef std::function<std::shared_ptr<const PackageIDSequence> (
diff --git a/src/clients/cave/resolve_cmdline.cc b/src/clients/cave/resolve_cmdline.cc
index 3e5c939..5ad7fb3 100644
--- a/src/clients/cave/resolve_cmdline.cc
+++ b/src/clients/cave/resolve_cmdline.cc
@@ -231,8 +231,12 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
g_package_options(this, "Package Selection Options", "Control which packages are selected."),
a_favour(&g_package_options, "favour", 'F', "If there is a choice (e.g. || ( ) dependencies), favour the "
"specified package names"),
+ a_favour_matching(&g_package_options, "favour-matching", '\0', "If there is a choice (e.g. || ( ) dependencies), favour specs "
+ "which match all of the packages matching the supplied spec"),
a_avoid(&g_package_options, "avoid", 'A', "If there is a choice (e.g. || ( ) dependencies), avoid the "
"specified package names"),
+ a_avoid_matching(&g_package_options, "avoid-matching", '\0', "If there is a choice (e.g. || ( ) dependencies), avoid specs "
+ "which match any of the packages matching the supplied spec"),
a_preset(&g_package_options, "preset", 'p', "Preset a given constraint. For example, --preset =cat/pkg-2.1 will tell "
"the resolver to use that particular version. Note that this may lead to errors, if the specified version "
"does not satisfy other constraints. Also note that specifying a preset will not force a package to be "
diff --git a/src/clients/cave/resolve_cmdline.hh b/src/clients/cave/resolve_cmdline.hh
index 8bdd0b4..ed78765 100644
--- a/src/clients/cave/resolve_cmdline.hh
+++ b/src/clients/cave/resolve_cmdline.hh
@@ -85,7 +85,9 @@ namespace paludis
args::ArgsGroup g_package_options;
args::StringSetArg a_favour;
+ args::StringSetArg a_favour_matching;
args::StringSetArg a_avoid;
+ args::StringSetArg a_avoid_matching;
args::StringSetArg a_preset;
args::StringSetArg a_hide;
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index 3ddbddb..00e4c1c 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -964,10 +964,16 @@ paludis::cave::resolve_common(
i_end(resolution_options.a_favour.end_args()) ;
i != i_end ; ++i)
prefer_or_avoid_helper.add_prefer_name(disambiguate_if_necessary(env.get(), *i));
- for (args::StringSetArg::ConstIterator i(resolution_options.a_avoid.begin_args()),
- i_end(resolution_options.a_avoid.end_args()) ;
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_favour_matching.begin_args()),
+ i_end(resolution_options.a_favour_matching.end_args()) ;
i != i_end ; ++i)
- prefer_or_avoid_helper.add_avoid_name(disambiguate_if_necessary(env.get(), *i));
+ prefer_or_avoid_helper.add_prefer_matching((*env)[selection::AllVersionsUnsorted(generator::Matches(
+ parse_spec_with_nice_error(*i, env.get(), { }, filter::All()), make_null_shared_ptr(), { }))]);
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_avoid_matching.begin_args()),
+ i_end(resolution_options.a_avoid_matching.end_args()) ;
+ i != i_end ; ++i)
+ prefer_or_avoid_helper.add_avoid_matching((*env)[selection::AllVersionsUnsorted(generator::Matches(
+ parse_spec_with_nice_error(*i, env.get(), { }, filter::All()), make_null_shared_ptr(), { }))]);
RemoveIfDependentHelper remove_if_dependent_helper(env.get());
for (args::StringSetArg::ConstIterator i(resolution_options.a_remove_if_dependent.begin_args()),