aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-23 11:08:08 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-23 11:08:08 +0100
commit7eab297e804d73548ac4c2cb6ad9145d095cdb34 (patch)
treeeed8e3a9d92e72686be411c9ef05d40c6a7df249
parent7be6e2a6a627f001d26784fc514f462d6bfb7a82 (diff)
downloadpaludis-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.cc27
-rw-r--r--src/clients/cave/cmd_update_world.cc27
-rw-r--r--src/clients/cave/resolve_common.cc40
-rw-r--r--src/clients/cave/resume_data.cc9
-rw-r--r--src/clients/cave/resume_data.hh2
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;