diff options
author | 2010-09-05 16:12:26 +0100 | |
---|---|---|
committer | 2010-09-05 16:12:26 +0100 | |
commit | 91a77a7156f6a730097393abae5a43b11f8a7e5a (patch) | |
tree | 1626f58a5b58981b1c425dd7a2f720f0b6962f04 | |
parent | fcf224a626d967528bba7d4cbabec46a03814000 (diff) | |
parent | 95e7880705435bee4833c0bd1b8694f023038e48 (diff) | |
download | paludis-91a77a7156f6a730097393abae5a43b11f8a7e5a.tar.gz paludis-91a77a7156f6a730097393abae5a43b11f8a7e5a.tar.xz |
Merge branch 'blocker-annotations'
34 files changed, 516 insertions, 83 deletions
diff --git a/paludis/dep_spec-fwd.hh b/paludis/dep_spec-fwd.hh index 4bc9409d8..fb968411b 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 4221d4662..6a5f71632 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 98b485f22..0b99291be 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 000000000..3531f2bd9 --- /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 7925b53ec..bf7e5595a 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 6657ec749..b987297de 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 74192cebd..fe4edf4d0 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 d73941657..7aa2beb82 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 f14e9ad27..6faa046d2 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 96e8e2438..ca74e6371 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 3941a5dae..b627b1c5c 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 c9a35e9de..f23e187e8 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 e1d4fa873..e7a97e472 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 7c083c38c..d68c3a9a8 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 d98a70643..e1ba60aeb 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 1309f6288..d27f9a64e 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 507290a25..631a1e423 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 3f4cd7c92..ee7ea91ff 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 33009769f..a82a3eedb 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 5982901d1..ce753449e 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 cb96300f3..576ec5755 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 d6ea45832..3033b7a60 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 51813e421..1dd0f886e 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 ab9e63f28..29da32865 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 be4a6fae0..7068f5b11 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 46c9ff7b5..8369b4600 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 d9208423c..08f6aca9b 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 e2e159208..5245f8705 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 7d0146822..0d568a4de 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 e51af9a82..466a5eaf5 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 556f24b28..375e7ee01 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 6f6636175..aacaf7069 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 1ded8658e..8e8112a8d 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 341f64f1a..8cf9f5365 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); } |