aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-09-05 16:12:26 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-09-05 16:12:26 +0100
commit91a77a7156f6a730097393abae5a43b11f8a7e5a (patch)
tree1626f58a5b58981b1c425dd7a2f720f0b6962f04
parentfcf224a626d967528bba7d4cbabec46a03814000 (diff)
parent95e7880705435bee4833c0bd1b8694f023038e48 (diff)
downloadpaludis-91a77a7156f6a730097393abae5a43b11f8a7e5a.tar.gz
paludis-91a77a7156f6a730097393abae5a43b11f8a7e5a.tar.xz
Merge branch 'blocker-annotations'
-rw-r--r--paludis/dep_spec-fwd.hh3
-rw-r--r--paludis/dep_spec.cc20
-rw-r--r--paludis/dep_spec.hh19
-rw-r--r--paludis/dep_spec.se27
-rw-r--r--paludis/dep_spec_TEST.cc2
-rw-r--r--paludis/files.m42
-rw-r--r--paludis/repositories/e/dep_parser.cc100
-rw-r--r--paludis/repositories/e/eapi.cc19
-rw-r--r--paludis/repositories/e/eapi.hh10
-rw-r--r--paludis/repositories/e/eapis/exheres-0.conf5
-rw-r--r--paludis/repositories/fake/dep_parser.cc2
-rw-r--r--paludis/resolver/constraint.cc13
-rw-r--r--paludis/resolver/constraint.hh3
-rw-r--r--paludis/resolver/decider.cc53
-rw-r--r--paludis/resolver/decider.hh2
-rw-r--r--paludis/resolver/get_constraints_for_dependent_helper.cc3
-rw-r--r--paludis/resolver/get_constraints_for_purge_helper.cc3
-rw-r--r--paludis/resolver/get_constraints_for_via_binary_helper.cc1
-rw-r--r--paludis/resolver/get_initial_constraints_for_helper.cc2
-rw-r--r--paludis/resolver/orderer.cc18
-rw-r--r--paludis/resolver/package_or_block_dep_spec.cc6
-rw-r--r--paludis/resolver/resolver_TEST_blockers.cc129
-rwxr-xr-xpaludis/resolver/resolver_TEST_blockers_setup.sh84
-rw-r--r--paludis/resolver/resolver_TEST_continue_on_failure.cc2
-rw-r--r--paludis/resolver/resolver_TEST_purges.cc2
-rw-r--r--paludis/resolver/resolver_TEST_uninstalls.cc2
-rw-r--r--paludis/resolver/spec_rewriter.cc2
-rw-r--r--paludis/stringify_formatter_TEST.cc3
-rw-r--r--python/dep_spec.cc23
-rw-r--r--python/dep_spec.hh6
-rwxr-xr-xpython/dep_spec_TEST.py2
-rw-r--r--ruby/dep_spec.cc21
-rw-r--r--ruby/dep_spec_TEST.rb8
-rw-r--r--src/clients/cave/resolve_common.cc2
34 files changed, 516 insertions, 83 deletions
diff --git a/paludis/dep_spec-fwd.hh b/paludis/dep_spec-fwd.hh
index 4bc9409..fb96841 100644
--- a/paludis/dep_spec-fwd.hh
+++ b/paludis/dep_spec-fwd.hh
@@ -32,6 +32,9 @@
namespace paludis
{
+
+#include <paludis/dep_spec-se.hh>
+
class DepSpec;
class PackageDepSpec;
class PlainTextDepSpec;
diff --git a/paludis/dep_spec.cc b/paludis/dep_spec.cc
index 4221d46..6a5f716 100644
--- a/paludis/dep_spec.cc
+++ b/paludis/dep_spec.cc
@@ -45,6 +45,8 @@
using namespace paludis;
+#include <paludis/dep_spec-se.cc>
+
namespace paludis
{
template <>
@@ -252,17 +254,17 @@ NamedSetDepSpec::need_keys_added() const
{
}
-BlockDepSpec::BlockDepSpec(const std::string & s, const PackageDepSpec & p, const bool t) :
+BlockDepSpec::BlockDepSpec(const std::string & s, const PackageDepSpec & p, const BlockKind k) :
StringDepSpec(s),
_spec(p),
- _strong(t)
+ _kind(k)
{
}
BlockDepSpec::BlockDepSpec(const BlockDepSpec & other) :
StringDepSpec(other.text()),
_spec(other._spec),
- _strong(other._strong)
+ _kind(other._kind)
{
}
@@ -450,10 +452,16 @@ BlockDepSpec::blocking() const
return _spec;
}
-bool
-BlockDepSpec::strong() const
+BlockKind
+BlockDepSpec::block_kind() const
+{
+ return _kind;
+}
+
+void
+BlockDepSpec::set_block_kind(const BlockKind k)
{
- return _strong;
+ _kind = k;
}
std::shared_ptr<DepSpec>
diff --git a/paludis/dep_spec.hh b/paludis/dep_spec.hh
index 98b485f..0b99291 100644
--- a/paludis/dep_spec.hh
+++ b/paludis/dep_spec.hh
@@ -595,7 +595,7 @@ namespace paludis
{
private:
PackageDepSpec _spec;
- bool _strong;
+ BlockKind _kind;
protected:
virtual void need_keys_added() const;
@@ -605,9 +605,9 @@ namespace paludis
///\{
/**
- * \since 0.41
+ * \since 0.55
*/
- BlockDepSpec(const std::string & text, const PackageDepSpec & spec, const bool strong);
+ BlockDepSpec(const std::string & text, const PackageDepSpec & spec, const BlockKind);
BlockDepSpec(const BlockDepSpec &);
@@ -621,11 +621,18 @@ namespace paludis
const PackageDepSpec blocking() const PALUDIS_ATTRIBUTE((warn_unused_result));
/**
- * Fetch whether we're a strong blocker.
+ * Fetch our blocker strength.
*
- * \since 0.41
+ * \since 0.55
+ */
+ BlockKind block_kind() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ /**
+ * Change our blocker strength.
+ *
+ * \since 0.55
*/
- bool strong() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void set_block_kind(const BlockKind);
virtual std::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
diff --git a/paludis/dep_spec.se b/paludis/dep_spec.se
new file mode 100644
index 0000000..3531f2b
--- /dev/null
+++ b/paludis/dep_spec.se
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_BlockKind()
+{
+ prefix bk
+
+ key bk_weak "Generic weak block"
+ key bk_strong "Generic strong block"
+ key bk_manual "A block requiring manual resolution"
+ key bk_upgrade_blocked_before "Strong, nothing is not fine if met"
+ key bk_uninstall_blocked_before "Strong, nothing is fine too"
+ key bk_uninstall_blocked_after "Weak, nothing is fine too"
+
+ want_destringify
+
+ doxygen_comment << "END"
+ /**
+ * Kind of a BlockDepSpec.
+ *
+ * \ingroup g_dep_spec
+ * \since 0.55
+ */
+END
+}
+
+
diff --git a/paludis/dep_spec_TEST.cc b/paludis/dep_spec_TEST.cc
index 7925b53..bf7e559 100644
--- a/paludis/dep_spec_TEST.cc
+++ b/paludis/dep_spec_TEST.cc
@@ -71,7 +71,7 @@ namespace test_cases
std::shared_ptr<PackageDepSpec> c(std::static_pointer_cast<PackageDepSpec>(a.clone()));
TEST_CHECK_STRINGIFY_EQUAL(a, *c);
- BlockDepSpec d("!" + stringify(*c), *c, false);
+ BlockDepSpec d("!" + stringify(*c), *c, bk_weak);
std::shared_ptr<BlockDepSpec> e(std::static_pointer_cast<BlockDepSpec>(d.clone()));
TEST_CHECK_STRINGIFY_EQUAL(d.blocking(), e->blocking());
}
diff --git a/paludis/files.m4 b/paludis/files.m4
index 6657ec7..b987297 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -25,7 +25,7 @@ add(`common_sets', `hh', `cc', `fwd')
add(`contents', `hh', `cc', `fwd')
add(`create_output_manager_info', `hh', `cc', `fwd', `se')
add(`dep_label', `hh', `cc', `fwd')
-add(`dep_spec', `hh', `cc', `test', `fwd')
+add(`dep_spec', `hh', `cc', `test', `fwd', `se')
add(`dep_spec_data', `hh', `cc', `fwd')
add(`dep_spec_flattener', `hh', `cc')
add(`dep_tag', `hh', `cc', `fwd')
diff --git a/paludis/repositories/e/dep_parser.cc b/paludis/repositories/e/dep_parser.cc
index 74192ce..fe4edf4 100644
--- a/paludis/repositories/e/dep_parser.cc
+++ b/paludis/repositories/e/dep_parser.cc
@@ -27,6 +27,8 @@
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/return_literal_function.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/make_null_shared_ptr.hh>
#include <paludis/elike_annotations.hh>
#include <paludis/elike_dep_parser.hh>
#include <paludis/elike_conditional_dep_spec.hh>
@@ -77,6 +79,30 @@ namespace
typedef std::function<void (const std::shared_ptr<DepSpec> &)> AnnotationsGoHere;
};
+ template <>
+ struct ParseStackTypes<DependencySpecTree>
+ {
+ struct Item
+ {
+ NamedValue<n::item, std::shared_ptr<DependencySpecTree::BasicInnerNode> > item;
+ NamedValue<n::spec, std::shared_ptr<DepSpec> > spec;
+ };
+
+ typedef std::list<Item> Stack;
+ typedef std::function<void (const std::shared_ptr<DepSpec> &, const std::shared_ptr<BlockDepSpec> &)> AnnotationsGoHere;
+ };
+
+ template <typename T_>
+ void call_annotations_go_here(const T_ & f, const std::shared_ptr<DepSpec> & spec)
+ {
+ f(spec);
+ }
+
+ void call_annotations_go_here(const ParseStackTypes<DependencySpecTree>::AnnotationsGoHere & f, const std::shared_ptr<DepSpec> & spec)
+ {
+ f(spec, make_null_shared_ptr());
+ }
+
template <typename T_>
void package_dep_spec_string_handler(
const typename ParseStackTypes<T_>::Stack & h,
@@ -89,7 +115,7 @@ namespace
parse_elike_package_dep_spec(s, eapi.supported()->package_dep_spec_parse_options(),
eapi.supported()->version_spec_options(), id)));
h.begin()->item()->append(spec);
- annotations_go_here(spec);
+ call_annotations_go_here(annotations_go_here, spec);
}
template <typename T_>
@@ -123,9 +149,9 @@ namespace
eapi.supported()->package_dep_spec_parse_options(),
eapi.supported()->version_spec_options(),
id),
- strong));
+ strong ? bk_strong : bk_weak));
h.begin()->item()->append(spec);
- annotations_go_here(spec);
+ annotations_go_here(spec, spec);
}
else
package_dep_spec_string_handler<T_>(h, annotations_go_here, s, eapi, id);
@@ -221,7 +247,7 @@ namespace
{
std::shared_ptr<DependenciesLabelsDepSpec> spec(parse_dependency_label(id, s, eapi));
h.begin()->item()->append(spec);
- annotations_go_here(spec);
+ annotations_go_here(spec, make_null_shared_ptr());
}
template <typename T_>
@@ -280,7 +306,7 @@ namespace
const typename ParseStackTypes<T_>::AnnotationsGoHere & annotations_go_here,
const std::string & s)
{
- annotations_go_here(stack.begin()->spec());
+ call_annotations_go_here(annotations_go_here, stack.begin()->spec());
stack.pop_front();
if (stack.empty())
throw EDepParseError(s, "Too many ')'s");
@@ -303,16 +329,62 @@ namespace
{
}
- void set_annotations(std::shared_ptr<DepSpec> & spec, const std::shared_ptr<const Map<std::string, std::string> > & m)
+ void set_annotations(
+ std::shared_ptr<DepSpec> & spec,
+ const std::shared_ptr<const Map<std::string, std::string> > & m)
+ {
+ std::shared_ptr<ELikeAnnotations> key(std::make_shared<ELikeAnnotations>(m));
+ spec->set_annotations_key(key);
+ }
+
+ void set_annotations_block(
+ const EAPI & eapi,
+ std::shared_ptr<DepSpec> & spec,
+ std::shared_ptr<BlockDepSpec> & if_block_spec,
+ const std::shared_ptr<const Map<std::string, std::string> > & m)
{
std::shared_ptr<ELikeAnnotations> key(std::make_shared<ELikeAnnotations>(m));
spec->set_annotations_key(key);
+
+ if (if_block_spec && (! eapi.supported()->annotations()->blocker_resolution().empty())
+ && if_block_spec->annotations_key())
+ {
+ auto a(if_block_spec->annotations_key()->find_metadata(eapi.supported()->annotations()->blocker_resolution()));
+ if (a != if_block_spec->annotations_key()->end_metadata())
+ {
+ auto k(simple_visitor_cast<const MetadataValueKey<std::string> >(**a));
+ if (! k)
+ throw EDepParseError(stringify(*if_block_spec), "Annotation key for blocker resolution not a string");
+
+ if (k->value().empty())
+ {
+ }
+ else if (k->value() == eapi.supported()->annotations()->blocker_resolution_manual())
+ if_block_spec->set_block_kind(bk_manual);
+ else if (k->value() == eapi.supported()->annotations()->blocker_resolution_uninstall_blocked_after())
+ if_block_spec->set_block_kind(bk_uninstall_blocked_after);
+ else if (k->value() == eapi.supported()->annotations()->blocker_resolution_uninstall_blocked_before())
+ if_block_spec->set_block_kind(bk_uninstall_blocked_before);
+ else if (k->value() == eapi.supported()->annotations()->blocker_resolution_upgrade_blocked_before())
+ if_block_spec->set_block_kind(bk_upgrade_blocked_before);
+ else
+ throw EDepParseError(stringify(*if_block_spec), "Unknown value '" + k->value() + "' for annotation '" + k->raw_name() + "'");
+ }
+ }
}
void set_thing_to_annotate(std::shared_ptr<DepSpec> & spec, const std::shared_ptr<DepSpec> & s)
{
spec = s;
}
+
+ void set_thing_to_annotate_maybe_block(
+ std::shared_ptr<DepSpec> & spec, const std::shared_ptr<DepSpec> & s,
+ std::shared_ptr<BlockDepSpec> & block, const std::shared_ptr<BlockDepSpec> & b)
+ {
+ spec = s;
+ block = b;
+ }
}
std::shared_ptr<DependencySpecTree>
@@ -324,6 +396,7 @@ paludis::erepository::parse_depend(const std::string & s,
ParseStackTypes<DependencySpecTree>::Stack stack;
std::shared_ptr<AllDepSpec> spec(std::make_shared<AllDepSpec>());
std::shared_ptr<DepSpec> thing_to_annotate(spec);
+ std::shared_ptr<BlockDepSpec> thing_to_annotate_if_block;
std::shared_ptr<DependencySpecTree> top(std::make_shared<DependencySpecTree>(spec));
stack.push_front(make_named_values<ParseStackTypes<DependencySpecTree>::Item>(
n::item() = top->top(),
@@ -333,22 +406,23 @@ paludis::erepository::parse_depend(const std::string & s,
ELikeDepParserCallbacks callbacks(
make_named_values<ELikeDepParserCallbacks>(
n::on_all() = std::bind(&any_all_handler<DependencySpecTree, AllDepSpec>, std::ref(stack)),
- n::on_annotations() = std::bind(&set_annotations, std::ref(thing_to_annotate), _1),
+ n::on_annotations() = std::bind(&set_annotations_block, std::cref(eapi), std::ref(thing_to_annotate),
+ std::ref(thing_to_annotate_if_block), _1),
n::on_any() = std::bind(&any_all_handler<DependencySpecTree, AnyDepSpec>, std::ref(stack)),
n::on_arrow() = std::bind(&arrows_not_allowed_handler, s, _1, _2),
n::on_error() = std::bind(&error_handler, s, _1),
n::on_label() = std::bind(&dependency_label_handler<DependencySpecTree>,
std::ref(stack),
ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
- &set_thing_to_annotate, std::ref(thing_to_annotate), _1)),
+ &set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)),
id, _1, std::cref(eapi)),
n::on_pop() = std::bind(&pop_handler<DependencySpecTree>, std::ref(stack),
ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
- &set_thing_to_annotate, std::ref(thing_to_annotate), _1)), s),
+ &set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<DependencySpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&package_or_block_dep_spec_string_handler<DependencySpecTree>, std::ref(stack),
ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
- &set_thing_to_annotate, std::ref(thing_to_annotate), _1)), _1, eapi, id),
+ &set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)), _1, eapi, id),
n::on_use() = std::bind(&use_handler<DependencySpecTree>, std::ref(stack), _1, env, id, std::cref(eapi)),
n::on_use_under_any() = std::bind(&use_under_any_handler, s, std::cref(eapi))
));
@@ -386,7 +460,7 @@ paludis::erepository::parse_provide(const std::string & s,
&set_thing_to_annotate, std::ref(thing_to_annotate), _1)), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<ProvideSpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&package_dep_spec_string_handler<ProvideSpecTree>, std::ref(stack),
- ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
+ ParseStackTypes<ProvideSpecTree>::AnnotationsGoHere(std::bind(
&set_thing_to_annotate, std::ref(thing_to_annotate), _1)), _1, std::cref(eapi), id),
n::on_use() = std::bind(&use_handler<ProvideSpecTree>, std::ref(stack), _1, env, id, std::cref(eapi)),
n::on_use_under_any() = std::bind(&use_under_any_handler, s, std::cref(eapi))
@@ -464,7 +538,7 @@ paludis::erepository::parse_simple_uri(const std::string & s,
n::on_error() = std::bind(&error_handler, s, _1),
n::on_label() = std::bind(&labels_not_allowed_handler, s, _1),
n::on_pop() = std::bind(&pop_handler<SimpleURISpecTree>, std::ref(stack),
- ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
+ ParseStackTypes<SimpleURISpecTree>::AnnotationsGoHere(std::bind(
&set_thing_to_annotate, std::ref(thing_to_annotate), _1)), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<SimpleURISpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&simple_uri_handler<SimpleURISpecTree>, std::ref(stack),
@@ -503,7 +577,7 @@ paludis::erepository::parse_license(const std::string & s,
n::on_error() = std::bind(&error_handler, s, _1),
n::on_label() = std::bind(&labels_not_allowed_handler, s, _1),
n::on_pop() = std::bind(&pop_handler<LicenseSpecTree>, std::ref(stack),
- ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
+ ParseStackTypes<LicenseSpecTree>::AnnotationsGoHere(std::bind(
&set_thing_to_annotate, std::ref(thing_to_annotate), _1)), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<LicenseSpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&license_handler<LicenseSpecTree>, std::ref(stack),
diff --git a/paludis/repositories/e/eapi.cc b/paludis/repositories/e/eapi.cc
index d739416..7aa2beb 100644
--- a/paludis/repositories/e/eapi.cc
+++ b/paludis/repositories/e/eapi.cc
@@ -243,13 +243,18 @@ namespace
std::shared_ptr<const EAPIAnnotations> make_annotations(const KeyValueConfigFile & k)
{
return std::make_shared<EAPIAnnotations>(make_named_values<EAPIAnnotations>(
- n::myoptions_description() = k.get("annotations_myoptions_description"),
- n::myoptions_number_selected() = k.get("annotations_myoptions_number_selected"),
- n::myoptions_number_selected_at_least_one() = k.get("annotations_myoptions_number_selected_at_least_one"),
- n::myoptions_number_selected_at_most_one() = k.get("annotations_myoptions_number_selected_at_most_one"),
- n::myoptions_number_selected_exactly_one() = k.get("annotations_myoptions_number_selected_exactly_one"),
- n::myoptions_requires() = k.get("annotations_myoptions_requires")
- ));
+ n::blocker_resolution() = k.get("annotations_blocker_resolution"),
+ n::blocker_resolution_manual() = k.get("annotations_blocker_resolution_manual"),
+ n::blocker_resolution_uninstall_blocked_after() = k.get("annotations_blocker_resolution_uninstall_blocked_after"),
+ n::blocker_resolution_uninstall_blocked_before() = k.get("annotations_blocker_resolution_uninstall_blocked_before"),
+ n::blocker_resolution_upgrade_blocked_before() = k.get("annotations_blocker_resolution_upgrade_blocked_before"),
+ n::myoptions_description() = k.get("annotations_myoptions_description"),
+ n::myoptions_number_selected() = k.get("annotations_myoptions_number_selected"),
+ n::myoptions_number_selected_at_least_one() = k.get("annotations_myoptions_number_selected_at_least_one"),
+ n::myoptions_number_selected_at_most_one() = k.get("annotations_myoptions_number_selected_at_most_one"),
+ n::myoptions_number_selected_exactly_one() = k.get("annotations_myoptions_number_selected_exactly_one"),
+ n::myoptions_requires() = k.get("annotations_myoptions_requires")
+ ));
}
std::shared_ptr<const EAPIChoicesOptions> make_choices_options(const KeyValueConfigFile & k)
diff --git a/paludis/repositories/e/eapi.hh b/paludis/repositories/e/eapi.hh
index f14e9ad..6faa046 100644
--- a/paludis/repositories/e/eapi.hh
+++ b/paludis/repositories/e/eapi.hh
@@ -39,6 +39,11 @@ namespace paludis
{
typedef Name<struct annotations_name> annotations;
typedef Name<struct binary_from_env_variables_name> binary_from_env_variables;
+ typedef Name<struct blocker_resolution_name> blocker_resolution;
+ typedef Name<struct blocker_resolution_manual_name> blocker_resolution_manual;
+ typedef Name<struct blocker_resolution_uninstall_blocked_after_name> blocker_resolution_uninstall_blocked_after;
+ typedef Name<struct blocker_resolution_uninstall_blocked_before_name> blocker_resolution_uninstall_blocked_before;
+ typedef Name<struct blocker_resolution_upgrade_blocked_before_name> blocker_resolution_upgrade_blocked_before;
typedef Name<struct bracket_merged_variables_name> bracket_merged_variables;
typedef Name<struct bracket_merged_variables_annotatable_name> bracket_merged_variables_annotatable;
typedef Name<struct bracket_merged_variables_annotation_name> bracket_merged_variables_annotation;
@@ -448,6 +453,11 @@ namespace paludis
struct EAPIAnnotations
{
+ NamedValue<n::blocker_resolution, std::string> blocker_resolution;
+ NamedValue<n::blocker_resolution_manual, std::string> blocker_resolution_manual;
+ NamedValue<n::blocker_resolution_uninstall_blocked_after, std::string> blocker_resolution_uninstall_blocked_after;
+ NamedValue<n::blocker_resolution_uninstall_blocked_before, std::string> blocker_resolution_uninstall_blocked_before;
+ NamedValue<n::blocker_resolution_upgrade_blocked_before, std::string> blocker_resolution_upgrade_blocked_before;
NamedValue<n::myoptions_description, std::string> myoptions_description;
NamedValue<n::myoptions_number_selected, std::string> myoptions_number_selected;
NamedValue<n::myoptions_number_selected_at_least_one, std::string> myoptions_number_selected_at_least_one;
diff --git a/paludis/repositories/e/eapis/exheres-0.conf b/paludis/repositories/e/eapis/exheres-0.conf
index 96e8e24..ca74e63 100644
--- a/paludis/repositories/e/eapis/exheres-0.conf
+++ b/paludis/repositories/e/eapis/exheres-0.conf
@@ -349,6 +349,11 @@ shell_options = extglob globstar
unpack_suffixes = tar tar.gz,tgz,tar.Z tar.bz2,tbz2,tbz zip,ZIP,jar gz,Z,z bz2 rar,RAR lha,LHa,LHA,lzh a,deb tar.lzma lzma 7z,7Z tar.xz xz
+annotations_blocker_resolution = resolution
+annotations_blocker_resolution_manual = manual
+annotations_blocker_resolution_uninstall_blocked_after = uninstall-blocked-after
+annotations_blocker_resolution_uninstall_blocked_before = uninstall-blocked-before
+annotations_blocker_resolution_upgrade_blocked_before = upgrade-blocked-before
annotations_myoptions_description = description
annotations_myoptions_requires = requires
annotations_myoptions_number_selected = number-selected
diff --git a/paludis/repositories/fake/dep_parser.cc b/paludis/repositories/fake/dep_parser.cc
index 3941a5d..b627b1c 100644
--- a/paludis/repositories/fake/dep_parser.cc
+++ b/paludis/repositories/fake/dep_parser.cc
@@ -73,7 +73,7 @@ namespace
+ epdso_allow_use_deps + epdso_allow_ranged_deps + epdso_allow_tilde_greater_deps
+ epdso_strict_parsing,
user_version_spec_options(),
- id), false));
+ id), bk_weak));
}
else
package_dep_spec_string_handler<T_>(h, s, id);
diff --git a/paludis/resolver/constraint.cc b/paludis/resolver/constraint.cc
index c9a35e9..f23e187 100644
--- a/paludis/resolver/constraint.cc
+++ b/paludis/resolver/constraint.cc
@@ -41,13 +41,15 @@ namespace paludis
UseExisting strictest_use_existing;
bool nothing_is_fine_too;
bool all_untaken;
+ bool any_force_unable;
Sequence<std::shared_ptr<const Constraint> > constraints;
Imp() :
strictest_use_existing(static_cast<UseExisting>(last_ue - 1)),
nothing_is_fine_too(true),
- all_untaken(true)
+ all_untaken(true),
+ any_force_unable(false)
{
}
};
@@ -75,6 +77,12 @@ Constraints::all_untaken() const
}
bool
+Constraints::any_force_unable() const
+{
+ return _imp->any_force_unable;
+}
+
+bool
Constraints::nothing_is_fine_too() const
{
return _imp->nothing_is_fine_too;
@@ -105,6 +113,7 @@ Constraints::add(const std::shared_ptr<const Constraint> & c)
_imp->strictest_use_existing = std::min(_imp->strictest_use_existing, c->use_existing());
_imp->nothing_is_fine_too = _imp->nothing_is_fine_too && c->nothing_is_fine_too();
_imp->all_untaken = _imp->all_untaken && c->untaken();
+ _imp->any_force_unable = _imp->any_force_unable || c->force_unable();
}
bool
@@ -137,6 +146,7 @@ Constraint::serialise(Serialiser & s) const
{
s.object("Constraint")
.member(SerialiserFlags<>(), "destination_type", stringify(destination_type()))
+ .member(SerialiserFlags<>(), "force_unable", stringify(force_unable()))
.member(SerialiserFlags<>(), "nothing_is_fine_too", nothing_is_fine_too())
.member(SerialiserFlags<serialise::might_be_null>(), "reason", reason())
.member(SerialiserFlags<>(), "spec", spec())
@@ -203,6 +213,7 @@ Constraint::deserialise(Deserialisation & d)
return std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = destringify<DestinationType>(v.member<std::string>("destination_type")),
+ n::force_unable() = v.member<bool>("force_unable"),
n::nothing_is_fine_too() = v.member<bool>("nothing_is_fine_too"),
n::reason() = reason,
n::spec() = PackageOrBlockDepSpec::deserialise(*v.find_remove_member("spec"),
diff --git a/paludis/resolver/constraint.hh b/paludis/resolver/constraint.hh
index e1d4fa8..e7a97e4 100644
--- a/paludis/resolver/constraint.hh
+++ b/paludis/resolver/constraint.hh
@@ -36,6 +36,7 @@ namespace paludis
namespace n
{
typedef Name<struct destination_type_name> destination_type;
+ typedef Name<struct force_unable_name> force_unable;
typedef Name<struct nothing_is_fine_too_name> nothing_is_fine_too;
typedef Name<struct reason_name> reason;
typedef Name<struct spec_name> spec;
@@ -48,6 +49,7 @@ namespace paludis
struct Constraint
{
NamedValue<n::destination_type, DestinationType> destination_type;
+ NamedValue<n::force_unable, bool> force_unable;
NamedValue<n::nothing_is_fine_too, bool> nothing_is_fine_too;
NamedValue<n::reason, std::shared_ptr<const Reason> > reason;
NamedValue<n::spec, PackageOrBlockDepSpec> spec;
@@ -69,6 +71,7 @@ namespace paludis
bool nothing_is_fine_too() const PALUDIS_ATTRIBUTE((warn_unused_result));
bool all_untaken() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool any_force_unable() const PALUDIS_ATTRIBUTE((warn_unused_result));
UseExisting strictest_use_existing() const PALUDIS_ATTRIBUTE((warn_unused_result));
void add(const std::shared_ptr<const Constraint> &);
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index 7c083c3..d68c3a9 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -610,6 +610,7 @@ Decider::_make_constraints_from_target(
const std::shared_ptr<ConstraintSequence> result(std::make_shared<ConstraintSequence>());
result->push_back(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = resolution->resolvent().destination_type(),
+ n::force_unable() = false,
n::nothing_is_fine_too() = existing.second,
n::reason() = reason,
n::spec() = spec,
@@ -638,6 +639,7 @@ Decider::_make_constraints_from_dependency(
const std::shared_ptr<ConstraintSequence> result(std::make_shared<ConstraintSequence>());
result->push_back(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = resolution->resolvent().destination_type(),
+ n::force_unable() = false,
n::nothing_is_fine_too() = existing.second,
n::reason() = reason,
n::spec() = *dep.spec().if_package(),
@@ -660,12 +662,34 @@ Decider::_make_constraints_from_blocker(
{
const std::shared_ptr<ConstraintSequence> result(std::make_shared<ConstraintSequence>());
+ bool nothing_is_fine_too(true), force_unable(false);
+ switch (spec.block_kind())
+ {
+ case bk_weak:
+ case bk_strong:
+ case bk_uninstall_blocked_before:
+ case bk_uninstall_blocked_after:
+ break;
+
+ case bk_manual:
+ force_unable = true;
+ break;
+
+ case bk_upgrade_blocked_before:
+ nothing_is_fine_too = ! _already_met(spec);
+ break;
+
+ case last_bk:
+ break;
+ }
+
DestinationTypes destination_types(_get_destination_types_for_blocker(spec, reason));
for (EnumIterator<DestinationType> t, t_end(last_dt) ; t != t_end ; ++t)
if (destination_types[*t])
result->push_back(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = *t,
- n::nothing_is_fine_too() = true,
+ n::force_unable() = force_unable,
+ n::nothing_is_fine_too() = nothing_is_fine_too,
n::reason() = reason,
n::spec() = spec,
n::untaken() = false,
@@ -707,6 +731,9 @@ namespace
bool ok(const std::shared_ptr<const PackageID> & chosen_id,
const std::shared_ptr<const ChangedChoices> & changed_choices) const
{
+ if (constraint.force_unable())
+ return false;
+
if (constraint.spec().if_package())
{
if (! match_package_with_maybe_changes(*env, *constraint.spec().if_package(),
@@ -745,6 +772,9 @@ namespace
bool visit(const RemoveDecision &) const
{
+ if (constraint.force_unable())
+ return false;
+
return constraint.nothing_is_fine_too();
}
@@ -1033,7 +1063,7 @@ Decider::_make_constraint_for_preloading(
result->spec().if_block() = std::make_shared<BlockDepSpec>(
"!" + stringify(s),
s,
- result->spec().if_block()->strong());
+ result->spec().if_block()->block_kind());
}
return result;
@@ -1179,7 +1209,7 @@ Decider::_add_dependencies_if_necessary(
}
const std::shared_ptr<DependencyReason> reason(std::make_shared<DependencyReason>(
- package_id, changed_choices, our_resolution->resolvent(), *s, _already_met(*s)));
+ package_id, changed_choices, our_resolution->resolvent(), *s, _already_met(s->spec())));
std::shared_ptr<const Resolvents> resolvents;
@@ -1340,7 +1370,7 @@ Decider::find_any_score(
}
const std::shared_ptr<DependencyReason> reason(std::make_shared<DependencyReason>(
- our_id, make_null_shared_ptr(), our_resolution->resolvent(), dep, _already_met(dep)));
+ our_id, make_null_shared_ptr(), our_resolution->resolvent(), dep, _already_met(dep.spec())));
const std::shared_ptr<const Resolvents> resolvents(_get_resolvents_for(spec, reason));
/* next: will already be installing */
@@ -1511,6 +1541,9 @@ Decider::_try_to_find_decision_for(
const bool try_masked_this_time,
const bool try_removes_if_allowed) const
{
+ if (resolution->constraints()->any_force_unable())
+ return make_null_shared_ptr();
+
const std::shared_ptr<const PackageID> existing_id(_find_existing_id_for(resolution));
std::shared_ptr<const PackageID> installable_id;
@@ -2086,19 +2119,16 @@ Decider::resolve()
}
bool
-Decider::_already_met(const SanitisedDependency & dep) const
+Decider::_already_met(const PackageOrBlockDepSpec & spec) const
{
const std::shared_ptr<const PackageIDSequence> installed_ids((*_imp->env)[selection::AllVersionsUnsorted(
- generator::Matches(dep.spec().if_package() ?
- *dep.spec().if_package() :
- dep.spec().if_block()->blocking(),
- { }) |
+ generator::Matches(spec.if_package() ? *spec.if_package() : spec.if_block()->blocking(), { }) |
filter::InstalledAtSlash())]);
if (installed_ids->empty())
- return bool(dep.spec().if_block());
+ return bool(spec.if_block());
else
{
- if (dep.spec().if_block())
+ if (spec.if_block())
return false;
if (installed_ids->end() == std::find_if(installed_ids->begin(), installed_ids->end(),
@@ -2361,6 +2391,7 @@ namespace
std::shared_ptr<ConstraintSequence> result(std::make_shared<ConstraintSequence>());
result->push_back(make_shared_copy(make_named_values<Constraint>(
n::destination_type() = destination_type,
+ n::force_unable() = false,
n::nothing_is_fine_too() = true,
n::reason() = std::make_shared<LikeOtherDestinationTypeReason>(
resolvent,
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index d98a706..e1ba60a 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -240,7 +240,7 @@ namespace paludis
const std::shared_ptr<const PackageID> &,
const bool existing) const;
- bool _already_met(const SanitisedDependency &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool _already_met(const PackageOrBlockDepSpec &) const PALUDIS_ATTRIBUTE((warn_unused_result));
bool _installed_but_allowed_to_remove(
const std::shared_ptr<const Resolution> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/resolver/get_constraints_for_dependent_helper.cc b/paludis/resolver/get_constraints_for_dependent_helper.cc
index 1309f62..d27f9a6 100644
--- a/paludis/resolver/get_constraints_for_dependent_helper.cc
+++ b/paludis/resolver/get_constraints_for_dependent_helper.cc
@@ -93,9 +93,10 @@ GetConstraintsForDependentHelper::operator() (
result->push_back(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = dt_install_to_slash,
+ n::force_unable() = false,
n::nothing_is_fine_too() = true,
n::reason() = reason,
- n::spec() = BlockDepSpec("!" + stringify(*spec), *spec, false),
+ n::spec() = BlockDepSpec("!" + stringify(*spec), *spec, bk_weak),
n::untaken() = false,
n::use_existing() = ue_if_possible
)));
diff --git a/paludis/resolver/get_constraints_for_purge_helper.cc b/paludis/resolver/get_constraints_for_purge_helper.cc
index 507290a..631a1e4 100644
--- a/paludis/resolver/get_constraints_for_purge_helper.cc
+++ b/paludis/resolver/get_constraints_for_purge_helper.cc
@@ -84,9 +84,10 @@ GetConstraintsForPurgeHelper::operator() (
result->push_back(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = dt_install_to_slash,
+ n::force_unable() = false,
n::nothing_is_fine_too() = true,
n::reason() = reason,
- n::spec() = BlockDepSpec("!" + stringify(spec), spec, false),
+ n::spec() = BlockDepSpec("!" + stringify(spec), spec, bk_weak),
n::untaken() = ! _imp->purge_specs.match_any(_imp->env, id, { }),
n::use_existing() = ue_if_possible
)));
diff --git a/paludis/resolver/get_constraints_for_via_binary_helper.cc b/paludis/resolver/get_constraints_for_via_binary_helper.cc
index 3f4cd7c..ee7ea91 100644
--- a/paludis/resolver/get_constraints_for_via_binary_helper.cc
+++ b/paludis/resolver/get_constraints_for_via_binary_helper.cc
@@ -70,6 +70,7 @@ GetConstraintsForViaBinaryHelper::operator() (
result->push_back(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = resolution->resolvent().destination_type(),
+ n::force_unable() = false,
n::nothing_is_fine_too() = false,
n::reason() = reason,
n::spec() = spec,
diff --git a/paludis/resolver/get_initial_constraints_for_helper.cc b/paludis/resolver/get_initial_constraints_for_helper.cc
index 3300976..a82a3ee 100644
--- a/paludis/resolver/get_initial_constraints_for_helper.cc
+++ b/paludis/resolver/get_initial_constraints_for_helper.cc
@@ -100,6 +100,7 @@ GetInitialConstraintsForHelper::add_preset_spec(const PackageDepSpec & spec)
const std::shared_ptr<Constraint> constraint(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = r.destination_type(),
+ n::force_unable() = false,
n::nothing_is_fine_too() = true,
n::reason() = reason,
n::spec() = spec,
@@ -252,6 +253,7 @@ GetInitialConstraintsForHelper::_make_initial_constraints_for(
{
result->add(std::make_shared<Constraint>(make_named_values<Constraint>(
n::destination_type() = resolvent.destination_type(),
+ n::force_unable() = false,
n::nothing_is_fine_too() = true,
n::reason() = std::make_shared<PresetReason>("is scm", make_null_shared_ptr()),
n::spec() = make_package_dep_spec({ }).package(resolvent.package()),
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index 5982901..ce75344 100644
--- a/paludis/resolver/orderer.cc
+++ b/paludis/resolver/orderer.cc
@@ -260,8 +260,22 @@ namespace
{
bool normal(true);
if (r.sanitised_dependency().spec().if_block())
- if (! r.sanitised_dependency().spec().if_block()->strong())
- normal = false;
+ switch (r.sanitised_dependency().spec().if_block()->block_kind())
+ {
+ case bk_weak:
+ case bk_uninstall_blocked_after:
+ normal = false;
+ break;
+
+ case bk_strong:
+ case bk_manual:
+ case bk_upgrade_blocked_before:
+ case bk_uninstall_blocked_before:
+ break;
+
+ case last_bk:
+ break;
+ }
NAGIndex from(make_named_values<NAGIndex>(
n::resolvent() = r.from_resolvent(),
diff --git a/paludis/resolver/package_or_block_dep_spec.cc b/paludis/resolver/package_or_block_dep_spec.cc
index cb96300..576ec57 100644
--- a/paludis/resolver/package_or_block_dep_spec.cc
+++ b/paludis/resolver/package_or_block_dep_spec.cc
@@ -66,7 +66,7 @@ PackageOrBlockDepSpec::serialise(Serialiser & s) const
w
.member(SerialiserFlags<>(), "block", true)
.member(SerialiserFlags<>(), "spec", stringify(if_block()->blocking()))
- .member(SerialiserFlags<>(), "strong", if_block()->strong())
+ .member(SerialiserFlags<>(), "block_kind", stringify(if_block()->block_kind()))
.member(SerialiserFlags<>(), "text", if_block()->text())
;
}
@@ -140,9 +140,9 @@ PackageOrBlockDepSpec::deserialise(Deserialisation & d, const std::shared_ptr<co
if (block)
{
- bool strong(v.member<bool>("strong"));
+ BlockKind kind(destringify<BlockKind>(v.member<std::string>("block_kind")));
std::string text(v.member<std::string>("text"));
- BlockDepSpec b_spec(text, spec, strong);
+ BlockDepSpec b_spec(text, spec, kind);
if (annotations)
b_spec.set_annotations_key(annotations);
return PackageOrBlockDepSpec(b_spec);
diff --git a/paludis/resolver/resolver_TEST_blockers.cc b/paludis/resolver/resolver_TEST_blockers.cc
index d6ea458..3033b7a 100644
--- a/paludis/resolver/resolver_TEST_blockers.cc
+++ b/paludis/resolver/resolver_TEST_blockers.cc
@@ -189,7 +189,7 @@ namespace test_cases
std::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
"!target/target",
parse_user_package_dep_spec("target/target", &env, { }),
- false)));
+ bk_weak)));
check_resolved(resolved,
n::taken_change_or_remove_decisions() = exists ? make_shared_copy(DecisionChecks()
@@ -415,5 +415,132 @@ namespace test_cases
test_self_block_x_1_w(-1, 1, false), test_self_block_x_1_s(-1, 1, true),
test_self_block_0_1_w( 0, 1, false), test_self_block_0_1_s( 0, 1, true),
test_self_block_1_1_w( 1, 1, false), test_self_block_1_1_s( 1, 1, true);
+
+ struct UninstallBlockedAfter : ResolverBlockersTestCase
+ {
+ UninstallBlockedAfter() :
+ ResolverBlockersTestCase("uninstall blocked after")
+ {
+ install("uninstall-blocked-after", "dep", "1");
+ allowed_to_remove_helper.add_allowed_to_remove_spec(parse_user_package_dep_spec("uninstall-blocked-after/dep", &env, { }));
+ }
+
+ void run()
+ {
+ std::shared_ptr<const Resolved> resolved(get_resolved("uninstall-blocked-after/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("uninstall-blocked-after/target"))
+ .remove(QualifiedPackageName("uninstall-blocked-after/dep"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unorderable_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_uninstall_blocked_after;
+
+ struct UninstallBlockedBefore : ResolverBlockersTestCase
+ {
+ UninstallBlockedBefore() :
+ ResolverBlockersTestCase("uninstall blocked before")
+ {
+ install("uninstall-blocked-before", "dep", "1");
+ allowed_to_remove_helper.add_allowed_to_remove_spec(parse_user_package_dep_spec("uninstall-blocked-before/dep", &env, { }));
+ }
+
+ void run()
+ {
+ std::shared_ptr<const Resolved> resolved(get_resolved("uninstall-blocked-before/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("uninstall-blocked-before/dep"))
+ .change(QualifiedPackageName("uninstall-blocked-before/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unorderable_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_uninstall_blocked_before;
+
+ struct UpgradeBlockedBefore : ResolverBlockersTestCase
+ {
+ UpgradeBlockedBefore() :
+ ResolverBlockersTestCase("upgrade blocked before")
+ {
+ install("upgrade-blocked-before", "dep", "1");
+ allowed_to_remove_helper.add_allowed_to_remove_spec(parse_user_package_dep_spec("upgrade-blocked-before/dep", &env, { }));
+ }
+
+ void run()
+ {
+ std::shared_ptr<const Resolved> resolved(get_resolved("upgrade-blocked-before/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("upgrade-blocked-before/dep"))
+ .change(QualifiedPackageName("upgrade-blocked-before/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unorderable_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_upgrade_blocked_before;
+
+ struct Manual : ResolverBlockersTestCase
+ {
+ Manual() :
+ ResolverBlockersTestCase("manual")
+ {
+ install("manual", "dep", "1");
+ }
+
+ void run()
+ {
+ std::shared_ptr<const Resolved> resolved(get_resolved("manual/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("manual/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .unable(QualifiedPackageName("manual/dep"))
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unorderable_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_manual;
}
diff --git a/paludis/resolver/resolver_TEST_blockers_setup.sh b/paludis/resolver/resolver_TEST_blockers_setup.sh
index 51813e4..1dd0f88 100755
--- a/paludis/resolver/resolver_TEST_blockers_setup.sh
+++ b/paludis/resolver/resolver_TEST_blockers_setup.sh
@@ -209,5 +209,89 @@ END
done
done
+# uninstall-blocked-after
+echo 'uninstall-blocked-after' >> metadata/categories.conf
+
+mkdir -p 'packages/uninstall-blocked-after/target'
+cat <<END > packages/uninstall-blocked-after/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ ( !uninstall-blocked-after/dep[=1] [[ resolution = uninstall-blocked-after ]] )
+ "
+END
+
+mkdir -p 'packages/upgrade-blocked-after/dep'
+cat <<END > packages/uninstall-blocked-after/dep/dep-2.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+# uninstall-blocked-before
+echo 'uninstall-blocked-before' >> metadata/categories.conf
+
+mkdir -p 'packages/uninstall-blocked-before/target'
+cat <<END > packages/uninstall-blocked-before/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ ( !uninstall-blocked-before/dep[=1] [[ resolution = uninstall-blocked-before ]] )
+ "
+END
+
+mkdir -p 'packages/upgrade-blocked-before/dep'
+cat <<END > packages/uninstall-blocked-before/dep/dep-2.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+# upgrade-blocked-before
+echo 'upgrade-blocked-before' >> metadata/categories.conf
+
+mkdir -p 'packages/upgrade-blocked-before/target'
+cat <<END > packages/upgrade-blocked-before/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ ( !upgrade-blocked-before/dep[=1] [[ resolution = upgrade-blocked-before ]] )
+ "
+END
+
+mkdir -p 'packages/upgrade-blocked-before/dep'
+cat <<END > packages/upgrade-blocked-before/dep/dep-2.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+# manual
+echo 'manual' >> metadata/categories.conf
+
+mkdir -p 'packages/manual/target'
+cat <<END > packages/manual/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ ( !manual/dep[=1] [[ resolution = manual ]] )
+ "
+END
+
+mkdir -p 'packages/manual/dep'
+cat <<END > packages/manual/dep/dep-2.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
cd ..
diff --git a/paludis/resolver/resolver_TEST_continue_on_failure.cc b/paludis/resolver/resolver_TEST_continue_on_failure.cc
index ab9e63f..29da328 100644
--- a/paludis/resolver/resolver_TEST_continue_on_failure.cc
+++ b/paludis/resolver/resolver_TEST_continue_on_failure.cc
@@ -169,7 +169,7 @@ namespace test_cases
std::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
"!continue-on-failure-uninstall/target",
parse_user_package_dep_spec("continue-on-failure-uninstall/target", &env, { }),
- false)));
+ bk_weak)));
check_resolved(resolved,
n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
diff --git a/paludis/resolver/resolver_TEST_purges.cc b/paludis/resolver/resolver_TEST_purges.cc
index be4a6fa..7068f5b 100644
--- a/paludis/resolver/resolver_TEST_purges.cc
+++ b/paludis/resolver/resolver_TEST_purges.cc
@@ -126,7 +126,7 @@ namespace test_cases
std::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
"!star-slot-purges/target:1",
parse_user_package_dep_spec("star-slot-purges/target:1", &env, { }),
- false)));
+ bk_weak)));
check_resolved(resolved,
n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
diff --git a/paludis/resolver/resolver_TEST_uninstalls.cc b/paludis/resolver/resolver_TEST_uninstalls.cc
index 46c9ff7..8369b46 100644
--- a/paludis/resolver/resolver_TEST_uninstalls.cc
+++ b/paludis/resolver/resolver_TEST_uninstalls.cc
@@ -96,7 +96,7 @@ namespace test_cases
std::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
"!breaking/target",
parse_user_package_dep_spec("breaking/target", &env, { }),
- false)));
+ bk_weak)));
if (allowed_to_remove)
check_resolved(resolved,
diff --git a/paludis/resolver/spec_rewriter.cc b/paludis/resolver/spec_rewriter.cc
index d920842..08f6aca 100644
--- a/paludis/resolver/spec_rewriter.cc
+++ b/paludis/resolver/spec_rewriter.cc
@@ -136,7 +136,7 @@ SpecRewriter::rewrite_if_special(const PackageOrBlockDepSpec & s, const std::sha
std::string::size_type p(prefix.find_first_not_of('!'));
if (std::string::npos != p)
prefix.erase(p);
- result->specs()->push_back(BlockDepSpec(prefix + stringify(spec), spec, s.if_block()->strong()));
+ result->specs()->push_back(BlockDepSpec(prefix + stringify(spec), spec, s.if_block()->block_kind()));
}
return result;
diff --git a/paludis/stringify_formatter_TEST.cc b/paludis/stringify_formatter_TEST.cc
index e2e1592..5245f87 100644
--- a/paludis/stringify_formatter_TEST.cc
+++ b/paludis/stringify_formatter_TEST.cc
@@ -115,8 +115,7 @@ namespace test_cases
PartialFormatter f;
StringifyFormatter ff(f);
- BlockDepSpec b("!!!!!cat/pkg", parse_user_package_dep_spec("cat/pkg",
- &env, { }), false);
+ BlockDepSpec b("!!!!!cat/pkg", parse_user_package_dep_spec("cat/pkg", &env, { }), bk_weak);
NamedSetDepSpec u(SetName("foo"));
std::string s(format_three(
parse_user_package_dep_spec("cat/pkg", &env, { }),
diff --git a/python/dep_spec.cc b/python/dep_spec.cc
index 7d01468..0d568a4 100644
--- a/python/dep_spec.cc
+++ b/python/dep_spec.cc
@@ -438,17 +438,17 @@ PythonSimpleURIDepSpec::PythonSimpleURIDepSpec(const SimpleURIDepSpec & d) :
{
}
-PythonBlockDepSpec::PythonBlockDepSpec(const std::string & t, const std::shared_ptr<const PythonPackageDepSpec> & a, const bool s) :
+PythonBlockDepSpec::PythonBlockDepSpec(const std::string & t, const std::shared_ptr<const PythonPackageDepSpec> & a, const BlockKind s) :
PythonStringDepSpec(t),
_spec(a),
- _strong(s)
+ _kind(s)
{
}
PythonBlockDepSpec::PythonBlockDepSpec(const BlockDepSpec & d) :
PythonStringDepSpec(d.text()),
_spec(std::make_shared<PythonPackageDepSpec>(d.blocking())),
- _strong(d.strong())
+ _kind(d.block_kind())
{
}
@@ -458,10 +458,10 @@ PythonBlockDepSpec::blocking() const
return _spec;
}
-bool
-PythonBlockDepSpec::strong() const
+BlockKind
+PythonBlockDepSpec::block_kind() const
{
- return _strong;
+ return _kind;
}
PythonFetchableURIDepSpec::PythonFetchableURIDepSpec(const std::string & s) :
@@ -924,7 +924,7 @@ template <typename H_>
void
SpecTreeFromPython<H_>::real_visit(const PythonBlockDepSpec & d)
{
- _add_to->append(std::make_shared<BlockDepSpec>(d.text(), *d.blocking(), d.strong()));
+ _add_to->append(std::make_shared<BlockDepSpec>(d.text(), *d.blocking(), d.block_kind()));
}
template <typename H_>
@@ -1045,6 +1045,9 @@ void expose_dep_spec()
enum_auto("UserPackageDepSpecOption", last_updso,
"Options for parse_user_package_dep_spec.");
+ enum_auto("BlockKind", last_bk,
+ "Options for BlockDepSpec.");
+
/**
* Options
*/
@@ -1332,15 +1335,15 @@ void expose_dep_spec()
"BlockDepSpec",
"A BlockDepSpec represents a block on a package name (for example, 'app-editors/vim'), \n"
"possibly with associated version and SLOT restrictions.",
- bp::init<std::string, std::shared_ptr<const PythonPackageDepSpec>, bool>("__init__(string, PackageDepSpec, bool)")
+ bp::init<std::string, std::shared_ptr<const PythonPackageDepSpec>, BlockKind>("__init__(string, PackageDepSpec, BlockKind)")
)
.add_property("blocking", &PythonBlockDepSpec::blocking,
"[ro] PackageDepSpec\n"
"The spec we're blocking."
)
- .add_property("strong", &PythonBlockDepSpec::strong,
- "[ro] bool\n"
+ .add_property("block_kind", &PythonBlockDepSpec::block_kind,
+ "[ro] BlockKind\n"
"Are we a strong block?"
)
diff --git a/python/dep_spec.hh b/python/dep_spec.hh
index e51af9a..466a5ea 100644
--- a/python/dep_spec.hh
+++ b/python/dep_spec.hh
@@ -233,14 +233,14 @@ namespace paludis
{
private:
std::shared_ptr<const PythonPackageDepSpec> _spec;
- bool _strong;
+ BlockKind _kind;
public:
- PythonBlockDepSpec(const std::string &, const std::shared_ptr<const PythonPackageDepSpec> &, const bool);
+ PythonBlockDepSpec(const std::string &, const std::shared_ptr<const PythonPackageDepSpec> &, const BlockKind);
PythonBlockDepSpec(const BlockDepSpec &);
std::shared_ptr<const PythonPackageDepSpec> blocking() const;
- bool strong() const;
+ BlockKind block_kind() const;
};
class PALUDIS_VISIBLE PythonURILabelsDepSpec :
diff --git a/python/dep_spec_TEST.py b/python/dep_spec_TEST.py
index 556f24b..375e7ee 100755
--- a/python/dep_spec_TEST.py
+++ b/python/dep_spec_TEST.py
@@ -31,7 +31,7 @@ class TestCase_1_DepSpecs(unittest.TestCase):
self.pds3 = parse_user_package_dep_spec("*/*::testrepo", self.env,
[UserPackageDepSpecOption.ALLOW_WILDCARDS])
self.pds4 = parse_user_package_dep_spec("cat/pkg::testrepo", self.env, [])
- self.bds = BlockDepSpec("!>=foo/bar-1:100::testrepo", self.pds, False)
+ self.bds = BlockDepSpec("!>=foo/bar-1:100::testrepo", self.pds, BlockKind.WEAK)
self.nds = NamedSetDepSpec("system")
def test_01_init(self):
diff --git a/ruby/dep_spec.cc b/ruby/dep_spec.cc
index 6f66361..aacaf70 100644
--- a/ruby/dep_spec.cc
+++ b/ruby/dep_spec.cc
@@ -45,6 +45,7 @@ namespace
static VALUE c_dep_spec;
static VALUE c_string_dep_spec;
+ static VALUE c_block_kind;
static VALUE c_block_dep_spec;
static VALUE c_dependencies_labels_dep_spec;
static VALUE c_fetchable_uri_dep_spec;
@@ -465,14 +466,18 @@ namespace
}
VALUE
- block_dep_spec_new(VALUE self, VALUE str, VALUE spec, VALUE strong)
+ block_dep_spec_new(VALUE self, VALUE str, VALUE spec, VALUE kind)
{
std::shared_ptr<const WrappedSpecBase> * ptr(0);
try
{
+ int l = NUM2INT(kind);
+ if (l < 0 || l >= last_bk)
+ rb_raise(rb_eTypeError, "BlockDepSpec expects a valid BlockKind as the third parameter");
+
std::shared_ptr<const PackageDepSpec> pkg(value_to_package_dep_spec(spec));
ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<BlockDepSpec>>(
- std::make_shared<BlockDepSpec>(StringValuePtr(str), *pkg, value_to_bool(strong))));
+ std::make_shared<BlockDepSpec>(StringValuePtr(str), *pkg, static_cast<BlockKind>(l))));
VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr));
rb_obj_call_init(tdata, 3, &str);
return tdata;
@@ -1274,6 +1279,18 @@ namespace
rb_define_method(c_plain_text_label_dep_spec, "to_s", RUBY_FUNC_CAST(plain_text_dep_label_spec_to_s), 0);
/*
+ * Document-module: Paludis::BlockKind
+ *
+ * The kind of a BlockDepSpec
+ */
+ c_block_kind = rb_define_module_under(paludis_module(), "BlockKind");
+ for (BlockKind l(static_cast<BlockKind>(0)), l_end(last_bk) ; l != l_end ;
+ l = static_cast<BlockKind>(static_cast<int>(l) + 1))
+ rb_define_const(c_block_kind, value_case_to_RubyCase(stringify(l)).c_str(), INT2FIX(l));
+
+ // cc_enum_special<paludis/dep_spec.hh, BlockKind, c_block_kind>
+
+ /*
* Document-class: Paludis::BlockDepSpec
*
* A BlockDepSpec represents a block on a package name (for example, 'app-editors/vim'), possibly with
diff --git a/ruby/dep_spec_TEST.rb b/ruby/dep_spec_TEST.rb
index 1ded865..8e8112a 100644
--- a/ruby/dep_spec_TEST.rb
+++ b/ruby/dep_spec_TEST.rb
@@ -273,22 +273,22 @@ module Paludis
end
def test_create
- v = BlockDepSpec.new("!>=foo/bar-1", Paludis::parse_user_package_dep_spec(">=foo/bar-1", env, []), false)
+ v = BlockDepSpec.new("!>=foo/bar-1", Paludis::parse_user_package_dep_spec(">=foo/bar-1", env, []), BlockKind::Weak)
end
def test_create_error
assert_raise TypeError do
- v = BlockDepSpec.new("!>=foo/bar-1", 0, false)
+ v = BlockDepSpec.new("!>=foo/bar-1", 0, BlockKind::Weak)
end
assert_raise TypeError do
- v = BlockDepSpec.new("!>=foo/bar-1", PlainTextDepSpec.new('foo-bar/baz'), false)
+ v = BlockDepSpec.new("!>=foo/bar-1", PlainTextDepSpec.new('foo-bar/baz'), BlockKind::Weak)
end
end
def test_blocked_spec
assert_equal "foo/baz", BlockDepSpec.new("!foo/baz", Paludis::parse_user_package_dep_spec(
- "foo/baz", env, []), false).blocking.to_s
+ "foo/baz", env, []), BlockKind::Weak).blocking.to_s
end
end
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index 341f64f..8cf9f53 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -140,7 +140,7 @@ namespace
{
seen_packages = true;
PackageDepSpec s(parse_user_package_dep_spec(p->first.substr(1), env.get(), { }));
- BlockDepSpec bs("!" + stringify(s), s, false);
+ BlockDepSpec bs("!" + stringify(s), s, bk_weak);
result->push_back(stringify(bs));
resolver->add_target(bs, p->second);
}