aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-02-09 13:41:37 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-02-09 13:41:37 +0000
commit06b80abf1b5faa7483cafff872e1731fb53b589e (patch)
tree7d6441865fce3091d90dc4dddf859ba59906525b
parentb35180cf066887cf11e3b45e740b8af37bbdcb13 (diff)
downloadpaludis-06b80abf1b5faa7483cafff872e1731fb53b589e.tar.gz
paludis-06b80abf1b5faa7483cafff872e1731fb53b589e.tar.xz
Allow prefer/avoid || ( ) names
-rw-r--r--paludis/resolver/any_child_score.se2
-rw-r--r--paludis/resolver/decider.cc10
-rw-r--r--paludis/resolver/resolver_TEST_any.cc72
-rwxr-xr-xpaludis/resolver/resolver_TEST_any_setup.sh34
-rw-r--r--paludis/resolver/resolver_functions.hh7
-rw-r--r--paludis/resolver/resolver_test.cc17
-rw-r--r--paludis/resolver/resolver_test.hh5
-rw-r--r--src/clients/cave/resolve_common.cc10
8 files changed, 155 insertions, 2 deletions
diff --git a/paludis/resolver/any_child_score.se b/paludis/resolver/any_child_score.se
index dba5ba4..3936338 100644
--- a/paludis/resolver/any_child_score.se
+++ b/paludis/resolver/any_child_score.se
@@ -8,11 +8,13 @@ make_enum_AnyChildScore()
key acs_worse_than_worst "Worse than the worst option"
key acs_hate_hate_hate "Doesn't even exist"
+ key acs_avoid "Explicitly avoiding"
key acs_exists "Exists"
key acs_could_install "Could install"
key acs_will_be_installing "Will be installing"
key acs_wrong_options_installed "Already installed, wrong options"
key acs_already_installed "Already installed"
+ key acs_prefer "Explicitly preferred"
want_destringify
}
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index fd31250..295e814 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -887,6 +887,16 @@ Decider::find_any_score(const Resolvent & our_resolvent, const SanitisedDependen
operator_bias = os_greater_or_none;
}
+ /* explicit preferences come first */
+ if (spec.package_ptr())
+ {
+ Tribool prefer_or_avoid(_imp->fns.prefer_or_avoid_fn()(*spec.package_ptr()));
+ if (prefer_or_avoid.is_true())
+ return std::make_pair(acs_prefer, operator_bias);
+ else if (prefer_or_avoid.is_false())
+ return std::make_pair(acs_avoid, operator_bias);
+ }
+
/* best: already installed */
{
const std::tr1::shared_ptr<const PackageIDSequence> installed_ids((*_imp->env)[selection::BestVersionOnly(
diff --git a/paludis/resolver/resolver_TEST_any.cc b/paludis/resolver/resolver_TEST_any.cc
index 18c8c28..77c81b2 100644
--- a/paludis/resolver/resolver_TEST_any.cc
+++ b/paludis/resolver/resolver_TEST_any.cc
@@ -33,7 +33,7 @@
#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/map-impl.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
#include <paludis/user_dep_spec.hh>
@@ -168,5 +168,75 @@ namespace test_cases
}
}
} test_empty_alternative_with_untaken_upgrade;
+
+ struct TestEmptyPreferences : ResolverAnyTestCase
+ {
+ const Tribool a, b;
+
+ TestEmptyPreferences(const Tribool aa, const Tribool bb) :
+ ResolverAnyTestCase("empty preferences " + stringify(aa) + " " + stringify(bb)),
+ a(aa),
+ b(bb)
+ {
+ if (! a.is_indeterminate())
+ prefer_or_avoid_names->insert(QualifiedPackageName("preferences/dep-a"), a.is_true());
+ if (! b.is_indeterminate())
+ prefer_or_avoid_names->insert(QualifiedPackageName("preferences/dep-b"), b.is_true());
+ }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("preferences/target"));
+
+ {
+ TestMessageSuffix s("taken errors");
+ check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
+ .finished()
+ );
+ }
+
+ {
+ TestMessageSuffix s("untaken errors");
+ check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
+ .finished()
+ );
+ }
+
+
+ {
+ if (a.is_true())
+ {
+ TestMessageSuffix s("ordered");
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
+ .qpn(QualifiedPackageName("preferences/dep-a"))
+ .qpn(QualifiedPackageName("preferences/target"))
+ .finished()
+ );
+ }
+ else if (b.is_true())
+ {
+ TestMessageSuffix s("ordered");
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
+ .qpn(QualifiedPackageName("preferences/dep-b"))
+ .qpn(QualifiedPackageName("preferences/target"))
+ .finished()
+ );
+ }
+ else if (a.is_false())
+ {
+ TestMessageSuffix s("ordered");
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
+ .qpn(QualifiedPackageName("preferences/dep-middle"))
+ .qpn(QualifiedPackageName("preferences/target"))
+ .finished()
+ );
+ }
+ }
+ }
+ } test_empty_preferences_tt(true, true),
+ test_empty_preferences_ti(true, indeterminate), test_empty_preferences_tf(true, false),
+ test_empty_preferences_it(indeterminate, true), test_empty_preferences_ii(indeterminate, indeterminate),
+ test_empty_preferences_if(indeterminate, false), test_empty_preferences_ft(false, true),
+ test_empty_preferences_fi(false, indeterminate), test_empty_preferences_ff(false, false);
}
diff --git a/paludis/resolver/resolver_TEST_any_setup.sh b/paludis/resolver/resolver_TEST_any_setup.sh
index 9100d13..d27a14b 100755
--- a/paludis/resolver/resolver_TEST_any_setup.sh
+++ b/paludis/resolver/resolver_TEST_any_setup.sh
@@ -34,5 +34,39 @@ PLATFORMS="test"
SLOT="0"
END
+# preferences
+echo 'preferences' >> metadata/categories.conf
+
+mkdir -p 'packages/preferences/target'
+cat <<END > packages/preferences/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ || ( preferences/dep-a preferences/dep-middle preferences/dep-b )
+ "
+END
+
+mkdir -p 'packages/preferences/dep-a'
+cat <<END > packages/preferences/dep-a/dep-a-1.exheres-0
+SUMMARY="dep"
+PLATFORMS="test"
+SLOT="0"
+END
+
+mkdir -p 'packages/preferences/dep-middle'
+cat <<END > packages/preferences/dep-middle/dep-middle-1.exheres-0
+SUMMARY="dep"
+PLATFORMS="test"
+SLOT="0"
+END
+
+mkdir -p 'packages/preferences/dep-b'
+cat <<END > packages/preferences/dep-b/dep-b-1.exheres-0
+SUMMARY="dep"
+PLATFORMS="test"
+SLOT="0"
+END
+
cd ..
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index 834cacc..780feb7 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -30,6 +30,7 @@
#include <paludis/resolver/destination_types-fwd.hh>
#include <paludis/resolver/constraint-fwd.hh>
#include <paludis/util/named_value.hh>
+#include <paludis/util/tribool-fwd.hh>
#include <paludis/filter-fwd.hh>
#include <paludis/name-fwd.hh>
#include <tr1/functional>
@@ -46,6 +47,7 @@ namespace paludis
struct get_resolvents_for_fn;
struct get_use_existing_fn;
struct make_destination_filtered_generator_fn;
+ struct prefer_or_avoid_fn;
struct take_dependency_fn;
}
@@ -94,6 +96,10 @@ namespace paludis
const Resolvent &
)> MakeDestinationFilteredGeneratorFunction;
+ typedef std::tr1::function<Tribool (
+ const QualifiedPackageName &
+ )> PreferOrAvoidFunction;
+
typedef std::tr1::function<bool (
const Resolvent &,
const SanitisedDependency &,
@@ -111,6 +117,7 @@ namespace paludis
NamedValue<n::get_use_existing_fn, GetUseExistingFunction> get_use_existing_fn;
NamedValue<n::make_destination_filtered_generator_fn,
MakeDestinationFilteredGeneratorFunction> make_destination_filtered_generator_fn;
+ NamedValue<n::prefer_or_avoid_fn, PreferOrAvoidFunction> prefer_or_avoid_fn;
NamedValue<n::take_dependency_fn, TakeDependencyFunction> take_dependency_fn;
};
}
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index f11dce8..18e7f8c 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -253,10 +253,23 @@ paludis::resolver::resolver_test::allowed_to_remove_fn(
return s->end() != s->find(i->name());
}
+Tribool
+paludis::resolver::resolver_test::prefer_or_avoid_fn(
+ const std::tr1::shared_ptr<const Map<QualifiedPackageName, bool> > & s,
+ const QualifiedPackageName & q)
+{
+ const Map<QualifiedPackageName, bool>::ConstIterator r(s->find(q));
+ if (s->end() != r)
+ return Tribool(r->second);
+ else
+ return indeterminate;
+}
+
ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s, const std::string & e,
const std::string & l) :
TestCase(s),
- allowed_to_remove_names(new QualifiedPackageNameSet)
+ allowed_to_remove_names(new QualifiedPackageNameSet),
+ prefer_or_avoid_names(new Map<QualifiedPackageName, bool>)
{
std::tr1::shared_ptr<Map<std::string, std::string> > keys(new Map<std::string, std::string>);
keys->insert("format", "exheres");
@@ -315,6 +328,8 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
value_for<n::get_resolvents_for_fn>(&get_resolvents_for_fn),
value_for<n::get_use_existing_fn>(&get_use_existing_fn),
value_for<n::make_destination_filtered_generator_fn>(&make_destination_filtered_generator_fn),
+ value_for<n::prefer_or_avoid_fn>(std::tr1::bind(&prefer_or_avoid_fn,
+ prefer_or_avoid_names, std::tr1::placeholders::_1)),
value_for<n::take_dependency_fn>(&take_dependency_fn)
);
}
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index 52161f4..99b1fd2 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -94,12 +94,17 @@ namespace paludis
const std::tr1::shared_ptr<const QualifiedPackageNameSet> &,
const std::tr1::shared_ptr<const PackageID> &);
+ Tribool prefer_or_avoid_fn(
+ const std::tr1::shared_ptr<const Map<QualifiedPackageName, bool> > &,
+ const QualifiedPackageName &);
+
struct ResolverTestCase : test::TestCase
{
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_remove_names;
+ std::tr1::shared_ptr<Map<QualifiedPackageName, bool> > prefer_or_avoid_names;
ResolverTestCase(const std::string & group, const std::string & test_name, const std::string & eapi,
const std::string & layout);
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index db973e9..34a5079 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -951,6 +951,13 @@ namespace
return false;
}
+ Tribool prefer_or_avoid_fn(
+ const ResolveCommandLineResolutionOptions &,
+ const QualifiedPackageName &)
+ {
+ return indeterminate;
+ }
+
void ser_thread_func(StringListStream & ser_stream, const ResolverLists & resolution_lists)
{
Serialiser ser(ser_stream);
@@ -1242,6 +1249,9 @@ paludis::cave::resolve_common(
std::tr1::cref(resolution_options), std::tr1::placeholders::_1, std::tr1::placeholders::_2, std::tr1::placeholders::_3)),
value_for<n::make_destination_filtered_generator_fn>(std::tr1::bind(&make_destination_filtered_generator,
env.get(), std::tr1::cref(resolution_options), std::tr1::placeholders::_1, std::tr1::placeholders::_2)),
+ value_for<n::prefer_or_avoid_fn>(std::tr1::bind(&prefer_or_avoid_fn,
+ std::tr1::cref(resolution_options),
+ std::tr1::placeholders::_1)),
value_for<n::take_dependency_fn>(std::tr1::bind(&take_dependency_fn, env.get(),
std::tr1::cref(resolution_options), std::tr1::placeholders::_1, std::tr1::placeholders::_2, std::tr1::placeholders::_3))