diff options
author | 2010-08-23 11:08:08 +0100 | |
---|---|---|
committer | 2010-08-23 11:08:08 +0100 | |
commit | 7eab297e804d73548ac4c2cb6ad9145d095cdb34 (patch) | |
tree | eed8e3a9d92e72686be411c9ef05d40c6a7df249 | |
parent | 7be6e2a6a627f001d26784fc514f462d6bfb7a82 (diff) | |
download | paludis-7eab297e804d73548ac4c2cb6ad9145d095cdb34.tar.gz paludis-7eab297e804d73548ac4c2cb6ad9145d095cdb34.tar.xz |
Remove remove-if-dependent specs from world
Fixes: ticket:971
-rw-r--r-- | src/clients/cave/cmd_execute_resolution.cc | 27 | ||||
-rw-r--r-- | src/clients/cave/cmd_update_world.cc | 27 | ||||
-rw-r--r-- | src/clients/cave/resolve_common.cc | 40 | ||||
-rw-r--r-- | src/clients/cave/resume_data.cc | 9 | ||||
-rw-r--r-- | src/clients/cave/resume_data.hh | 2 |
5 files changed, 100 insertions, 5 deletions
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc index c864201..5cfdf49 100644 --- a/src/clients/cave/cmd_execute_resolution.cc +++ b/src/clients/cave/cmd_execute_resolution.cc @@ -106,6 +106,7 @@ namespace args::SwitchArg a_pretend; args::SwitchArg a_set; args::StringSetArg a_world_specs; + args::StringSetArg a_removed_if_dependent_names; ResolveCommandLineExecutionOptions execution_options; ResolveCommandLineProgramOptions program_options; @@ -116,6 +117,8 @@ namespace a_pretend(&g_general_options, "pretend", '\0', "Only carry out the pretend action", false), a_set(&g_general_options, "set", '\0', "Our target is a set rather than package specs", false), a_world_specs(&g_general_options, "world-specs", '\0', "Use the specified spec or set name for updating world"), + a_removed_if_dependent_names(&g_general_options, "removed-if-dependent-names", '\0', + "If nothing is left with the specified name, also remove it from world"), execution_options(this), program_options(this), import_options(this) @@ -177,9 +180,13 @@ namespace std::shared_ptr<Sequence<std::string> > world_specs(std::make_shared<Sequence<std::string>>()); std::copy(cmdline.a_world_specs.begin_args(), cmdline.a_world_specs.end_args(), world_specs->back_inserter()); + std::shared_ptr<Sequence<std::string> > removed_if_dependent_names(std::make_shared<Sequence<std::string>>()); + std::copy(cmdline.a_removed_if_dependent_names.begin_args(), cmdline.a_removed_if_dependent_names.end_args(), world_specs->back_inserter()); + ResumeData resume_data(make_named_values<ResumeData>( n::job_lists() = lists, n::preserve_world() = cmdline.execution_options.a_preserve_world.specified(), + n::removed_if_dependent_names() = removed_if_dependent_names, n::target_set() = cmdline.a_set.specified(), n::targets() = targets, n::world_specs() = world_specs @@ -659,6 +666,26 @@ namespace update_world(env, cmdline, true); update_world(env, cmdline, false); + + bool any(false); + std::string command(cmdline.program_options.a_update_world_program.argument()); + if (command.empty()) + command = "$CAVE update-world --verbose --remove --if-nothing-left "; + + for (args::StringSetArg::ConstIterator a(cmdline.a_removed_if_dependent_names.begin_args()), + a_end(cmdline.a_removed_if_dependent_names.end_args()) ; + a != a_end ; ++a) + { + any = true; + command.append(" " + stringify(*a)); + } + + if (any) + { + Process process(ProcessCommand({ "sh", "-c", command })); + if (0 != process.run().wait()) + throw ActionAbortedError("Updating world failed"); + } } int execute_pretends( diff --git a/src/clients/cave/cmd_update_world.cc b/src/clients/cave/cmd_update_world.cc index a4a1f6a..cc4d1ce 100644 --- a/src/clients/cave/cmd_update_world.cc +++ b/src/clients/cave/cmd_update_world.cc @@ -20,13 +20,18 @@ #include "cmd_update_world.hh" #include <paludis/args/args.hh> #include <paludis/args/do_help.hh> -#include <paludis/environment.hh> -#include <paludis/package_database.hh> #include <paludis/util/wrapped_forward_iterator.hh> #include <paludis/util/fs_entry.hh> #include <paludis/util/iterator_funcs.hh> #include <paludis/util/options.hh> #include <paludis/util/sequence.hh> +#include <paludis/environment.hh> +#include <paludis/package_database.hh> +#include <paludis/generator.hh> +#include <paludis/selection.hh> +#include <paludis/filter.hh> +#include <paludis/filtered_generator.hh> +#include <paludis/metadata_key.hh> #include <iostream> #include <cstdlib> @@ -62,6 +67,7 @@ namespace args::ArgsGroup g_update_options; args::SwitchArg a_remove; + args::SwitchArg a_if_nothing_left; args::SwitchArg a_set; UpdateWorldCommandLine() : @@ -70,10 +76,11 @@ namespace g_update_options(main_options_section(), "Update Options", "Alter how updates are performed."), a_remove(&g_update_options, "remove", 'r', "Remove the specified items instead of adding them", true), + a_if_nothing_left(&g_update_options, "if-nothing-left", 'l', "Skip any removes where versions remain", true), a_set(&g_update_options, "set", 's', "The parameters are set names, not package names", true) { - add_usage_line("[ --remove ] cat/pkg ..."); - add_usage_line("[ --remove ] --set setname ..."); + add_usage_line("[ --remove [ --if-nothing-left ] ] cat/pkg ..."); + add_usage_line("[ --remove [ --if-nothing-left ] ] --set setname ..."); } }; } @@ -123,7 +130,17 @@ UpdateWorldCommand::run( name = stringify(q); if (cmdline.a_remove.specified()) - result = env->remove_from_world(q); + { + if (cmdline.a_if_nothing_left.specified()) + { + auto ids((*env)[selection::SomeArbitraryVersion(generator::Package(q) | + filter::InstalledAtRoot(env->preferred_root_key()->value()))]); + if (ids->empty()) + result = env->remove_from_world(q); + } + else + result = env->remove_from_world(q); + } else result = env->add_to_world(q); } diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc index eb87b49..4b0fa66 100644 --- a/src/clients/cave/resolve_common.cc +++ b/src/clients/cave/resolve_common.cc @@ -62,6 +62,8 @@ #include <paludis/resolver/constraint.hh> #include <paludis/resolver/resolver_functions.hh> #include <paludis/resolver/decisions.hh> +#include <paludis/resolver/resolution.hh> +#include <paludis/resolver/resolutions_by_resolvent.hh> #include <paludis/resolver/allow_choice_changes_helper.hh> #include <paludis/resolver/allowed_to_remove_helper.hh> @@ -268,6 +270,7 @@ namespace const std::shared_ptr<const Map<std::string, std::string> > & keys_if_import, const std::shared_ptr<const Sequence<std::pair<std::string, std::string> > > & targets, const std::shared_ptr<const Sequence<std::string> > & world_specs, + const std::shared_ptr<const Sequence<std::string> > & removed_if_dependent_names, const bool is_set) { Context context("When performing chosen resolution:"); @@ -311,6 +314,13 @@ namespace args->push_back(*p); } + for (auto p(removed_if_dependent_names->begin()), p_end(removed_if_dependent_names->end()) ; + p != p_end ; ++p) + { + args->push_back("--removed-if-dependent-names"); + args->push_back(*p); + } + for (Sequence<std::pair<std::string, std::string> >::ConstIterator p(targets->begin()), p_end(targets->end()) ; p != p_end ; ++p) args->push_back(p->first); @@ -521,6 +531,35 @@ namespace throw args::DoHelp("Don't understand argument '" + arg.argument() + "' to '--" + arg.long_name() + "'"); } + + std::shared_ptr<const QualifiedPackageName> name_if_dependent_remove( + const std::shared_ptr<const Resolution> & resolution) + { + const RemoveDecision * const remove_decision(simple_visitor_cast<const RemoveDecision>(*resolution->decision())); + if (remove_decision) + for (auto r(resolution->constraints()->begin()), r_end(resolution->constraints()->end()) ; + r != r_end ; ++r) + if (simple_visitor_cast<const DependentReason>(*(*r)->reason())) + return make_shared_copy((*remove_decision->ids()->begin())->name()); + return make_null_shared_ptr(); + } + + std::shared_ptr<Sequence<std::string> > get_removed_if_dependent_names( + const Environment * const, + const std::shared_ptr<const Resolved> & resolved) + { + auto result(std::make_shared<Sequence<std::string> >()); + for (auto d(resolved->taken_change_or_remove_decisions()->begin()), + d_end(resolved->taken_change_or_remove_decisions()->end()) ; + d != d_end ; ++d) + { + auto n(name_if_dependent_remove(*resolved->resolutions_by_resolvent()->find(d->first->resolvent()))); + if (n) + result->push_back(stringify(*n)); + } + + return result; + } } int @@ -861,6 +900,7 @@ paludis::cave::resolve_common( execution_options, program_options, keys_if_import, purge ? std::make_shared<const Sequence<std::pair<std::string, std::string> > >() : targets_if_not_purge, world_specs_if_not_auto ? world_specs_if_not_auto : targets_cleaned_up, + get_removed_if_dependent_names(env.get(), resolver->resolved()), is_set); } catch (...) diff --git a/src/clients/cave/resume_data.cc b/src/clients/cave/resume_data.cc index cbbe630..4368e94 100644 --- a/src/clients/cave/resume_data.cc +++ b/src/clients/cave/resume_data.cc @@ -54,9 +54,17 @@ ResumeData::deserialise(Deserialisation & d) world_specs->push_back(vv.member<std::string>(stringify(n))); } + std::shared_ptr<Sequence<std::string> > removed_if_dependent_names(std::make_shared<Sequence<std::string>>()); + { + Deserialisator vv(*v.find_remove_member("removed_if_dependent_names"), "c"); + for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n) + removed_if_dependent_names->push_back(vv.member<std::string>(stringify(n))); + } + return make_shared_copy(make_named_values<ResumeData>( n::job_lists() = v.member<std::shared_ptr<JobLists> >("job_lists"), n::preserve_world() = v.member<bool>("preserve_world"), + n::removed_if_dependent_names() = removed_if_dependent_names, n::target_set() = v.member<bool>("target_set"), n::targets() = targets, n::world_specs() = world_specs @@ -69,6 +77,7 @@ ResumeData::serialise(Serialiser & s) const s.object("ResumeData@" + stringify(PALUDIS_VERSION)) .member(SerialiserFlags<serialise::might_be_null>(), "job_lists", job_lists()) .member(SerialiserFlags<>(), "preserve_world", preserve_world()) + .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "removed_if_dependent_names", removed_if_dependent_names()) .member(SerialiserFlags<>(), "target_set", target_set()) .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "targets", targets()) .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "world_specs", world_specs()) diff --git a/src/clients/cave/resume_data.hh b/src/clients/cave/resume_data.hh index 3e02794..ab7cde5 100644 --- a/src/clients/cave/resume_data.hh +++ b/src/clients/cave/resume_data.hh @@ -32,6 +32,7 @@ namespace paludis { typedef Name<struct job_lists_name> job_lists; typedef Name<struct preserve_world_name> preserve_world; + typedef Name<struct removed_if_dependent_names_name> removed_if_dependent_names; typedef Name<struct target_set_name> target_set; typedef Name<struct targets_name> targets; typedef Name<struct world_specs_name> world_specs; @@ -43,6 +44,7 @@ namespace paludis { NamedValue<n::job_lists, std::shared_ptr<resolver::JobLists> > job_lists; NamedValue<n::preserve_world, bool> preserve_world; + NamedValue<n::removed_if_dependent_names, std::shared_ptr<Sequence<std::string> > > removed_if_dependent_names; NamedValue<n::target_set, bool> target_set; NamedValue<n::targets, std::shared_ptr<Sequence<std::string> > > targets; NamedValue<n::world_specs, std::shared_ptr<Sequence<std::string> > > world_specs; |