aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-02-04 06:34:17 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-02-04 06:34:17 +0000
commit3a1fb9dce16fd93cb16dffe3ec6d237e68386c7d (patch)
tree5f510e92a38157d1b65b24fb53e5ca131c909daf
parent959b3533b6b24ceb6056d4de58b7c37a90deb4b0 (diff)
downloadpaludis-3a1fb9dce16fd93cb16dffe3ec6d237e68386c7d.tar.gz
paludis-3a1fb9dce16fd93cb16dffe3ec6d237e68386c7d.tar.xz
Allow uninstalling of sets. Fixes: ticket:20, ticket:21.
-rw-r--r--doc/sets.html.skel5
-rw-r--r--paludis/environment.cc8
-rw-r--r--paludis/tasks/Makefile.am6
-rw-r--r--paludis/tasks/exceptions.hh52
-rw-r--r--paludis/tasks/install_task.cc40
-rw-r--r--paludis/tasks/install_task.hh24
-rw-r--r--paludis/tasks/uninstall_task.cc75
-rw-r--r--paludis/tasks/uninstall_task.hh1
-rw-r--r--src/clients/gtkpaludis/queue_list.cc1
-rw-r--r--src/clients/paludis/install.cc1
-rw-r--r--src/clients/paludis/uninstall.cc28
11 files changed, 185 insertions, 56 deletions
diff --git a/doc/sets.html.skel b/doc/sets.html.skel
index 600471e..99bee85 100644
--- a/doc/sets.html.skel
+++ b/doc/sets.html.skel
@@ -74,8 +74,9 @@ user defined sets above.</p>
<h3>Using Sets</h3>
-<p>Sets can currently be used as targets for <code>paludis --query</code> and
-<code>paludis --install</code>. They can also be used as the atom column in the
+<p>Sets can currently be used as targets for <code>paludis --query</code>,
+<code>paludis --install</code> and <code>paludis --uninstall</code>.
+They can also be used as the atom column in the
<code>use.conf</code>, <code>keywords.conf</code>, <code>licenses.conf</code>,
<code>package_mask.conf</code> and <code>package_unmask.conf</code>.</p>
diff --git a/paludis/environment.cc b/paludis/environment.cc
index c11992b..fedaa46 100644
--- a/paludis/environment.cc
+++ b/paludis/environment.cc
@@ -365,9 +365,11 @@ Environment::add_set_to_world(const SetName & s, Environment::WorldCallbacks * w
for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
r_end(package_database()->end_repositories()) ;
r != r_end ; ++r)
- if ((*r)->world_interface && (*r)->sets_interface)
- if ((*r)->sets_interface->package_set(s))
- (*r)->world_interface->add_to_world(s);
+ if ((*r)->world_interface)
+ (*r)->world_interface->add_to_world(s);
+
+ if (ww)
+ ww->add_callback(s);
}
void
diff --git a/paludis/tasks/Makefile.am b/paludis/tasks/Makefile.am
index 0bda44a..48c7723 100644
--- a/paludis/tasks/Makefile.am
+++ b/paludis/tasks/Makefile.am
@@ -28,7 +28,8 @@ paludis_tasks_include_HEADERS = \
sync_task.hh \
stage_builder_task.hh \
stage_options-sr.hh \
- report_task.hh
+ report_task.hh \
+ exceptions.hh
libpaludistasks_a_SOURCES = $(paludis_tasks_include_HEADERS) \
find_unused_packages_task.cc \
@@ -36,7 +37,8 @@ libpaludistasks_a_SOURCES = $(paludis_tasks_include_HEADERS) \
uninstall_task.cc \
sync_task.cc \
stage_builder_task.cc \
- report_task.cc
+ report_task.cc \
+ exceptions.cc
if ! MONOLITHIC
diff --git a/paludis/tasks/exceptions.hh b/paludis/tasks/exceptions.hh
new file mode 100644
index 0000000..e277c04
--- /dev/null
+++ b/paludis/tasks/exceptions.hh
@@ -0,0 +1,52 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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_EXCEPTIONS_HH
+#define PALUDIS_GUARD_PALUDIS_TASKS_EXCEPTIONS_HH 1
+
+#include <paludis/util/exception.hh>
+
+namespace paludis
+{
+ /**
+ * Thrown if multiple set targets are specified.
+ *
+ * \ingroup grpexceptions
+ */
+ class PALUDIS_VISIBLE MultipleSetTargetsSpecified :
+ public Exception
+ {
+ public:
+ MultipleSetTargetsSpecified() throw ();
+ };
+
+ /**
+ * Thrown if both sets and packages are specified as targets.
+ *
+ * \ingroup grpexceptions
+ */
+ class PALUDIS_VISIBLE HadBothPackageAndSetTargets :
+ public Exception
+ {
+ public:
+ HadBothPackageAndSetTargets() throw ();
+ };
+}
+
+#endif
diff --git a/paludis/tasks/install_task.cc b/paludis/tasks/install_task.cc
index 26c8ef5..8c3bb57 100644
--- a/paludis/tasks/install_task.cc
+++ b/paludis/tasks/install_task.cc
@@ -21,6 +21,8 @@
#include <paludis/dep_atom.hh>
#include <paludis/portage_dep_parser.hh>
#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/tasks/exceptions.hh>
#include <list>
using namespace paludis;
@@ -37,7 +39,7 @@ namespace paludis
std::list<std::string> raw_targets;
std::tr1::shared_ptr<AllDepAtom> targets;
- std::tr1::shared_ptr<const DepAtom> add_to_world_atom;
+ std::tr1::shared_ptr<std::string> add_to_world_atom;
bool pretend;
bool preserve_world;
@@ -60,16 +62,6 @@ namespace paludis
};
}
-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))
{
@@ -388,16 +380,29 @@ InstallTask::execute()
}
/* update world */
- if ((! _imp->had_set_targets) && (! _imp->install_options.fetch_only))
+ if (! _imp->install_options.fetch_only)
{
if (! _imp->preserve_world)
{
on_update_world_pre();
WorldCallbacks w(this);
- if (_imp->add_to_world_atom)
- _imp->env->add_appropriate_to_world(_imp->add_to_world_atom, &w);
- else
- _imp->env->add_appropriate_to_world(_imp->targets, &w);
+
+ if (_imp->had_package_targets)
+ {
+ if (_imp->add_to_world_atom)
+ _imp->env->add_appropriate_to_world(PortageDepParser::parse_depend(
+ *_imp->add_to_world_atom), &w);
+ else
+ _imp->env->add_appropriate_to_world(_imp->targets, &w);
+ }
+ else if (_imp->had_set_targets)
+ {
+ if (_imp->add_to_world_atom)
+ _imp->env->add_set_to_world(SetName(*_imp->add_to_world_atom), &w);
+ else if (! _imp->raw_targets.empty())
+ _imp->env->add_set_to_world(SetName(*_imp->raw_targets.begin()), &w);
+ }
+
on_update_world_post();
}
else
@@ -464,8 +469,7 @@ InstallTask::set_debug_mode(const InstallDebugOption value)
void
InstallTask::set_add_to_world_atom(const std::string & value)
{
- Context context("When setting world atom to '" + value + "':");
- _imp->add_to_world_atom = PortageDepParser::parse_depend(value);
+ _imp->add_to_world_atom.reset(new std::string(value));
}
InstallTask::TargetsIterator
diff --git a/paludis/tasks/install_task.hh b/paludis/tasks/install_task.hh
index 766fded..77f39c6 100644
--- a/paludis/tasks/install_task.hh
+++ b/paludis/tasks/install_task.hh
@@ -30,30 +30,6 @@ namespace paludis
class Environment;
/**
- * Thrown if multiple set targets are specified.
- *
- * \ingroup grpexceptions
- */
- class PALUDIS_VISIBLE MultipleSetTargetsSpecified :
- public Exception
- {
- public:
- MultipleSetTargetsSpecified() throw ();
- };
-
- /**
- * Thrown if both sets and packages are specified as targets.
- *
- * \ingroup grpexceptions
- */
- class PALUDIS_VISIBLE HadBothPackageAndSetTargets :
- public Exception
- {
- public:
- HadBothPackageAndSetTargets() throw ();
- };
-
- /**
* Task used to install one or more targets.
*
* \ingroup grptasks
diff --git a/paludis/tasks/uninstall_task.cc b/paludis/tasks/uninstall_task.cc
index d5a9e4d..97d7763 100644
--- a/paludis/tasks/uninstall_task.cc
+++ b/paludis/tasks/uninstall_task.cc
@@ -20,7 +20,9 @@
#include "uninstall_task.hh"
#include <paludis/environment.hh>
#include <paludis/dep_list/uninstall_list.hh>
+#include <paludis/dep_atom_flattener.hh>
#include <paludis/util/collection_concrete.hh>
+#include <paludis/tasks/exceptions.hh>
#include <list>
using namespace paludis;
@@ -43,6 +45,9 @@ namespace paludis
bool with_dependencies;
bool unused;
+ bool had_set_targets;
+ bool had_package_targets;
+
Implementation<UninstallTask>(Environment * const e) :
env(e),
install_options(false, false, ido_none, false),
@@ -51,7 +56,9 @@ namespace paludis
all_versions(false),
with_unused_dependencies(false),
with_dependencies(false),
- unused(false)
+ unused(false),
+ had_set_targets(false),
+ had_package_targets(false)
{
}
};
@@ -92,11 +99,52 @@ UninstallTask::add_target(const std::string & 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('/'))
+ {
+ if (_imp->had_set_targets)
+ throw HadBothPackageAndSetTargets();
+
+ _imp->had_package_targets = true;
_imp->targets.push_back(std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom(target)));
+ }
else
- _imp->targets.push_back(std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom(
- _imp->env->package_database()->fetch_unique_qualified_package_name(
- PackageNamePart(target)))));
+ try
+ {
+ std::tr1::shared_ptr<DepAtom> atom(_imp->env->package_set(SetName(target)));
+ if (atom)
+ {
+ if (_imp->had_package_targets)
+ throw HadBothPackageAndSetTargets();
+
+ if (_imp->had_set_targets)
+ throw MultipleSetTargetsSpecified();
+
+ _imp->had_set_targets = true;
+ DepAtomFlattener f(_imp->env, 0, atom);
+ for (DepAtomFlattener::Iterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
+ _imp->targets.push_back(std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom(
+ stringify((*i)->text()))));
+ }
+ else
+ {
+ if (_imp->had_set_targets)
+ throw HadBothPackageAndSetTargets();
+
+ _imp->had_package_targets = false;
+ _imp->targets.push_back(std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom(
+ _imp->env->package_database()->fetch_unique_qualified_package_name(
+ PackageNamePart(target)))));
+ }
+ }
+ catch (const SetNameError &)
+ {
+ if (_imp->had_set_targets)
+ throw HadBothPackageAndSetTargets();
+
+ _imp->had_package_targets = false;
+ _imp->targets.push_back(std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom(
+ _imp->env->package_database()->fetch_unique_qualified_package_name(
+ PackageNamePart(target)))));
+ }
_imp->raw_targets.push_back(target);
@@ -126,9 +174,14 @@ namespace
{
}
- virtual void remove_callback(const PackageDepAtom * a)
+ virtual void remove_callback(const PackageDepAtom & a)
{
- t->on_update_world(*a);
+ t->on_update_world(a);
+ }
+
+ virtual void remove_callback(const SetName & a)
+ {
+ t->on_update_world(a);
}
};
}
@@ -155,7 +208,10 @@ UninstallTask::execute()
std::tr1::shared_ptr<const PackageDatabaseEntryCollection> r(_imp->env->package_database()->query(
**t, is_installed_only, qo_order_by_version));
if (r->empty())
- throw NoSuchPackageError(stringify(**t));
+ {
+ if (! _imp->had_set_targets)
+ throw NoSuchPackageError(stringify(**t));
+ }
else if (next(r->begin()) != r->end())
{
if (_imp->all_versions)
@@ -221,6 +277,11 @@ UninstallTask::execute()
WorldCallbacks w(this);
_imp->env->remove_appropriate_from_world(all, &w);
+ if (_imp->had_set_targets)
+ for (std::list<std::string>::const_iterator t(_imp->raw_targets.begin()),
+ t_end(_imp->raw_targets.end()) ; t != t_end ; ++t)
+ _imp->env->remove_set_from_world(SetName(*t), &w);
+
on_update_world_post();
}
diff --git a/paludis/tasks/uninstall_task.hh b/paludis/tasks/uninstall_task.hh
index e530462..594ebd5 100644
--- a/paludis/tasks/uninstall_task.hh
+++ b/paludis/tasks/uninstall_task.hh
@@ -147,6 +147,7 @@ namespace paludis
virtual void on_update_world_pre() = 0;
virtual void on_update_world(const PackageDepAtom &) = 0;
+ virtual void on_update_world(const SetName &) = 0;
virtual void on_update_world_post() = 0;
virtual void on_preserve_world() = 0;
diff --git a/src/clients/gtkpaludis/queue_list.cc b/src/clients/gtkpaludis/queue_list.cc
index 85f1849..630ecc5 100644
--- a/src/clients/gtkpaludis/queue_list.cc
+++ b/src/clients/gtkpaludis/queue_list.cc
@@ -30,6 +30,7 @@
#include <paludis/util/stringify.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/log.hh>
+#include <paludis/tasks/exceptions.hh>
#include <paludis/environment/default/default_environment.hh>
#include <list>
diff --git a/src/clients/paludis/install.cc b/src/clients/paludis/install.cc
index c8825e6..5cd77ca 100644
--- a/src/clients/paludis/install.cc
+++ b/src/clients/paludis/install.cc
@@ -37,6 +37,7 @@
#include <errno.h>
#include <paludis/tasks/install_task.hh>
+#include <paludis/tasks/exceptions.hh>
#include <paludis/util/fd_output_stream.hh>
#include <paludis/util/log.hh>
#include <paludis/util/tokeniser.hh>
diff --git a/src/clients/paludis/uninstall.cc b/src/clients/paludis/uninstall.cc
index 9441e4a..3f29efd 100644
--- a/src/clients/paludis/uninstall.cc
+++ b/src/clients/paludis/uninstall.cc
@@ -22,6 +22,7 @@
#include <paludis/environment/default/default_environment.hh>
#include <paludis/tasks/uninstall_task.hh>
+#include <paludis/tasks/exceptions.hh>
#include <paludis/dep_list/uninstall_list.hh>
#include <iostream>
@@ -156,6 +157,11 @@ namespace
cout << "* removing " << colour(cl_package_name, a.package()) << endl;
}
+ virtual void on_update_world(const SetName & a)
+ {
+ cout << "* removing " << colour(cl_package_name, a) << endl;
+ }
+
virtual void on_update_world_post()
{
cout << endl;
@@ -209,6 +215,8 @@ namespace
o_end(e.end()) ; o != o_end ; ++o)
cerr << " * =" << colour(cl_package_name, *o) << endl;
cerr << endl;
+ cerr << "Consider using --all-versions if appropriate." << endl;
+ cerr << endl;
return 1;
}
catch (const PackageUninstallActionError & e)
@@ -220,6 +228,26 @@ namespace
return_code |= 1;
}
+ catch (const HadBothPackageAndSetTargets &)
+ {
+ cout << endl;
+ cerr << "Error: both package sets and packages were specified." << endl;
+ cerr << endl;
+ cerr << "Package sets (like 'system' and 'world') cannot be uninstalled at the same time" << endl;
+ cerr << "as ordinary packages." << endl;
+
+ return_code |= 1;
+ }
+ catch (const MultipleSetTargetsSpecified &)
+ {
+ cout << endl;
+ cerr << "Error: multiple package sets were specified." << endl;
+ cerr << endl;
+ cerr << "Package sets (like 'system' and 'world') must be uninstalled individually," << endl;
+ cerr << "without any other sets or packages." << endl;
+
+ return_code |= 1;
+ }
catch (const NoSuchPackageError & e)
{
cout << endl;