aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-18 11:28:11 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-18 11:28:11 +0100
commit5f73749a5fd82645c897e7f86d9e923b802852ce (patch)
tree90a3f46255753d1ce3c0d6eeeecdd6fc4030c82a
parentb584bf5adb0f3eefb2a2f176f390db2b00befd87 (diff)
downloadpaludis-5f73749a5fd82645c897e7f86d9e923b802852ce.tar.gz
paludis-5f73749a5fd82645c897e7f86d9e923b802852ce.tar.xz
cave uninstall wildcards
Fixes: ticket:921
-rw-r--r--src/clients/cave/cmd_uninstall.cc66
1 files changed, 47 insertions, 19 deletions
diff --git a/src/clients/cave/cmd_uninstall.cc b/src/clients/cave/cmd_uninstall.cc
index 6e86f17..9d9bc31 100644
--- a/src/clients/cave/cmd_uninstall.cc
+++ b/src/clients/cave/cmd_uninstall.cc
@@ -25,6 +25,7 @@
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/wrapped_output_iterator.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/selection.hh>
#include <paludis/generator.hh>
@@ -35,6 +36,7 @@
#include <paludis/metadata_key.hh>
#include <iostream>
+#include <set>
#include <cstdlib>
using namespace paludis;
@@ -86,6 +88,20 @@ namespace
"the same as 'cave resolve !foo'.";
}
};
+
+ bool has_multiple_versions(const std::tr1::shared_ptr<const PackageIDSequence> & ids)
+ {
+ QualifiedPackageName old_qpn("x/x");
+ for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ if ((*i)->name() == old_qpn)
+ return true;
+ old_qpn = (*i)->name();
+ }
+
+ return false;
+ }
}
bool
@@ -114,46 +130,58 @@ UninstallCommand::run(
std::tr1::shared_ptr<Sequence<std::pair<std::string, std::string> > > targets(new Sequence<std::pair<std::string, std::string> >);
std::tr1::shared_ptr<Sequence<std::string> > targets_cleaned_up(new Sequence<std::string>);
+
+ std::set<QualifiedPackageName> qpns_being_changed;
+ std::tr1::shared_ptr<PackageIDSequence> ids_going_away(new PackageIDSequence);
+
for (UninstallCommandLine::ParametersConstIterator p(cmdline.begin_parameters()), p_end(cmdline.end_parameters()) ;
p != p_end ; ++p)
{
- PackageDepSpec spec(parse_user_package_dep_spec(*p, env.get(), UserPackageDepSpecOptions()));
+ PackageDepSpec spec(parse_user_package_dep_spec(*p, env.get(), UserPackageDepSpecOptions() + updso_allow_wildcards));
const std::tr1::shared_ptr<const PackageIDSequence> ids((*env)[selection::AllVersionsSorted(
generator::Matches(spec, MatchPackageOptions()) | filter::SupportsAction<UninstallAction>())]);
if (ids->empty())
throw NothingMatching(spec);
- else if (1 != std::distance(ids->begin(), ids->end()) && ! cmdline.a_all_versions.specified())
+ else if ((! cmdline.a_all_versions.specified()) && has_multiple_versions(ids))
throw BeMoreSpecific(spec, ids);
else
{
for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
i != i_end ; ++i)
{
+ qpns_being_changed.insert((*i)->name());
std::string target("!" + stringify((*i)->name()));
if ((*i)->slot_key())
target.append(":" + stringify((*i)->slot_key()->value()));
targets->push_back(std::make_pair(target, ""));
}
- bool removing_all_slots(true);
- const std::tr1::shared_ptr<const PackageIDSequence> all_uninstallable((*env)[selection::AllVersionsSorted(
- generator::Package(*spec.package_ptr()) | filter::SupportsAction<UninstallAction>())]);
- for (PackageIDSequence::ConstIterator i(all_uninstallable->begin()), i_end(all_uninstallable->end()) ;
- i != i_end ; ++i)
- if (indirect_iterator(ids->end()) == std::find(indirect_iterator(ids->begin()), indirect_iterator(ids->end()), **i))
- {
- removing_all_slots = false;
- break;
- }
-
- if (removing_all_slots)
- targets_cleaned_up->push_back("!" + stringify((*ids->begin())->name()));
- else
+ std::copy(ids->begin(), ids->end(), ids_going_away->back_inserter());
+ }
+ }
+
+ for (std::set<QualifiedPackageName>::const_iterator q(qpns_being_changed.begin()), q_end(qpns_being_changed.end()) ;
+ q != q_end ; ++q)
+ {
+ bool removing_all_slots(true);
+ const std::tr1::shared_ptr<const PackageIDSequence> all_uninstallable((*env)[selection::AllVersionsSorted(
+ generator::Package(*q) | filter::SupportsAction<UninstallAction>())]);
+ for (PackageIDSequence::ConstIterator i(all_uninstallable->begin()), i_end(all_uninstallable->end()) ;
+ i != i_end ; ++i)
+ if (indirect_iterator(ids_going_away->end()) == std::find(
+ indirect_iterator(ids_going_away->begin()), indirect_iterator(ids_going_away->end()), **i))
{
- for (Sequence<std::pair<std::string, std::string> >::ConstIterator t(targets->begin()), t_end(targets->end()) ;
- t != t_end ; ++t)
- targets_cleaned_up->push_back(t->first);
+ removing_all_slots = false;
+ break;
}
+
+ if (removing_all_slots)
+ targets_cleaned_up->push_back("!" + stringify(*q));
+ else
+ {
+ for (Sequence<std::pair<std::string, std::string> >::ConstIterator t(targets->begin()), t_end(targets->end()) ;
+ t != t_end ; ++t)
+ targets_cleaned_up->push_back(t->first);
}
}