aboutsummaryrefslogtreecommitdiff
path: root/0.8.0/paludis/tasks
diff options
context:
space:
mode:
Diffstat (limited to '0.8.0/paludis/tasks')
-rw-r--r--0.8.0/paludis/tasks/Makefile.am32
-rw-r--r--0.8.0/paludis/tasks/install_task.cc378
-rw-r--r--0.8.0/paludis/tasks/install_task.hh139
-rw-r--r--0.8.0/paludis/tasks/sync_task.cc104
-rw-r--r--0.8.0/paludis/tasks/sync_task.hh79
-rw-r--r--0.8.0/paludis/tasks/uninstall_task.cc206
-rw-r--r--0.8.0/paludis/tasks/uninstall_task.hh133
7 files changed, 1071 insertions, 0 deletions
diff --git a/0.8.0/paludis/tasks/Makefile.am b/0.8.0/paludis/tasks/Makefile.am
new file mode 100644
index 0000000..07ce51b
--- /dev/null
+++ b/0.8.0/paludis/tasks/Makefile.am
@@ -0,0 +1,32 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\"
+SUBDIRS = .
+
+TESTS =
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \
+ PALUDIS_SKIP_CONFIG="yes" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ bash $(top_srcdir)/test/run_test.sh
+
+check_PROGRAMS = $(TESTS)
+check_SCRIPTS =
+
+lib_LIBRARIES = libpaludistasks.a
+paludis_tasks_includedir = $(includedir)/paludis/tasks
+paludis_tasks_include_HEADERS = \
+ install_task.hh \
+ uninstall_task.hh \
+ sync_task.hh
+
+libpaludistasks_a_SOURCES = $(paludis_tasks_include_HEADERS) \
+ install_task.cc \
+ uninstall_task.cc \
+ sync_task.cc
+
diff --git a/0.8.0/paludis/tasks/install_task.cc b/0.8.0/paludis/tasks/install_task.cc
new file mode 100644
index 0000000..f05e946
--- /dev/null
+++ b/0.8.0/paludis/tasks/install_task.cc
@@ -0,0 +1,378 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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 "install_task.hh"
+#include <paludis/dep_atom.hh>
+#include <paludis/portage_dep_parser.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <list>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<InstallTask> :
+ InternalCounted<Implementation<InstallTask> >
+ {
+ Environment * const env;
+ DepList dep_list;
+ DepList::Iterator current_dep_list_entry;
+ InstallOptions install_options;
+
+ std::list<std::string> raw_targets;
+ AllDepAtom::Pointer targets;
+
+ bool pretend;
+ bool preserve_world;
+
+ bool had_set_targets;
+ bool had_package_targets;
+
+ Implementation<InstallTask>(Environment * const e, const DepListOptions & o) :
+ env(e),
+ dep_list(e, o),
+ current_dep_list_entry(dep_list.begin()),
+ install_options(false, false),
+ targets(new AllDepAtom),
+ pretend(false),
+ preserve_world(false),
+ had_set_targets(false),
+ had_package_targets(false)
+ {
+ }
+ };
+}
+
+MultipleSetTargetsSpecified::MultipleSetTargetsSpecified() throw () :
+ Exception("More than one set target was specified")
+{
+}
+
+HadBothPackageAndSetTargets::HadBothPackageAndSetTargets() throw () :
+ Exception("Both package and set targets were specified")
+{
+}
+
+InstallTask::InstallTask(Environment * const env, const DepListOptions & options) :
+ PrivateImplementationPattern<InstallTask>(new Implementation<InstallTask>(env, options))
+{
+}
+
+InstallTask::~InstallTask()
+{
+}
+
+void
+InstallTask::add_target(const std::string & target)
+{
+ Context context("When adding install target '" + target + "':");
+
+ DepAtom::Pointer s(0);
+
+ if ((target != "insecurity") && ((s = ((_imp->env->package_set(target))))))
+ {
+ if (_imp->had_set_targets)
+ throw MultipleSetTargetsSpecified();
+
+ if (_imp->had_package_targets)
+ throw HadBothPackageAndSetTargets();
+
+ _imp->had_set_targets = true;
+ _imp->dep_list.options.target_type = dl_target_set;
+ _imp->targets->add_child(s);
+ }
+ else
+ {
+ if (_imp->had_set_targets)
+ throw HadBothPackageAndSetTargets();
+
+ _imp->had_package_targets = true;
+ _imp->dep_list.options.target_type = dl_target_package;
+
+ if (std::string::npos != target.find('/'))
+ _imp->targets->add_child(PortageDepParser::parse(target));
+ else
+ _imp->targets->add_child(DepAtom::Pointer(new PackageDepAtom(
+ _imp->env->package_database()->fetch_unique_qualified_package_name(
+ PackageNamePart(target)))));
+ }
+
+ _imp->raw_targets.push_back(target);
+}
+
+namespace
+{
+ struct WorldCallbacks :
+ public Environment::WorldCallbacks
+ {
+ InstallTask * const t;
+
+ WorldCallbacks(InstallTask * const tt) :
+ t(tt)
+ {
+ }
+
+ virtual void add_callback(const PackageDepAtom * a)
+ {
+ t->on_update_world(*a);
+ }
+
+ virtual void skip_callback(const PackageDepAtom * a,
+ const std::string & s)
+ {
+ t->on_update_world_skip(*a, s);
+ }
+ };
+}
+
+void
+InstallTask::execute()
+{
+ Context context("When executing install task:");
+
+ /* build up our dep list */
+ on_build_deplist_pre();
+ _imp->dep_list.add(_imp->targets);
+ on_build_deplist_post();
+
+ /* we're about to display our task list */
+ if (_imp->pretend)
+ _imp->env->perform_hook(Hook("install_pretend_pre")("TARGETS", join(_imp->raw_targets.begin(),
+ _imp->raw_targets.end(), " ")));
+
+ on_display_merge_list_pre();
+
+ /* display our task list */
+ for (DepList::Iterator dep(_imp->dep_list.begin()), dep_end(_imp->dep_list.end()) ;
+ dep != dep_end ; ++dep)
+ {
+ _imp->current_dep_list_entry = dep;
+ on_display_merge_list_entry(*dep);
+ }
+
+ /* we're done displaying our task list */
+ on_display_merge_list_post();
+
+ if (_imp->pretend)
+ {
+ _imp->env->perform_hook(Hook("install_pretend_post")("TARGETS", join(
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " ")));
+ return;
+ }
+
+ /* we're about to fetch / install the entire list */
+ if (_imp->install_options.fetch_only)
+ {
+ _imp->env->perform_hook(Hook("fetch_all_pre")("TARGETS", join(
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " ")));
+ on_fetch_all_pre();
+ }
+ else
+ {
+ _imp->env->perform_hook(Hook("install_all_pre")("TARGETS", join(
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " ")));
+ on_install_all_pre();
+ }
+
+ /* fetch / install our entire list */
+ for (DepList::Iterator dep(_imp->dep_list.begin()), dep_end(_imp->dep_list.end()) ;
+ dep != dep_end ; ++dep)
+ {
+ if (dep->already_installed)
+ continue;
+ _imp->current_dep_list_entry = dep;
+
+ std::string cpvr(stringify(dep->package.name) + "-" +
+ stringify(dep->package.version) + "::" +
+ stringify(dep->package.repository));
+
+ /* we're about to fetch / install one item */
+ if (_imp->install_options.fetch_only)
+ {
+ _imp->env->perform_hook(Hook("fetch_pre")("TARGET", cpvr));
+ on_fetch_pre(*dep);
+ }
+ else
+ {
+ _imp->env->perform_hook(Hook("install_pre")("TARGET", cpvr));
+ on_install_pre(*dep);
+ }
+
+ /* fetch / install one item */
+ const RepositoryInstallableInterface * const installable_interface(
+ _imp->env->package_database()->fetch_repository(dep->package.repository)->
+ installable_interface);
+ if (! installable_interface)
+ throw InternalError(PALUDIS_HERE, "Trying to install from a non-installable repository");
+
+ try
+ {
+ installable_interface->install(dep->package.name, dep->package.version, _imp->install_options);
+ }
+ catch (const PackageInstallActionError & e)
+ {
+ _imp->env->perform_hook(Hook("install_fail")("TARGET", cpvr)("MESSAGE", e.message()));
+ throw;
+ }
+
+ /* we've fetched / installed one item */
+ if (_imp->install_options.fetch_only)
+ {
+ on_fetch_post(*dep);
+ _imp->env->perform_hook(Hook("fetch_post")("TARGET", cpvr));
+ }
+ else
+ {
+ on_install_post(*dep);
+ _imp->env->perform_hook(Hook("install_post")("TARGET", cpvr));
+ }
+
+ if (_imp->install_options.fetch_only)
+ continue;
+
+ /* figure out whether we need to unmerge (clean) anything */
+ on_build_cleanlist_pre(*dep);
+
+ // manually invalidate any installed repos, they're probably
+ // wrong now
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ if ((*r)->installed_interface)
+ (*r)->invalidate();
+
+ // look for packages with the same name in the same slot
+ PackageDatabaseEntryCollection::Pointer collision_list(_imp->env->package_database()->query(
+ PackageDepAtom::Pointer(new PackageDepAtom(
+ stringify(dep->package.name) + ":" +
+ stringify(dep->metadata->slot))),
+ is_installed_only));
+
+ // don't clean the thing we just installed
+ PackageDatabaseEntryCollection::Concrete clean_list;
+ for (PackageDatabaseEntryCollection::Iterator c(collision_list->begin()),
+ c_end(collision_list->end()) ; c != c_end ; ++c)
+ if (dep->package.version != c->version)
+ clean_list.insert(*c);
+
+ on_build_cleanlist_post(*dep);
+
+ /* ok, we have the cleanlist. we're about to clean */
+ _imp->env->perform_hook(Hook("uninstall_all_pre")("TARGETS", join(
+ clean_list.begin(), clean_list.end(), " ")));
+ on_clean_all_pre(*dep, clean_list);
+
+ for (PackageDatabaseEntryCollection::Iterator c(clean_list.begin()),
+ c_end(clean_list.end()) ; c != c_end ; ++c)
+ {
+ /* clean one item */
+ _imp->env->perform_hook(Hook("uninstall_pre")("TARGET", stringify(*c)));
+ on_clean_pre(*dep, *c);
+
+ const RepositoryUninstallableInterface * const uninstall_interface(
+ _imp->env->package_database()->fetch_repository(c->repository)->
+ uninstallable_interface);
+ if (! uninstall_interface)
+ throw InternalError(PALUDIS_HERE, "Trying to uninstall from a non-uninstallable repo");
+
+ try
+ {
+ uninstall_interface->uninstall(c->name, c->version, _imp->install_options);
+ }
+ catch (const PackageUninstallActionError & e)
+ {
+ _imp->env->perform_hook(Hook("uninstall_fail")("TARGET", stringify(*c))("MESSAGE", e.message()));
+ throw;
+ }
+
+ on_clean_post(*dep, *c);
+ _imp->env->perform_hook(Hook("uninstall_post")("TARGET", stringify(*c)));
+ }
+
+ /* we're done cleaning */
+ _imp->env->perform_hook(Hook("uninstall_all_post")("TARGETS", join(
+ clean_list.begin(), clean_list.end(), " ")));
+ on_clean_all_post(*dep, clean_list);
+ }
+
+ /* update world */
+ if ((! _imp->had_set_targets) && (! _imp->install_options.fetch_only))
+ {
+ if (! _imp->preserve_world)
+ {
+ on_update_world_pre();
+ WorldCallbacks w(this);
+ _imp->env->add_appropriate_to_world(_imp->targets, &w);
+ on_update_world_post();
+ }
+ else
+ on_preserve_world();
+ }
+
+ /* we've fetched / installed the entire list */
+ if (_imp->install_options.fetch_only)
+ {
+ on_fetch_all_post();
+ _imp->env->perform_hook(Hook("fetch_all_post")("TARGETS", join(
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " ")));
+ }
+ else
+ {
+ on_install_all_post();
+ _imp->env->perform_hook(Hook("install_all_post")("TARGETS", join(
+ _imp->raw_targets.begin(), _imp->raw_targets.end(), " ")));
+ }
+}
+
+const DepList &
+InstallTask::dep_list() const
+{
+ return _imp->dep_list;
+}
+
+DepList::Iterator
+InstallTask::current_dep_list_entry() const
+{
+ return _imp->current_dep_list_entry;
+}
+
+void
+InstallTask::set_no_config_protect(const bool value)
+{
+ _imp->install_options.no_config_protect = value;
+}
+
+void
+InstallTask::set_fetch_only(const bool value)
+{
+ _imp->install_options.fetch_only = value;
+}
+
+void
+InstallTask::set_pretend(const bool value)
+{
+ _imp->pretend = value;
+}
+
+void
+InstallTask::set_preserve_world(const bool value)
+{
+ _imp->preserve_world = value;
+}
+
diff --git a/0.8.0/paludis/tasks/install_task.hh b/0.8.0/paludis/tasks/install_task.hh
new file mode 100644
index 0000000..34a4cd3
--- /dev/null
+++ b/0.8.0/paludis/tasks/install_task.hh
@@ -0,0 +1,139 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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_PALUDIS_TASKS_INSTALL_TASK_HH
+#define PALUDIS_GUARD_PALUDIS_TASKS_INSTALL_TASK_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/dep_list.hh>
+
+namespace paludis
+{
+ class Environment;
+
+ class PALUDIS_VISIBLE MultipleSetTargetsSpecified :
+ public Exception
+ {
+ public:
+ MultipleSetTargetsSpecified() throw ();
+ };
+
+ class PALUDIS_VISIBLE HadBothPackageAndSetTargets :
+ public Exception
+ {
+ public:
+ HadBothPackageAndSetTargets() throw ();
+ };
+
+ class PALUDIS_VISIBLE InstallTask :
+ PrivateImplementationPattern<InstallTask>,
+ InstantiationPolicy<InstallTask, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ InstallTask(Environment * const env, const DepListOptions & options);
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~InstallTask();
+
+ ///\}
+
+ ///\name DepList and Install behaviour options
+ ///\{
+
+ void set_no_config_protect(const bool value);
+ void set_fetch_only(const bool value);
+ void set_pretend(const bool value);
+ void set_preserve_world(const bool value);
+
+ ///\}
+
+ ///\name Add targets
+ ///\{
+
+ void add_target(const std::string &);
+
+ ///\}
+
+ ///\name Event callbacks
+ ///\{
+
+ 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;
+
+ virtual void on_fetch_all_pre() = 0;
+ virtual void on_fetch_pre(const DepListEntry &) = 0;
+ virtual void on_fetch_post(const DepListEntry &) = 0;
+ virtual void on_fetch_all_post() = 0;
+
+ virtual void on_install_all_pre() = 0;
+ virtual void on_install_pre(const DepListEntry &) = 0;
+ virtual void on_install_post(const DepListEntry &) = 0;
+ virtual void on_install_all_post() = 0;
+
+ virtual void on_clean_all_pre(const DepListEntry &,
+ const PackageDatabaseEntryCollection &) = 0;
+ virtual void on_clean_pre(const DepListEntry &,
+ const PackageDatabaseEntry &) = 0;
+ virtual void on_clean_post(const DepListEntry &,
+ const PackageDatabaseEntry &) = 0;
+ virtual void on_clean_all_post(const DepListEntry &,
+ const PackageDatabaseEntryCollection &) = 0;
+
+ virtual void on_update_world_pre() = 0;
+ virtual void on_update_world(const PackageDepAtom &) = 0;
+ virtual void on_update_world_skip(const PackageDepAtom &, const std::string &) = 0;
+ virtual void on_update_world_post() = 0;
+ virtual void on_preserve_world() = 0;
+
+ ///\}
+
+ /**
+ * Run the task.
+ */
+ void execute();
+
+ /**
+ * Fetch our deplist.
+ */
+ const DepList & dep_list() const;
+
+ /**
+ * Fetch our current deplist entry.
+ */
+ DepList::Iterator current_dep_list_entry() const;
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/tasks/sync_task.cc b/0.8.0/paludis/tasks/sync_task.cc
new file mode 100644
index 0000000..f3f0a95
--- /dev/null
+++ b/0.8.0/paludis/tasks/sync_task.cc
@@ -0,0 +1,104 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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 "sync_task.hh"
+#include <paludis/environment.hh>
+#include <paludis/syncer.hh>
+#include <list>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<SyncTask> :
+ InternalCounted<Implementation<SyncTask> >
+ {
+ Environment * const env;
+ std::list<RepositoryName> targets;
+
+ Implementation(Environment * const e) :
+ env(e)
+ {
+ }
+ };
+}
+
+SyncTask::SyncTask(Environment * const env) :
+ PrivateImplementationPattern<SyncTask>(new Implementation<SyncTask>(env))
+{
+}
+
+SyncTask::~SyncTask()
+{
+}
+
+void
+SyncTask::add_target(const std::string & t)
+{
+ Context context("When adding sync target '" + t + "':");
+ _imp->targets.push_back(RepositoryName(t));
+}
+
+void
+SyncTask::execute()
+{
+ Context context("When executing sync task:");
+
+ if (_imp->targets.empty())
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ _imp->targets.push_back((*r)->name());
+
+ _imp->env->perform_hook(Hook("sync_all_pre")("TARGETS", join(_imp->targets.begin(),
+ _imp->targets.end(), " ")));
+ on_sync_all_pre();
+
+ for (std::list<RepositoryName>::const_iterator r(_imp->targets.begin()), r_end(_imp->targets.end()) ;
+ r != r_end ; ++r)
+ {
+ Context context_local("When syncing repository '" + stringify(*r) + "':");
+
+ _imp->env->perform_hook(Hook("sync_pre")("TARGET", stringify(*r)));
+ on_sync_pre(*r);
+
+ try
+ {
+ Repository::ConstPointer rr(_imp->env->package_database()->fetch_repository(*r));
+
+ if (rr->syncable_interface && rr->syncable_interface->sync())
+ on_sync_succeed(*r);
+ else
+ on_sync_skip(*r);
+ }
+ catch (const SyncFailedError & e)
+ {
+ _imp->env->perform_hook(Hook("sync_fail")("TARGET", stringify(*r)));
+ on_sync_fail(*r, e);
+ }
+
+ on_sync_post(*r);
+ _imp->env->perform_hook(Hook("sync_post")("TARGET", stringify(*r)));
+ }
+
+ on_sync_all_post();
+ _imp->env->perform_hook(Hook("sync_all_post")("TARGETS", join(_imp->targets.begin(),
+ _imp->targets.end(), " ")));
+}
+
diff --git a/0.8.0/paludis/tasks/sync_task.hh b/0.8.0/paludis/tasks/sync_task.hh
new file mode 100644
index 0000000..baedfd7
--- /dev/null
+++ b/0.8.0/paludis/tasks/sync_task.hh
@@ -0,0 +1,79 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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_PALUDIS_TASKS_SYNC_TASK_HH
+#define PALUDIS_GUARD_PALUDIS_TASKS_SYNC_TASK_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/dep_list.hh>
+
+namespace paludis
+{
+ class Environment;
+ class SyncFailedError;
+
+ class PALUDIS_VISIBLE SyncTask :
+ PrivateImplementationPattern<SyncTask>,
+ InstantiationPolicy<SyncTask, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ SyncTask(Environment * const env);
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~SyncTask();
+
+ ///\}
+
+ ///\name Add targets
+ ///\{
+
+ void add_target(const std::string &);
+
+ ///\}
+
+ ///\name Event callbacks
+ ///\{
+
+ virtual void on_sync_all_pre() = 0;
+ virtual void on_sync_pre(const RepositoryName &) = 0;
+ virtual void on_sync_post(const RepositoryName &) = 0;
+ virtual void on_sync_skip(const RepositoryName &) = 0;
+ virtual void on_sync_fail(const RepositoryName &, const SyncFailedError &) = 0;
+ virtual void on_sync_succeed(const RepositoryName &) = 0;
+ virtual void on_sync_all_post() = 0;
+
+ ///\}
+
+ /**
+ * Run the task.
+ */
+ void execute();
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/tasks/uninstall_task.cc b/0.8.0/paludis/tasks/uninstall_task.cc
new file mode 100644
index 0000000..6770c75
--- /dev/null
+++ b/0.8.0/paludis/tasks/uninstall_task.cc
@@ -0,0 +1,206 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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 "uninstall_task.hh"
+#include <paludis/environment.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <list>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<UninstallTask> :
+ InternalCounted<Implementation<UninstallTask> >
+ {
+ Environment * const env;
+ InstallOptions install_options;
+
+ std::list<std::string> raw_targets;
+ std::list<PackageDepAtom::Pointer> targets;
+
+ bool pretend;
+ bool preserve_world;
+
+ Implementation<UninstallTask>(Environment * const e) :
+ env(e),
+ install_options(false, false),
+ pretend(false),
+ preserve_world(false)
+ {
+ }
+ };
+}
+
+UninstallTask::UninstallTask(Environment * const e) :
+ PrivateImplementationPattern<UninstallTask>(new Implementation<UninstallTask>(e))
+{
+}
+
+UninstallTask::~UninstallTask()
+{
+}
+
+void
+UninstallTask::set_pretend(const bool v)
+{
+ _imp->pretend = v;
+}
+
+void
+UninstallTask::set_no_config_protect(const bool v)
+{
+ _imp->install_options.no_config_protect = v;
+}
+
+void
+UninstallTask::set_preserve_world(const bool v)
+{
+ _imp->preserve_world = v;
+}
+
+void
+UninstallTask::add_target(const std::string & target)
+{
+ Context context("When adding uninstall target '" + target + "':");
+
+ /* we might have a dep atom, but we might just have a simple package name
+ * without a category. either should work. */
+ if (std::string::npos != target.find('/'))
+ _imp->targets.push_back(PackageDepAtom::Pointer(new PackageDepAtom(target)));
+ else
+ _imp->targets.push_back(PackageDepAtom::Pointer(new PackageDepAtom(
+ _imp->env->package_database()->fetch_unique_qualified_package_name(
+ PackageNamePart(target)))));
+
+ _imp->raw_targets.push_back(target);
+}
+
+namespace
+{
+ struct WorldCallbacks :
+ public Environment::WorldCallbacks
+ {
+ UninstallTask * const t;
+
+ WorldCallbacks(UninstallTask * const tt) :
+ t(tt)
+ {
+ }
+
+ virtual void remove_callback(const PackageDepAtom * a)
+ {
+ t->on_update_world(*a);
+ }
+ };
+}
+
+void
+UninstallTask::execute()
+{
+ Context context("When executing install task:");
+
+ on_build_unmergelist_pre();
+
+ PackageDatabaseEntryCollection::Pointer unmerge(new PackageDatabaseEntryCollection::Concrete);
+ for (std::list<PackageDepAtom::Pointer>::const_iterator t(_imp->targets.begin()),
+ t_end(_imp->targets.end()) ; t != t_end ; ++t)
+ {
+ PackageDatabaseEntryCollection::ConstPointer r(_imp->env->package_database()->query(
+ *t, is_installed_only));
+ if (r->empty())
+ throw NoSuchPackageError(stringify(**t));
+ else if (r->size() > 1)
+ throw AmbiguousUnmergeTargetError(stringify(**t), r);
+ else
+ unmerge->insert(*r->begin());
+ }
+
+ on_build_unmergelist_post();
+
+ on_display_unmerge_list_pre();
+
+ for (PackageDatabaseEntryCollection::Iterator i(unmerge->begin()),
+ i_end(unmerge->end()) ; i != i_end ; ++i)
+ on_display_unmerge_list_entry(*i);
+
+ on_display_unmerge_list_post();
+
+ if (_imp->pretend)
+ return;
+
+ if (_imp->preserve_world)
+ on_preserve_world();
+ else
+ {
+ on_update_world_pre();
+
+ AllDepAtom::Pointer all(new AllDepAtom);
+ for (std::list<PackageDepAtom::Pointer>::const_iterator t(_imp->targets.begin()),
+ t_end(_imp->targets.end()) ; t != t_end ; ++t)
+ all->add_child(*t);
+
+ WorldCallbacks w(this);
+ _imp->env->remove_appropriate_from_world(all, &w);
+
+ on_update_world_post();
+ }
+
+ _imp->env->perform_hook(Hook("uninstall_all_pre")("TARGETS", join(unmerge->begin(), unmerge->end(), " ")));
+ on_uninstall_all_pre();
+
+ for (PackageDatabaseEntryCollection::Iterator i(unmerge->begin()),
+ i_end(unmerge->end()) ; i != i_end ; ++i)
+ {
+ std::string cpvr(stringify(i->name) + "-" +
+ stringify(i->version) + "::" +
+ stringify(i->repository));
+
+ _imp->env->perform_hook(Hook("uninstall_pre")("TARGET", cpvr));
+ on_uninstall_pre(*i);
+
+ const RepositoryUninstallableInterface * const uninstall_interface(
+ _imp->env->package_database()->fetch_repository(i->repository)->
+ uninstallable_interface);
+ if (! uninstall_interface)
+ throw InternalError(PALUDIS_HERE, "Trying to uninstall from a non-uninstallable repo");
+
+ try
+ {
+ uninstall_interface->uninstall(i->name, i->version, _imp->install_options);
+ }
+ catch (const PackageUninstallActionError & e)
+ {
+ _imp->env->perform_hook(Hook("uninstall_fail")("TARGET", cpvr)("MESSAGE", e.message()));
+ throw;
+ }
+
+ on_uninstall_post(*i);
+ _imp->env->perform_hook(Hook("uninstall_post")("TARGET", cpvr));
+ }
+
+ on_uninstall_all_post();
+ _imp->env->perform_hook(Hook("uninstall_all_post")("TARGETS", join(unmerge->begin(), unmerge->end(), " ")));
+}
+
+AmbiguousUnmergeTargetError::~AmbiguousUnmergeTargetError() throw ()
+{
+}
+
diff --git a/0.8.0/paludis/tasks/uninstall_task.hh b/0.8.0/paludis/tasks/uninstall_task.hh
new file mode 100644
index 0000000..5820bca
--- /dev/null
+++ b/0.8.0/paludis/tasks/uninstall_task.hh
@@ -0,0 +1,133 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * 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_PALUDIS_TASKS_UNINSTALL_TASK_HH
+#define PALUDIS_GUARD_PALUDIS_TASKS_UNINSTALL_TASK_HH 1
+
+#include <paludis/dep_atom.hh>
+#include <paludis/package_database_entry.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+namespace paludis
+{
+ class Environment;
+
+ class PALUDIS_VISIBLE AmbiguousUnmergeTargetError :
+ public Exception
+ {
+ private:
+ const std::string _t;
+ const PackageDatabaseEntryCollection::ConstPointer _p;
+
+ public:
+ AmbiguousUnmergeTargetError(const std::string & our_target,
+ const PackageDatabaseEntryCollection::ConstPointer matches) throw () :
+ Exception("Ambiguous unmerge target '" + our_target + "'"),
+ _t(our_target),
+ _p(matches)
+ {
+ }
+
+ ~AmbiguousUnmergeTargetError() throw ();
+
+ typedef PackageDatabaseEntryCollection::Iterator Iterator;
+
+ Iterator begin() const
+ {
+ return _p->begin();
+ }
+
+ Iterator end() const
+ {
+ return _p->end();
+ }
+
+ const std::string & target() const
+ {
+ return _t;
+ }
+ };
+
+ class PALUDIS_VISIBLE UninstallTask :
+ PrivateImplementationPattern<UninstallTask>,
+ InstantiationPolicy<UninstallTask, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ UninstallTask(Environment * const env);
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~UninstallTask();
+
+ ///\}
+
+ ///\name Behaviour options
+ ///\{
+
+ void set_no_config_protect(const bool value);
+ void set_pretend(const bool value);
+ void set_preserve_world(const bool value);
+
+ ///\}
+
+ ///\name Add targets
+ ///\{
+
+ void add_target(const std::string &);
+
+ ///\}
+
+ ///\name Event callbacks
+ ///\{
+
+ virtual void on_build_unmergelist_pre() = 0;
+ virtual void on_build_unmergelist_post() = 0;
+
+ virtual void on_display_unmerge_list_pre() = 0;
+ virtual void on_display_unmerge_list_post() = 0;
+ virtual void on_display_unmerge_list_entry(const PackageDatabaseEntry &) = 0;
+
+ virtual void on_uninstall_all_pre() = 0;
+ virtual void on_uninstall_pre(const PackageDatabaseEntry &) = 0;
+ virtual void on_uninstall_post(const PackageDatabaseEntry &) = 0;
+ virtual void on_uninstall_all_post() = 0;
+
+ virtual void on_update_world_pre() = 0;
+ virtual void on_update_world(const PackageDepAtom &) = 0;
+ virtual void on_update_world_post() = 0;
+ virtual void on_preserve_world() = 0;
+
+ ///\}
+
+ /**
+ * Run the task.
+ */
+ void execute();
+ };
+}
+
+#endif