aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-02-21 21:46:28 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-02-21 21:48:28 +0000
commit977328d782f70c7b3bc4fb52903fa937d037d778 (patch)
treec7e8b29dd906149ac9560a1f93dc7f1f1f1dcbe0
parent47533bc320d045cd7b0d8ab1b32a6d43f1332479 (diff)
downloadpaludis-977328d782f70c7b3bc4fb52903fa937d037d778.tar.gz
paludis-977328d782f70c7b3bc4fb52903fa937d037d778.tar.xz
Do uninstalls as part of the install
-rw-r--r--paludis/action.hh11
-rw-r--r--paludis/install_task.cc132
-rw-r--r--paludis/install_task.hh10
-rw-r--r--paludis/repositories/accounts/accounts_id.cc11
-rw-r--r--paludis/repositories/e/e_repository_TEST.cc12
-rw-r--r--paludis/repositories/e/e_repository_TEST_ever.cc7
-rw-r--r--paludis/repositories/e/e_repository_TEST_exlibs.cc7
-rw-r--r--paludis/repositories/e/ebuild_entries.cc15
-rw-r--r--paludis/repositories/e/exndbam_repository_TEST.cc7
-rw-r--r--paludis/repositories/e/vdb_repository_TEST.cc12
-rw-r--r--paludis/repositories/unpackaged/installed_repository_TEST.cc9
-rw-r--r--paludis/repositories/unpackaged/unpackaged_id.cc22
-rw-r--r--paludis/repositories/unpackaged/unpackaged_repository_TEST.cc8
-rw-r--r--python/action.cc6
-rw-r--r--ruby/action.cc6
-rw-r--r--src/output/console_install_task.cc55
-rw-r--r--src/output/console_install_task.hh15
17 files changed, 186 insertions, 159 deletions
diff --git a/paludis/action.hh b/paludis/action.hh
index 14b6a5f..0416b10 100644
--- a/paludis/action.hh
+++ b/paludis/action.hh
@@ -55,6 +55,7 @@ namespace paludis
struct failed_integrity_checks;
struct fetch_unneeded;
struct make_output_manager;
+ struct perform_uninstall;
struct replacing;
struct requires_manual_fetching;
struct safe_resume;
@@ -110,6 +111,16 @@ namespace paludis
*/
NamedValue<n::make_output_manager, std::tr1::function<std::tr1::shared_ptr<OutputManager> (
const InstallAction &)> > make_output_manager;
+ /**
+ * Callback to carry out an uninstall, for replacing.
+ *
+ * Won't necessarily be used. Some repositories have special code paths
+ * for reinstalls, and in some cases (e.g. accounts) an upgrade doesn't
+ * remove the old version at all.
+ *
+ * \since 0.36
+ */
+ NamedValue<n::perform_uninstall, std::tr1::function<void (const std::tr1::shared_ptr<const PackageID> &)> > perform_uninstall;
/**
* We must replace these.
diff --git a/paludis/install_task.cc b/paludis/install_task.cc
index e424eba..9e65718 100644
--- a/paludis/install_task.cc
+++ b/paludis/install_task.cc
@@ -726,6 +726,45 @@ InstallTask::_pretend()
}
void
+InstallTask::_clean(
+ const DepList::Iterator dep,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const std::string & cpvr,
+ const int x, const int y, const int s, const int f)
+{
+ /* clean one item */
+ if (0 != perform_hook(Hook("clean_pre")("TARGET", stringify(*id))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status())
+ throw InstallActionError("Clean of '" + cpvr + "' aborted by hook");
+ on_clean_pre(*dep, *id, x, y, s, f);
+
+ try
+ {
+ OutputManagerFromEnvironment output_manager_holder(_imp->env, id, oe_exclusive);
+ UninstallAction uninstall_action(
+ make_named_values<UninstallActionOptions>(
+ value_for<n::config_protect>(_imp->config_protect),
+ value_for<n::make_output_manager>(std::tr1::ref(output_manager_holder))
+ ));
+ id->perform_action(uninstall_action);
+ if (output_manager_holder.output_manager_if_constructed())
+ output_manager_holder.output_manager_if_constructed()->succeeded();
+ }
+ catch (const UninstallActionError & e)
+ {
+ on_clean_fail(*dep, *id, x, y, s, f);
+ HookResult PALUDIS_ATTRIBUTE((unused)) dummy(perform_hook(Hook("clean_fail")
+ ("TARGET", stringify(*id))("MESSAGE", e.message())));
+ throw;
+ }
+
+ on_clean_post(*dep, *id, x, y, s, f);
+ if (0 != perform_hook(Hook("clean_post")("TARGET", stringify(*id))
+ ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status())
+ throw InstallActionError("Clean of '" + cpvr + "' aborted by hook");
+}
+
+void
InstallTask::_one(const DepList::Iterator dep, const int x, const int y, const int s, const int f, const bool is_first, const bool is_last,
std::tr1::shared_ptr<OutputManagerFromEnvironment> & output_manager_holder)
{
@@ -780,11 +819,23 @@ InstallTask::_one(const DepList::Iterator dep, const int x, const int y, const i
{
output_manager_holder.reset(new OutputManagerFromEnvironment(_imp->env, dep->package_id(), oe_exclusive));
- std::tr1::shared_ptr<PackageIDSequence> replacing(new PackageIDSequence);
+ std::tr1::shared_ptr<PackageIDSequence> replacing;
+
+ // look for packages with the same name in the same slot in the destination repos
+ if (dep->destination())
+ replacing = (*_imp->env)[selection::AllVersionsSorted(
+ (generator::Package(dep->package_id()->name()) &
+ generator::InRepository(dep->destination()->name())) |
+ filter::SupportsAction<UninstallAction>() |
+ filter::SameSlot(dep->package_id()))];
+ else
+ replacing.reset(new PackageIDSequence);
InstallActionOptions install_options(make_named_values<InstallActionOptions>(
value_for<n::destination>(dep->destination()),
value_for<n::make_output_manager>(std::tr1::ref(*output_manager_holder)),
+ value_for<n::perform_uninstall>(std::tr1::bind(&InstallTask::_clean, this, dep,
+ std::tr1::placeholders::_1, cpvr, x, y, s, f)),
value_for<n::replacing>(replacing),
value_for<n::used_this_for_config_protect>(std::tr1::bind(
&Implementation<InstallTask>::assign_config_protect,
@@ -850,90 +901,11 @@ InstallTask::_one(const DepList::Iterator dep, const int x, const int y, const i
if (_imp->fetch_only || ! live_destination)
return;
- /* figure out whether we need to unmerge (clean) anything */
- on_build_cleanlist_pre(*dep);
-
// manually invalidate repos, they're probably wrong now
for (PackageDatabase::RepositoryConstIterator r(_imp->env->package_database()->begin_repositories()),
r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
(*r)->invalidate();
- // look for packages with the same name in the same slot in the destination repos
- std::tr1::shared_ptr<const PackageIDSequence> collision_list;
-
- if (dep->destination())
- collision_list = (*_imp->env)[selection::AllVersionsSorted(
- (generator::Package(dep->package_id()->name()) &
- generator::InRepository(dep->destination()->name())) |
- filter::SupportsAction<UninstallAction>() |
- filter::SameSlot(dep->package_id()))];
-
- // don't clean the thing we just installed
- PackageIDSequence clean_list;
- if (collision_list)
- for (PackageIDSequence::ConstIterator c(collision_list->begin()),
- c_end(collision_list->end()) ; c != c_end ; ++c)
- if (dep->package_id()->version() != (*c)->version())
- clean_list.push_back(*c);
- /* no need to sort clean_list here, although if the above is
- * changed then check that this still holds... */
-
- on_build_cleanlist_post(*dep);
-
- /* ok, we have the cleanlist. we're about to clean */
- if (clean_list.empty())
- on_no_clean_needed(*dep);
- else
- {
- if (0 != perform_hook(Hook("clean_all_pre")
- ("TARGETS", join(indirect_iterator(clean_list.begin()), indirect_iterator(clean_list.end()), " "))
- ).max_exit_status())
- throw InstallActionError("Clean aborted by hook");
- on_clean_all_pre(*dep, clean_list);
-
- for (PackageIDSequence::ConstIterator c(clean_list.begin()),
- c_end(clean_list.end()) ; c != c_end ; ++c)
- {
- /* clean one item */
- if (0 != perform_hook(Hook("clean_pre")("TARGET", stringify(**c))
- ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status())
- throw InstallActionError("Clean of '" + cpvr + "' aborted by hook");
- on_clean_pre(*dep, **c, x, y, s, f);
-
- try
- {
- output_manager_holder.reset(new OutputManagerFromEnvironment(_imp->env, dep->package_id(), oe_exclusive));
- UninstallAction uninstall_action(
- make_named_values<UninstallActionOptions>(
- value_for<n::config_protect>(_imp->config_protect),
- value_for<n::make_output_manager>(std::tr1::ref(*output_manager_holder))
- ));
- (*c)->perform_action(uninstall_action);
- if (output_manager_holder->output_manager_if_constructed())
- output_manager_holder->output_manager_if_constructed()->succeeded();
- output_manager_holder.reset();
- }
- catch (const UninstallActionError & e)
- {
- on_clean_fail(*dep, **c, x, y, s, f);
- HookResult PALUDIS_ATTRIBUTE((unused)) dummy(perform_hook(Hook("clean_fail")
- ("TARGET", stringify(**c))("MESSAGE", e.message())));
- throw;
- }
-
- on_clean_post(*dep, **c, x, y, s, f);
- if (0 != perform_hook(Hook("clean_post")("TARGET", stringify(**c))
- ("X_OF_Y", stringify(x) + " of " + stringify(y))).max_exit_status())
- throw InstallActionError("Clean of '" + cpvr + "' aborted by hook");
- }
-
- /* we're done cleaning */
- if (0 != perform_hook(Hook("clean_all_post")("TARGETS", join(
- indirect_iterator(clean_list.begin()), indirect_iterator(clean_list.end()), " "))).max_exit_status())
- throw InstallActionError("Clean aborted by hook");
- on_clean_all_post(*dep, clean_list);
- }
-
dep->handled().reset(new DepListEntryHandledSuccess);
/* if we installed paludis and a re-exec is available, use it. */
diff --git a/paludis/install_task.hh b/paludis/install_task.hh
index e733324..39472df 100644
--- a/paludis/install_task.hh
+++ b/paludis/install_task.hh
@@ -65,6 +65,8 @@ namespace paludis
void _main_actions();
void _one(const DepList::Iterator, const int, const int, const int, const int, const bool is_first, const bool is_last,
std::tr1::shared_ptr<OutputManagerFromEnvironment> &);
+ void _clean(const DepList::Iterator, const std::tr1::shared_ptr<const PackageID> & id,
+ const std::string & cpvr, const int x, const int y, const int s, const int f);
void _display_failure_summary();
void _add_target(const std::string &);
@@ -136,9 +138,6 @@ namespace paludis
virtual void on_build_deplist_pre() = 0;
virtual void on_build_deplist_post() = 0;
- virtual void on_build_cleanlist_pre(const DepListEntry &) = 0;
- virtual void on_build_cleanlist_post(const DepListEntry &) = 0;
-
virtual void on_display_merge_list_pre() = 0;
virtual void on_display_merge_list_post() = 0;
virtual void on_display_merge_list_entry(const DepListEntry &) = 0;
@@ -175,9 +174,6 @@ namespace paludis
const int x, const int y, const int s, const int f) = 0;
virtual void on_skip_already_done(const DepListEntry &, const int, const int, const int, const int) = 0;
- virtual void on_no_clean_needed(const DepListEntry &) = 0;
- virtual void on_clean_all_pre(const DepListEntry &,
- const PackageIDSequence &) = 0;
virtual void on_clean_pre(const DepListEntry &,
const PackageID &,
const int x, const int y, const int s, const int f) = 0;
@@ -187,8 +183,6 @@ namespace paludis
virtual void on_clean_fail(const DepListEntry &,
const PackageID &,
const int x, const int y, const int s, const int f) = 0;
- virtual void on_clean_all_post(const DepListEntry &,
- const PackageIDSequence &) = 0;
virtual void on_update_world_pre() = 0;
virtual void on_update_world(const PackageDepSpec &) = 0;
diff --git a/paludis/repositories/accounts/accounts_id.cc b/paludis/repositories/accounts/accounts_id.cc
index a306a69..b1d10bf 100644
--- a/paludis/repositories/accounts/accounts_id.cc
+++ b/paludis/repositories/accounts/accounts_id.cc
@@ -463,5 +463,16 @@ AccountsID::perform_action(Action & action) const
}
output_manager->succeeded();
+
+ for (PackageIDSequence::ConstIterator i(install_action->options.replacing()->begin()), i_end(install_action->options.replacing()->end()) ;
+ i != i_end ; ++i)
+ {
+ Context local_context("When cleaning '" + stringify(**i) + "':");
+ if ((*i)->repository()->format_key() && (*i)->repository()->format_key()->value() == "installed-accounts"
+ && (*i)->name() == name())
+ continue;
+ else
+ install_action->options.perform_uninstall()(*i);
+ }
}
diff --git a/paludis/repositories/e/e_repository_TEST.cc b/paludis/repositories/e/e_repository_TEST.cc
index 64c265e..5bf1665 100644
--- a/paludis/repositories/e/e_repository_TEST.cc
+++ b/paludis/repositories/e/e_repository_TEST.cc
@@ -58,6 +58,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -1106,6 +1112,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -1363,6 +1370,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -1459,6 +1467,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -1585,6 +1594,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -1792,6 +1802,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -2376,6 +2387,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/paludis/repositories/e/e_repository_TEST_ever.cc b/paludis/repositories/e/e_repository_TEST_ever.cc
index a7c6e46..71320c7 100644
--- a/paludis/repositories/e/e_repository_TEST_ever.cc
+++ b/paludis/repositories/e/e_repository_TEST_ever.cc
@@ -58,6 +58,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -146,6 +152,7 @@ namespace
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/paludis/repositories/e/e_repository_TEST_exlibs.cc b/paludis/repositories/e/e_repository_TEST_exlibs.cc
index 8209c98..20fa8f3 100644
--- a/paludis/repositories/e/e_repository_TEST_exlibs.cc
+++ b/paludis/repositories/e/e_repository_TEST_exlibs.cc
@@ -58,6 +58,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -136,6 +142,7 @@ namespace
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/paludis/repositories/e/ebuild_entries.cc b/paludis/repositories/e/ebuild_entries.cc
index 3f9f681..cc3bc28 100644
--- a/paludis/repositories/e/ebuild_entries.cc
+++ b/paludis/repositories/e/ebuild_entries.cc
@@ -530,7 +530,10 @@ EbuildEntries::install(const std::tr1::shared_ptr<const ERepositoryID> & id,
{
using namespace std::tr1::placeholders;
- Context context("When installing '" + stringify(*id) + "':");
+ Context context("When installing '" + stringify(*id) + "'" +
+ (install_action.options.replacing()->empty() ? "" : " replacing { '"
+ + join(indirect_iterator(install_action.options.replacing()->begin()),
+ indirect_iterator(install_action.options.replacing()->end()), "', '") + "' }") + ":");
std::tr1::shared_ptr<OutputManager> output_manager(install_action.options.make_output_manager()(install_action));
@@ -777,6 +780,16 @@ EbuildEntries::install(const std::tr1::shared_ptr<const ERepositoryID> & id,
}
output_manager->succeeded();
+
+ for (PackageIDSequence::ConstIterator i(install_action.options.replacing()->begin()), i_end(install_action.options.replacing()->end()) ;
+ i != i_end ; ++i)
+ {
+ Context local_context("When cleaning '" + stringify(**i) + "':");
+ if ((*i)->name() == id->name() && (*i)->version() == id->version())
+ continue;
+
+ install_action.options.perform_uninstall()(*i);
+ }
}
void
diff --git a/paludis/repositories/e/exndbam_repository_TEST.cc b/paludis/repositories/e/exndbam_repository_TEST.cc
index 0f8cae9..9608cfa 100644
--- a/paludis/repositories/e/exndbam_repository_TEST.cc
+++ b/paludis/repositories/e/exndbam_repository_TEST.cc
@@ -40,6 +40,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -130,6 +136,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(exndbam_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/paludis/repositories/e/vdb_repository_TEST.cc b/paludis/repositories/e/vdb_repository_TEST.cc
index f2d7160..b8d95b7 100644
--- a/paludis/repositories/e/vdb_repository_TEST.cc
+++ b/paludis/repositories/e/vdb_repository_TEST.cc
@@ -51,6 +51,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -344,6 +350,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(vdb_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -471,6 +478,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(vdb_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -598,6 +606,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(vdb_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -997,6 +1006,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(vdb_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -1237,6 +1247,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(vdb_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -1330,6 +1341,7 @@ namespace test_cases
InstallAction install_action(make_named_values<InstallActionOptions>(
value_for<n::destination>(vdb_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/paludis/repositories/unpackaged/installed_repository_TEST.cc b/paludis/repositories/unpackaged/installed_repository_TEST.cc
index 2c33132..202d756 100644
--- a/paludis/repositories/unpackaged/installed_repository_TEST.cc
+++ b/paludis/repositories/unpackaged/installed_repository_TEST.cc
@@ -44,6 +44,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -397,6 +403,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -454,6 +461,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -514,6 +522,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/paludis/repositories/unpackaged/unpackaged_id.cc b/paludis/repositories/unpackaged/unpackaged_id.cc
index 64468b3..ced8e48 100644
--- a/paludis/repositories/unpackaged/unpackaged_id.cc
+++ b/paludis/repositories/unpackaged/unpackaged_id.cc
@@ -284,6 +284,18 @@ UnpackagedID::supports_action(const SupportsActionTestBase & test) const
return simple_visitor_cast<const SupportsActionTest<InstallAction> >(test);
}
+namespace
+{
+ bool slot_is_same(const std::tr1::shared_ptr<const PackageID> & a,
+ const PackageID * const b)
+ {
+ if (a->slot_key())
+ return b->slot_key() && a->slot_key()->value() == b->slot_key()->value();
+ else
+ return ! b->slot_key();
+ }
+}
+
void
UnpackagedID::perform_action(Action & action) const
{
@@ -369,6 +381,16 @@ UnpackagedID::perform_action(Action & action) const
}
output_manager->succeeded();
+
+ for (PackageIDSequence::ConstIterator i(install_action->options.replacing()->begin()), i_end(install_action->options.replacing()->end()) ;
+ i != i_end ; ++i)
+ {
+ Context local_context("When cleaning '" + stringify(**i) + "':");
+ if ((*i)->name() == name() && (*i)->version() == version() && slot_is_same(*i, this))
+ continue;
+
+ install_action->options.perform_uninstall()(*i);
+ }
}
void
diff --git a/paludis/repositories/unpackaged/unpackaged_repository_TEST.cc b/paludis/repositories/unpackaged/unpackaged_repository_TEST.cc
index 6e8e5ee..2a030c1 100644
--- a/paludis/repositories/unpackaged/unpackaged_repository_TEST.cc
+++ b/paludis/repositories/unpackaged/unpackaged_repository_TEST.cc
@@ -42,6 +42,12 @@ using namespace paludis;
namespace
{
+ void cannot_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if (id)
+ throw InternalError(PALUDIS_HERE, "cannot uninstall");
+ }
+
std::tr1::shared_ptr<OutputManager> make_standard_output_manager(const Action &)
{
return make_shared_ptr(new StandardOutputManager);
@@ -237,6 +243,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
@@ -293,6 +300,7 @@ namespace test_cases
InstallAction action(make_named_values<InstallActionOptions>(
value_for<n::destination>(installed_repo),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/python/action.cc b/python/action.cc
index ceedafb..5f8f99f 100644
--- a/python/action.cc
+++ b/python/action.cc
@@ -66,12 +66,18 @@ namespace
return make_shared_ptr(new StandardOutputManager);
}
+ void cannot_perform_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ throw InternalError(PALUDIS_HERE, "Can't uninstall '" + stringify(*id) + "'");
+ }
+
InstallActionOptions * make_install_action_options(
const std::tr1::shared_ptr<paludis::Repository> & r)
{
return new InstallActionOptions(make_named_values<InstallActionOptions>(
value_for<n::destination>(r),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_perform_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/ruby/action.cc b/ruby/action.cc
index 1c16f13..4723cca 100644
--- a/ruby/action.cc
+++ b/ruby/action.cc
@@ -510,6 +510,11 @@ namespace
return wp_yes;
}
+ void cannot_perform_uninstall(const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ throw InternalError(PALUDIS_HERE, "Can't uninstall '" + stringify(*id) + "'");
+ }
+
/*
* call-seq:
* InstallActionOptions.new(destination) -> InstallActionOptions
@@ -547,6 +552,7 @@ namespace
ptr = new InstallActionOptions(make_named_values<InstallActionOptions>(
value_for<n::destination>(v_destination),
value_for<n::make_output_manager>(&make_standard_output_manager),
+ value_for<n::perform_uninstall>(&cannot_perform_uninstall),
value_for<n::replacing>(make_shared_ptr(new PackageIDSequence)),
value_for<n::used_this_for_config_protect>(&dummy_used_this_for_config_protect),
value_for<n::want_phase>(&want_all_phases)
diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc
index d224b08..9fd1128 100644
--- a/src/output/console_install_task.cc
+++ b/src/output/console_install_task.cc
@@ -210,36 +210,6 @@ ConsoleInstallTask::on_build_deplist_post()
}
void
-ConsoleInstallTask::on_build_cleanlist_pre(const DepListEntry & d)
-{
- output_heading("Cleaning stale versions after installing " + stringify(*d.package_id()));
-}
-
-void
-ConsoleInstallTask::on_build_cleanlist_post(const DepListEntry &)
-{
-}
-
-void
-ConsoleInstallTask::on_clean_all_pre(const DepListEntry & d,
- const PackageIDSequence & c)
-{
- display_clean_all_pre_list_start(d, c);
-
- using namespace std::tr1::placeholders;
- std::for_each(indirect_iterator(c.begin()), indirect_iterator(c.end()),
- std::tr1::bind(std::tr1::mem_fn(&ConsoleInstallTask::display_one_clean_all_pre_list_entry), this, _1));
-
- display_clean_all_pre_list_end(d, c);
-}
-
-void
-ConsoleInstallTask::on_no_clean_needed(const DepListEntry &)
-{
- output_starred_item("No cleaning required");
-}
-
-void
ConsoleInstallTask::on_clean_pre(const DepListEntry &,
const PackageID & c, const int x, const int y, const int s, const int f)
{
@@ -262,12 +232,6 @@ ConsoleInstallTask::on_clean_fail(const DepListEntry &,
}
void
-ConsoleInstallTask::on_clean_all_post(const DepListEntry &,
- const PackageIDSequence &)
-{
-}
-
-void
ConsoleInstallTask::on_display_merge_list_pre()
{
output_heading("These packages will be installed:");
@@ -625,25 +589,6 @@ ConsoleInstallTask::on_preserve_world()
}
void
-ConsoleInstallTask::display_clean_all_pre_list_start(const DepListEntry &,
- const PackageIDSequence &)
-{
-}
-
-void
-ConsoleInstallTask::display_one_clean_all_pre_list_entry(
- const PackageID & c)
-{
- output_starred_item(render_as_package_name(stringify(c)));
-}
-
-void
-ConsoleInstallTask::display_clean_all_pre_list_end(const DepListEntry &,
- const PackageIDSequence &)
-{
-}
-
-void
ConsoleInstallTask::display_merge_list_post_counts()
{
std::ostringstream s;
diff --git a/src/output/console_install_task.hh b/src/output/console_install_task.hh
index 5262580..220c12a 100644
--- a/src/output/console_install_task.hh
+++ b/src/output/console_install_task.hh
@@ -126,9 +126,6 @@ namespace paludis
virtual void on_build_deplist_pre();
virtual void on_build_deplist_post();
- virtual void on_build_cleanlist_pre(const DepListEntry &);
- virtual void on_build_cleanlist_post(const DepListEntry &);
-
virtual void on_display_merge_list_pre();
virtual void on_display_merge_list_post();
virtual void on_not_continuing_due_to_errors();
@@ -156,17 +153,12 @@ namespace paludis
const int x, const int y, const int s, const int f);
virtual void on_skip_already_done(const DepListEntry &, const int, const int, const int, const int);
- virtual void on_no_clean_needed(const DepListEntry &);
- virtual void on_clean_all_pre(const DepListEntry &,
- const PackageIDSequence &);
virtual void on_clean_pre(const DepListEntry &,
const PackageID &, const int x, const int y, const int s, const int f);
virtual void on_clean_post(const DepListEntry &,
const PackageID &, const int x, const int y, const int s, const int f);
virtual void on_clean_fail(const DepListEntry &,
const PackageID &, const int x, const int y, const int s, const int f);
- virtual void on_clean_all_post(const DepListEntry &,
- const PackageIDSequence &);
virtual void on_update_world_pre();
virtual void on_update_world(const PackageDepSpec &);
@@ -204,13 +196,6 @@ namespace paludis
///\name More granular display routines
///\{
- virtual void display_clean_all_pre_list_start(const DepListEntry &,
- const PackageIDSequence &);
- virtual void display_one_clean_all_pre_list_entry(
- const PackageID &);
- virtual void display_clean_all_pre_list_end(const DepListEntry &,
- const PackageIDSequence &);
-
virtual void display_merge_list_post_counts();
virtual void display_merge_list_post_tags();
virtual void display_merge_list_post_use_descriptions();