aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-24 16:33:47 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-24 16:35:09 +0100
commit80d490caeb816cba5db8909cba0b99b541d99c51 (patch)
tree8b965398370de4222535a2cb1dd7b8f55d0d10bc
parenta6330defb9164948d1181411d40373f85d6fe3eb (diff)
downloadpaludis-80d490caeb816cba5db8909cba0b99b541d99c51.tar.gz
paludis-80d490caeb816cba5db8909cba0b99b541d99c51.tar.xz
cave purge
Fixes: ticket:838
-rw-r--r--paludis/resolver/decider.cc56
-rw-r--r--paludis/resolver/decider.hh5
-rw-r--r--paludis/resolver/resolver.cc6
-rw-r--r--paludis/resolver/resolver.hh1
-rw-r--r--src/clients/cave/Makefile.am2
-rw-r--r--src/clients/cave/cmd_display_resolution.cc7
-rw-r--r--src/clients/cave/cmd_fix_linkage.cc2
-rw-r--r--src/clients/cave/cmd_import.cc2
-rw-r--r--src/clients/cave/cmd_purge.cc119
-rw-r--r--src/clients/cave/cmd_purge.hh45
-rw-r--r--src/clients/cave/cmd_resolve.cc2
-rw-r--r--src/clients/cave/cmd_uninstall.cc2
-rw-r--r--src/clients/cave/command_factory.cc2
-rw-r--r--src/clients/cave/resolve_common.cc22
-rw-r--r--src/clients/cave/resolve_common.hh5
15 files changed, 264 insertions, 14 deletions
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index dbc40e2..8e127bd 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -1713,6 +1713,62 @@ Decider::add_target_with_reason(const PackageOrBlockDepSpec & spec, const std::t
}
void
+Decider::purge()
+{
+ Context context("When purging everything:");
+
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Collecting"));
+
+ const std::tr1::shared_ptr<const PackageIDSet> have_now(_collect_installed());
+ const std::tr1::shared_ptr<PackageIDSequence> have_now_seq(new PackageIDSequence);
+ std::copy(have_now->begin(), have_now->end(), have_now_seq->back_inserter());
+
+ const std::tr1::shared_ptr<const PackageIDSet> world(_collect_world(have_now));
+ const std::tr1::shared_ptr<const PackageIDSet> world_plus_deps(_accumulate_deps(world, have_now_seq));
+
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Calculating Unused"));
+
+ const std::tr1::shared_ptr<PackageIDSet> unused(new PackageIDSet);
+ std::set_difference(have_now->begin(), have_now->end(),
+ world_plus_deps->begin(), world_plus_deps->end(), unused->inserter(), PackageIDSetComparator());
+
+ for (PackageIDSet::ConstIterator i(unused->begin()), i_end(unused->end()) ;
+ i != i_end ; ++i)
+ {
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
+
+ Resolvent resolvent(*i, dt_install_to_slash);
+ const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
+
+ if (resolution->decision())
+ continue;
+
+ const std::tr1::shared_ptr<const PackageIDSequence> used_to_use(new PackageIDSequence);
+ const std::tr1::shared_ptr<const ConstraintSequence> constraints(_make_constraints_for_purge(resolution, *i, used_to_use));
+ for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
+ c != c_end ; ++c)
+ _apply_resolution_constraint(resolution, *c);
+
+ _decide(resolution);
+ }
+}
+
+const std::tr1::shared_ptr<const PackageIDSet>
+Decider::_collect_world(
+ const std::tr1::shared_ptr<const PackageIDSet> & from) const
+{
+ const std::tr1::shared_ptr<PackageIDSet> result(new PackageIDSet);
+ const std::tr1::shared_ptr<const SetSpecTree> set(_imp->env->set(SetName("world")));
+
+ for (PackageIDSet::ConstIterator i(from->begin()), i_end(from->end()) ;
+ i != i_end ; ++i)
+ if (match_package_in_set(*_imp->env, *set, **i, MatchPackageOptions()))
+ result->insert(*i);
+
+ return result;
+}
+
+void
Decider::resolve()
{
while (true)
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index cbdac4a..d57b495 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -233,6 +233,9 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const PackageIDSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const PackageIDSet> _collect_world(
+ const std::tr1::shared_ptr<const PackageIDSet> & from) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
public:
Decider(const Environment * const,
const ResolverFunctions &,
@@ -243,6 +246,8 @@ namespace paludis
void add_target_with_reason(const PackageOrBlockDepSpec &, const std::tr1::shared_ptr<const Reason> &);
+ void purge();
+
std::pair<AnyChildScore, OperatorScore> find_any_score(
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &,
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index cbcdc4c..f35ccae 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -163,6 +163,12 @@ Resolver::add_target(const SetName & set_name)
}
void
+Resolver::purge()
+{
+ _imp->decider->purge();
+}
+
+void
Resolver::resolve()
{
_imp->decider->resolve();
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index 7473f68..443b88e 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -53,6 +53,7 @@ namespace paludis
void add_target(const PackageOrBlockDepSpec &);
void add_target(const SetName &);
+ void purge();
void resolve();
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index 12b41c3..bdd3a84 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -42,6 +42,7 @@ command_MANS = \
cave-print-repository-formats.1 \
cave-print-sets.1 \
cave-print-sync-protocols.1 \
+ cave-purge.1 \
cave-resolve.1 \
cave-resume.1 \
cave-search.1 \
@@ -116,6 +117,7 @@ libcave_a_SOURCES = \
cmd_print_repository_formats.cc cmd_print_repository_formats.hh \
cmd_print_sets.cc cmd_print_sets.hh \
cmd_print_sync_protocols.cc cmd_print_sync_protocols.hh \
+ cmd_purge.cc cmd_purge.hh \
cmd_resolve.cc cmd_resolve.hh \
cmd_resolve_cmdline.cc cmd_resolve_cmdline.hh \
cmd_resolve_display_callback.cc cmd_resolve_display_callback.hh \
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index b797c5c..c70d2d0 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -206,8 +206,11 @@ namespace
std::pair<std::string, bool> visit(const WasUsedByReason & r) const
{
- return std::make_pair("was used by " + join(indirect_iterator(r.ids_being_removed()->begin()),
- indirect_iterator(r.ids_being_removed()->end()), ", "), true);
+ if (r.ids_being_removed()->empty())
+ return std::make_pair("was unused", true);
+ else
+ return std::make_pair("was used by " + join(indirect_iterator(r.ids_being_removed()->begin()),
+ indirect_iterator(r.ids_being_removed()->end()), ", "), true);
}
std::pair<std::string, bool> visit(const TargetReason &) const
diff --git a/src/clients/cave/cmd_fix_linkage.cc b/src/clients/cave/cmd_fix_linkage.cc
index a8cf3bc..af403e9 100644
--- a/src/clients/cave/cmd_fix_linkage.cc
+++ b/src/clients/cave/cmd_fix_linkage.cc
@@ -242,7 +242,7 @@ FixLinkageCommand::run(
resolve_cmdline.execution_options,
resolve_cmdline.display_options,
resolve_cmdline.program_options,
- make_null_shared_ptr(), targets);
+ make_null_shared_ptr(), targets, false);
}
std::tr1::shared_ptr<args::ArgsHandler>
diff --git a/src/clients/cave/cmd_import.cc b/src/clients/cave/cmd_import.cc
index 2a2125f..6b41632 100644
--- a/src/clients/cave/cmd_import.cc
+++ b/src/clients/cave/cmd_import.cc
@@ -280,7 +280,7 @@ ImportCommand::run(
resolve_cmdline.execution_options,
resolve_cmdline.display_options,
resolve_cmdline.program_options,
- keys, targets);
+ keys, targets, false);
}
std::tr1::shared_ptr<args::ArgsHandler>
diff --git a/src/clients/cave/cmd_purge.cc b/src/clients/cave/cmd_purge.cc
new file mode 100644
index 0000000..fc58a70
--- /dev/null
+++ b/src/clients/cave/cmd_purge.cc
@@ -0,0 +1,119 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "cmd_purge.hh"
+#include "cmd_resolve_cmdline.hh"
+#include "resolve_common.hh"
+#include "exceptions.hh"
+
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/selection.hh>
+#include <paludis/generator.hh>
+#include <paludis/filter.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_id.hh>
+#include <paludis/metadata_key.hh>
+
+#include <iostream>
+#include <cstdlib>
+
+using namespace paludis;
+using namespace cave;
+
+using std::cout;
+using std::endl;
+
+namespace
+{
+ struct PurgeCommandLine :
+ CaveCommandCommandLine
+ {
+ std::tr1::shared_ptr<ResolveCommandLineResolutionOptions> resolution_options;
+ std::tr1::shared_ptr<ResolveCommandLineExecutionOptions> execution_options;
+ std::tr1::shared_ptr<ResolveCommandLineDisplayOptions> display_options;
+ std::tr1::shared_ptr<ResolveCommandLineProgramOptions> program_options;
+
+ PurgeCommandLine(const bool for_docs) :
+ resolution_options(for_docs ? make_null_shared_ptr() : make_shared_ptr(new ResolveCommandLineResolutionOptions(this))),
+ execution_options(for_docs ? make_null_shared_ptr() : make_shared_ptr(new ResolveCommandLineExecutionOptions(this))),
+ display_options(for_docs ? make_null_shared_ptr() : make_shared_ptr(new ResolveCommandLineDisplayOptions(this))),
+ program_options(for_docs ? make_null_shared_ptr() : make_shared_ptr(new ResolveCommandLineProgramOptions(this)))
+ {
+ add_usage_line("[ -x|--execute ]");
+ add_note("All options available for 'cave resolve' are also permitted. See 'man cave-resolve' for details.");
+ }
+
+ std::string app_name() const
+ {
+ return "cave purge";
+ }
+
+ std::string app_synopsis() const
+ {
+ return "Uninstall unused packages.";
+ }
+
+ std::string app_description() const
+ {
+ return "Uninstalls any package that is not either in 'world' or a dependency of a package "
+ "in 'world'.";
+ }
+ };
+}
+
+bool
+PurgeCommand::important() const
+{
+ return true;
+}
+
+int
+PurgeCommand::run(
+ const std::tr1::shared_ptr<Environment> & env,
+ const std::tr1::shared_ptr<const Sequence<std::string > > & args
+ )
+{
+ PurgeCommandLine cmdline(false);
+ cmdline.run(args, "CAVE", "CAVE_PURGE_OPTIONS", "CAVE_PURGE_CMDLINE");
+
+ if (cmdline.a_help.specified())
+ {
+ cout << cmdline;
+ return EXIT_SUCCESS;
+ }
+
+ cmdline.resolution_options->apply_shortcuts();
+ cmdline.resolution_options->verify(env);
+
+ cmdline.resolution_options->a_purge.set_specified(true);
+ cmdline.resolution_options->a_purge.add_argument("*/*");
+
+ return resolve_common(env, *cmdline.resolution_options, *cmdline.execution_options, *cmdline.display_options,
+ *cmdline.program_options, make_null_shared_ptr(), make_null_shared_ptr(), true);
+}
+
+std::tr1::shared_ptr<args::ArgsHandler>
+PurgeCommand::make_doc_cmdline()
+{
+ return make_shared_ptr(new PurgeCommandLine(true));
+}
+
diff --git a/src/clients/cave/cmd_purge.hh b/src/clients/cave/cmd_purge.hh
new file mode 100644
index 0000000..33c8920
--- /dev/null
+++ b/src/clients/cave/cmd_purge.hh
@@ -0,0 +1,45 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_PURGE_HH
+#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_PURGE_HH 1
+
+#include "command.hh"
+
+namespace paludis
+{
+ namespace cave
+ {
+ class PALUDIS_VISIBLE PurgeCommand :
+ public Command
+ {
+ public:
+ int run(
+ const std::tr1::shared_ptr<Environment> &,
+ const std::tr1::shared_ptr<const Sequence<std::string > > & args
+ );
+
+ std::tr1::shared_ptr<args::ArgsHandler> make_doc_cmdline();
+
+ bool important() const;
+ };
+ }
+}
+
+#endif
diff --git a/src/clients/cave/cmd_resolve.cc b/src/clients/cave/cmd_resolve.cc
index 8ece545..aee1947 100644
--- a/src/clients/cave/cmd_resolve.cc
+++ b/src/clients/cave/cmd_resolve.cc
@@ -103,7 +103,7 @@ ResolveCommand::run(
targets->push_back(*p);
return resolve_common(env, cmdline.resolution_options, cmdline.execution_options, cmdline.display_options,
- cmdline.program_options, make_null_shared_ptr(), targets);
+ cmdline.program_options, make_null_shared_ptr(), targets, false);
}
std::tr1::shared_ptr<args::ArgsHandler>
diff --git a/src/clients/cave/cmd_uninstall.cc b/src/clients/cave/cmd_uninstall.cc
index 349ab77..5632351 100644
--- a/src/clients/cave/cmd_uninstall.cc
+++ b/src/clients/cave/cmd_uninstall.cc
@@ -136,7 +136,7 @@ UninstallCommand::run(
}
return resolve_common(env, *cmdline.resolution_options, *cmdline.execution_options, *cmdline.display_options,
- *cmdline.program_options, make_null_shared_ptr(), targets);
+ *cmdline.program_options, make_null_shared_ptr(), targets, false);
}
std::tr1::shared_ptr<args::ArgsHandler>
diff --git a/src/clients/cave/command_factory.cc b/src/clients/cave/command_factory.cc
index 550a8d6..d917a3a 100644
--- a/src/clients/cave/command_factory.cc
+++ b/src/clients/cave/command_factory.cc
@@ -51,6 +51,7 @@
#include "cmd_print_repository_formats.hh"
#include "cmd_print_sets.hh"
#include "cmd_print_sync_protocols.hh"
+#include "cmd_purge.hh"
#include "cmd_resolve.hh"
#include "cmd_resume.hh"
#include "cmd_search.hh"
@@ -103,6 +104,7 @@ CommandFactory::CommandFactory() :
_imp->handlers.insert(std::make_pair("info", std::tr1::bind(&make_command<InfoCommand>)));
_imp->handlers.insert(std::make_pair("match", std::tr1::bind(&make_command<MatchCommand>)));
_imp->handlers.insert(std::make_pair("perform", std::tr1::bind(&make_command<PerformCommand>)));
+ _imp->handlers.insert(std::make_pair("purge", std::tr1::bind(&make_command<PurgeCommand>)));
_imp->handlers.insert(std::make_pair("print-categories", std::tr1::bind(&make_command<PrintCategoriesCommand>)));
_imp->handlers.insert(std::make_pair("print-commands", std::tr1::bind(&make_command<PrintCommandsCommand>)));
_imp->handlers.insert(std::make_pair("print-environment-metadata", std::tr1::bind(&make_command<PrintEnvironmentMetadataCommand>)));
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index e3df2e7..84e6fb0 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -1497,8 +1497,11 @@ namespace
const std::string visit(const WasUsedByReason & r) const
{
- return "from was used by " + join(indirect_iterator(r.ids_being_removed()->begin()),
- indirect_iterator(r.ids_being_removed()->end()), ", ");
+ if (r.ids_being_removed()->empty())
+ return "from was unused";
+ else
+ return "from was used by " + join(indirect_iterator(r.ids_being_removed()->begin()),
+ indirect_iterator(r.ids_being_removed()->end()), ", ");
}
const std::string visit(const DependentReason & r) const
@@ -1569,7 +1572,8 @@ paludis::cave::resolve_common(
const ResolveCommandLineDisplayOptions & display_options,
const ResolveCommandLineProgramOptions & program_options,
const std::tr1::shared_ptr<const Map<std::string, std::string> > & keys_if_import,
- const std::tr1::shared_ptr<const Sequence<std::string> > & targets)
+ const std::tr1::shared_ptr<const Sequence<std::string> > & targets_if_not_purge,
+ const bool purge)
{
int retcode(0);
@@ -1785,7 +1789,10 @@ paludis::cave::resolve_common(
{
try
{
- add_resolver_targets(env, resolver, resolution_options, targets, is_set);
+ if (purge)
+ resolver->purge();
+ else
+ add_resolver_targets(env, resolver, resolution_options, targets_if_not_purge, is_set);
resolver->resolve();
break;
}
@@ -1812,7 +1819,8 @@ paludis::cave::resolve_common(
dump_if_requested(env, resolver, resolution_options);
retcode |= display_resolution(env, resolver->resolved(), resolution_options,
- display_options, program_options, keys_if_import, targets);
+ display_options, program_options, keys_if_import,
+ purge ? make_shared_ptr(new const Sequence<std::string>) : targets_if_not_purge);
if (! resolver->resolved()->taken_unable_to_make_decisions()->empty())
retcode |= 1;
@@ -1825,7 +1833,9 @@ paludis::cave::resolve_common(
if (0 == retcode)
return perform_resolution(env, resolver->resolved(), resolution_options,
- execution_options, program_options, keys_if_import, targets, is_set);
+ execution_options, program_options, keys_if_import,
+ purge ? make_shared_ptr(new const Sequence<std::string>) : targets_if_not_purge,
+ is_set);
}
catch (...)
{
diff --git a/src/clients/cave/resolve_common.hh b/src/clients/cave/resolve_common.hh
index b43d6da..132e5da 100644
--- a/src/clients/cave/resolve_common.hh
+++ b/src/clients/cave/resolve_common.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * Copyright (c) 2009, 2010 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -37,7 +37,8 @@ namespace paludis
const ResolveCommandLineDisplayOptions & display_options,
const ResolveCommandLineProgramOptions & program_options,
const std::tr1::shared_ptr<const Map<std::string, std::string> > & keys_if_import,
- const std::tr1::shared_ptr<const Sequence<std::string> > & targets
+ const std::tr1::shared_ptr<const Sequence<std::string> > & targets_if_not_purge,
+ const bool purge
) PALUDIS_ATTRIBUTE((warn_unused_result));
}
}