aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-03-08 11:29:07 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-03-08 11:29:07 +0000
commit141be4efd04237d93c6dff1a844ea9be376caf26 (patch)
treec33381316ecf77cbf6e9574b034fd10de32d18e1
parent1d29ccaf6eb8bb3d5b0fdb56fc8a7ec07db4edb0 (diff)
downloadpaludis-141be4efd04237d93c6dff1a844ea9be376caf26.tar.gz
paludis-141be4efd04237d93c6dff1a844ea9be376caf26.tar.xz
less restrictive remove blockers
-rw-r--r--paludis/resolver/decider.cc39
-rw-r--r--paludis/resolver/decider.hh7
-rw-r--r--paludis/resolver/resolver_functions.hh9
-rw-r--r--paludis/resolver/resolver_test.cc37
-rw-r--r--paludis/resolver/resolver_test.hh7
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.cc22
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.hh6
-rw-r--r--src/clients/cave/resolve_common.cc54
8 files changed, 145 insertions, 36 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index 84652b0..5074247 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -176,8 +176,11 @@ Decider::_resolve_dependents()
changed = true;
const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
- _apply_resolution_constraint(resolvent, _resolution_for_resolvent(resolvent, true),
- _make_constraint_for_removing_dependent(*s));
+ const std::tr1::shared_ptr<const ConstraintSequence> constraints(_make_constraints_for_dependent(
+ resolvent, resolution, *s, dependent_upon));
+ for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
+ c != c_end ; ++c)
+ _apply_resolution_constraint(resolvent, resolution, *c);
}
else
{
@@ -188,32 +191,16 @@ Decider::_resolve_dependents()
return changed;
}
-const std::tr1::shared_ptr<const Constraint>
-Decider::_make_constraint_for_removing_dependent(
- const std::tr1::shared_ptr<const PackageID> & id) const
-{
- const std::tr1::shared_ptr<PresetReason> reason(new PresetReason("dependent", make_null_shared_ptr()));
-
- PartiallyMadePackageDepSpec partial_spec((PartiallyMadePackageDepSpecOptions()));
- partial_spec.package(id->name());
- if (id->slot_key())
- partial_spec.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(
- id->slot_key()->value(), false)));
- PackageDepSpec spec(partial_spec);
-
- const std::tr1::shared_ptr<Constraint> result(new Constraint(make_named_values<Constraint>(
- value_for<n::destination_type>(dt_install_to_slash),
- value_for<n::nothing_is_fine_too>(true),
- value_for<n::reason>(reason),
- value_for<n::spec>(BlockDepSpec("!" + stringify(spec), spec, false)),
- value_for<n::untaken>(false),
- value_for<n::use_existing>(ue_if_possible)
- )));
-
- return result;
+const std::tr1::shared_ptr<ConstraintSequence>
+Decider::_make_constraints_for_dependent(
+ const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & r) const
+{
+ return _imp->fns.get_constraints_for_dependent_fn()(resolvent, resolution, id, r);
}
-
namespace
{
struct DependentChecker
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index f844d7b..3a17b65 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -85,8 +85,11 @@ namespace paludis
const Resolvent & resolvent, const BlockDepSpec & dep,
const std::tr1::shared_ptr<const Reason> & reason) const;
- const std::tr1::shared_ptr<const Constraint> _make_constraint_for_removing_dependent(
- const std::tr1::shared_ptr<const PackageID> &) const;
+ const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_for_dependent(
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &) const;
void _apply_resolution_constraint(const Resolvent &,
const std::tr1::shared_ptr<Resolution> &,
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index ad9e8db..8c6f525 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -45,6 +45,7 @@ namespace paludis
struct care_about_dep_fn;
struct confirm_fn;
struct find_repository_for_fn;
+ struct get_constraints_for_dependent_fn;
struct get_destination_types_for_fn;
struct get_initial_constraints_for_fn;
struct get_resolvents_for_fn;
@@ -83,6 +84,13 @@ namespace paludis
const ChangesToMakeDecision &
)> FindRepositoryForFunction;
+ typedef std::tr1::function<std::tr1::shared_ptr<ConstraintSequence> (
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &
+ )> GetConstraintsForDependentFunction;
+
typedef std::tr1::function<DestinationTypes (
const PackageDepSpec &,
const std::tr1::shared_ptr<const PackageID> &,
@@ -131,6 +139,7 @@ namespace paludis
NamedValue<n::care_about_dep_fn, CareAboutDepFunction> care_about_dep_fn;
NamedValue<n::confirm_fn, ConfirmFunction> confirm_fn;
NamedValue<n::find_repository_for_fn, FindRepositoryForFunction> find_repository_for_fn;
+ NamedValue<n::get_constraints_for_dependent_fn, GetConstraintsForDependentFunction> get_constraints_for_dependent_fn;
NamedValue<n::get_destination_types_for_fn, GetDestinationTypesForFunction> get_destination_types_for_fn;
NamedValue<n::get_initial_constraints_for_fn, GetInitialConstraintsFunction> get_initial_constraints_for_fn;
NamedValue<n::get_resolvents_for_fn, GetResolventsForFunction> get_resolvents_for_fn;
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index 3dccf11..a41482b 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -31,6 +31,7 @@
#include <paludis/resolver/job.hh>
#include <paludis/resolver/jobs.hh>
#include <paludis/resolver/job_id.hh>
+#include <paludis/resolver/reason.hh>
#include <paludis/util/map.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/sequence.hh>
@@ -46,6 +47,7 @@
#include <paludis/filter.hh>
#include <paludis/filtered_generator.hh>
#include <paludis/generator.hh>
+#include <paludis/elike_slot_requirement.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/indirect_iterator-impl.hh>
@@ -290,6 +292,40 @@ paludis::resolver::resolver_test::confirm_fn(
return true;
}
+const std::tr1::shared_ptr<ConstraintSequence>
+paludis::resolver::resolver_test::get_constraints_for_dependent_fn(
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & ids)
+{
+ const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
+
+ PartiallyMadePackageDepSpec partial_spec((PartiallyMadePackageDepSpecOptions()));
+ partial_spec.package(id->name());
+ if (id->slot_key())
+ partial_spec.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(
+ id->slot_key()->value(), false)));
+ PackageDepSpec spec(partial_spec);
+
+ for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ const std::tr1::shared_ptr<PresetReason> reason(new PresetReason("dependent " + stringify(**i), make_null_shared_ptr()));
+
+ result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
+ value_for<n::destination_type>(dt_install_to_slash),
+ value_for<n::nothing_is_fine_too>(true),
+ value_for<n::reason>(reason),
+ value_for<n::spec>(BlockDepSpec("!" + stringify(spec), spec, false)),
+ value_for<n::untaken>(false),
+ value_for<n::use_existing>(ue_if_possible)
+ ))));
+ }
+
+ return result;
+}
+
ResolverTestCase::ResolverTestCase(const std::string & t, const std::string & s, const std::string & e,
const std::string & l) :
TestCase(s),
@@ -351,6 +387,7 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
value_for<n::find_repository_for_fn>(std::tr1::bind(&find_repository_for_fn,
&env, std::tr1::placeholders::_1, std::tr1::placeholders::_2,
std::tr1::placeholders::_3)),
+ value_for<n::get_constraints_for_dependent_fn>(&get_constraints_for_dependent_fn),
value_for<n::get_destination_types_for_fn>(&get_destination_types_for_fn),
value_for<n::get_initial_constraints_for_fn>(
std::tr1::bind(&initial_constraints_for_fn, std::tr1::ref(initial_constraints),
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index c25b006..65acbc3 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -63,6 +63,13 @@ namespace paludis
const InitialConstraints & initial_constraints,
const Resolvent & resolvent);
+ const std::tr1::shared_ptr<ConstraintSequence>
+ get_constraints_for_dependent_fn(
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & ids);
+
std::tr1::shared_ptr<Resolvents> get_resolvents_for_fn(const PackageDepSpec & spec,
const std::tr1::shared_ptr<const SlotName> &,
const std::tr1::shared_ptr<const Reason> &);
diff --git a/src/clients/cave/cmd_resolve_cmdline.cc b/src/clients/cave/cmd_resolve_cmdline.cc
index 1669470..b95cc3e 100644
--- a/src/clients/cave/cmd_resolve_cmdline.cc
+++ b/src/clients/cave/cmd_resolve_cmdline.cc
@@ -66,17 +66,29 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
a_permit_any_version(&g_resolution_options, "permit-any-version", 'a', "Permit installs of versions matching the supplied "
"specification even if those versions are worse than the best visible version in the slot. Use '*/*' "
"to allow all worse versions to be installed."),
+// a_purge(&g_resolution_options, "purge", 'P',
+// "Purge packages matching the given specification, if they will no longer be used after "
+// "a resolution. Use '*/*' to accept all purges, but note that by doing so you are putting "
+// "a great deal of trust in package authors to get dependencies right."),
+
+ g_dependent_options(this, "Dependent Options", "Dependent options. A package is dependent if it "
+ "requires (or looks like it might require) a package which is being removed. By default, "
+ "dependent packages are treated as errors. These options specify a different behaviour."),
a_uninstalls_may_break(&g_resolution_options, "uninstalls-may-break", 'u',
"Permit uninstalls that might break packages matching the specified specification. May be "
"specified multiple times. Use '*/*' to allow all packages to be broken."),
a_remove_if_dependent(&g_resolution_options, "remove-if-dependent", 'r',
"Remove dependent packages that might be broken by other changes if those packages match "
"the specified specification. May be specified multiple times. Use '*/*' to remove all "
- "dependent packages that might be broken, recursively. Does not imply --permit-uninstall."),
-// a_purge(&g_resolution_options, "purge", 'P',
-// "Purge packages matching the given specification, if they will no longer be used after "
-// "a resolution. Use '*/*' to accept all purges, but note that by doing so you are putting "
-// "a great deal of trust in package authors to get dependencies right."),
+ "dependent packages that might be broken, recursively. Does not imply --permit-uninstall, "
+ "which must also be specified."),
+ a_less_restrictive_remove_blockers(&g_resolution_options, "less-restrictive-remove-blockers", 'l',
+ "Use less restrictive blockers for packages matching the supplied specification if that "
+ "package is to be removed by --remove-if-dependent. May be specified multiple times. "
+ "Normally removing dependents is done by a pseudo-block in the form '!cat/pkg:slot'. If "
+ "matched by this option, the block will instead only block the installed dependent "
+ "package, so if reinstalling or upgrading the package will make it no longer be dependent "
+ "then this will be done instead."),
g_keep_options(this, "Reinstall Options", "Control whether installed packages are kept."),
a_keep_targets(&g_keep_options, "keep-targets", 'K',
diff --git a/src/clients/cave/cmd_resolve_cmdline.hh b/src/clients/cave/cmd_resolve_cmdline.hh
index 79eb58e..de465a8 100644
--- a/src/clients/cave/cmd_resolve_cmdline.hh
+++ b/src/clients/cave/cmd_resolve_cmdline.hh
@@ -46,15 +46,17 @@ namespace paludis
args::StringSetArg a_permit_uninstall;
args::StringSetArg a_permit_downgrade;
args::StringSetArg a_permit_any_version;
+// args::StringSetArg a_purge;
+
+ args::ArgsGroup g_dependent_options;
args::StringSetArg a_uninstalls_may_break;
args::StringSetArg a_remove_if_dependent;
-// args::StringSetArg a_purge;
+ args::StringSetArg a_less_restrictive_remove_blockers;
args::ArgsGroup g_keep_options;
args::EnumArg a_keep_targets;
args::EnumArg a_keep;
args::EnumArg a_reinstall_scm;
-// args::SwitchArg a_reinstall_for_removals;
args::StringSetArg a_with;
args::StringSetArg a_without;
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index ec0f559..c945246 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -38,6 +38,7 @@
#include <paludis/util/thread.hh>
#include <paludis/util/timestamp.hh>
#include <paludis/util/map.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/args/do_help.hh>
#include <paludis/args/escape.hh>
#include <paludis/resolver/resolver.hh>
@@ -66,6 +67,7 @@
#include <paludis/serialise-impl.hh>
#include <paludis/selection_cache.hh>
#include <paludis/package_dep_spec_properties.hh>
+#include <paludis/elike_slot_requirement.hh>
#include <algorithm>
#include <iostream>
@@ -1191,6 +1193,47 @@ namespace
));
}
+ const std::tr1::shared_ptr<ConstraintSequence> get_constraints_for_dependent_fn(
+ const Environment * const env,
+ const PackageDepSpecList & list,
+ const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::tr1::shared_ptr<const PackageIDSequence> & ids)
+ {
+ const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
+
+ std::tr1::shared_ptr<PackageDepSpec> spec;
+ if (match_any(env, list, id))
+ spec = make_shared_copy(id->uniquely_identifying_spec());
+ else
+ {
+ PartiallyMadePackageDepSpec partial_spec((PartiallyMadePackageDepSpecOptions()));
+ partial_spec.package(id->name());
+ if (id->slot_key())
+ partial_spec.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(
+ id->slot_key()->value(), false)));
+ spec = make_shared_ptr(new PackageDepSpec(partial_spec));
+ }
+
+ for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ const std::tr1::shared_ptr<PresetReason> reason(new PresetReason("dependent " + stringify(**i), make_null_shared_ptr()));
+
+ result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
+ value_for<n::destination_type>(dt_install_to_slash),
+ value_for<n::nothing_is_fine_too>(true),
+ value_for<n::reason>(reason),
+ value_for<n::spec>(BlockDepSpec("!" + stringify(*spec), *spec, false)),
+ value_for<n::untaken>(false),
+ value_for<n::use_existing>(ue_if_possible)
+ ))));
+ }
+
+ return result;
+ }
+
void ser_thread_func(StringListStream & ser_stream, const ResolverLists & resolution_lists)
{
Serialiser ser(ser_stream);
@@ -1421,7 +1464,7 @@ paludis::cave::resolve_common(
int retcode(0);
InitialConstraints initial_constraints;
- PackageDepSpecList allowed_to_remove_specs, allowed_to_break_specs, remove_if_dependent_specs;
+ PackageDepSpecList allowed_to_remove_specs, allowed_to_break_specs, remove_if_dependent_specs, less_restrictive_remove_blockers_specs;
for (args::StringSetArg::ConstIterator i(resolution_options.a_permit_uninstall.begin_args()),
i_end(resolution_options.a_permit_uninstall.end_args()) ;
@@ -1441,6 +1484,12 @@ paludis::cave::resolve_common(
remove_if_dependent_specs.push_back(parse_user_package_dep_spec(*i, env.get(),
UserPackageDepSpecOptions() + updso_allow_wildcards));
+ for (args::StringSetArg::ConstIterator i(resolution_options.a_less_restrictive_remove_blockers.begin_args()),
+ i_end(resolution_options.a_less_restrictive_remove_blockers.end_args()) ;
+ i != i_end ; ++i)
+ less_restrictive_remove_blockers_specs.push_back(parse_user_package_dep_spec(*i, env.get(),
+ UserPackageDepSpecOptions() + updso_allow_wildcards));
+
for (args::StringSetArg::ConstIterator i(resolution_options.a_preset.begin_args()),
i_end(resolution_options.a_preset.end_args()) ;
i != i_end ; ++i)
@@ -1488,6 +1537,9 @@ paludis::cave::resolve_common(
value_for<n::find_repository_for_fn>(std::tr1::bind(&find_repository_for_fn,
env.get(), std::tr1::cref(resolution_options), std::tr1::placeholders::_1, std::tr1::placeholders::_2,
std::tr1::placeholders::_3)),
+ value_for<n::get_constraints_for_dependent_fn>(std::tr1::bind(&get_constraints_for_dependent_fn,
+ env.get(), std::tr1::cref(less_restrictive_remove_blockers_specs), std::tr1::placeholders::_1,
+ std::tr1::placeholders::_2, std::tr1::placeholders::_3, std::tr1::placeholders::_4)),
value_for<n::get_destination_types_for_fn>(std::tr1::bind(&get_destination_types_for_fn,
env.get(), std::tr1::cref(resolution_options), std::tr1::placeholders::_1, std::tr1::placeholders::_2,
std::tr1::placeholders::_3)),