aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2007-06-05 20:00:41 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2007-06-05 20:00:41 +0000
commit41e6de161a3701068edf7373e4869da494db1ee3 (patch)
treee838832d0cdc8bf896a8b990969a30725295cd21
parent66b1c876c09833a4dd57d2be968a9acb1052e068 (diff)
downloadpaludis-41e6de161a3701068edf7373e4869da494db1ee3.tar.gz
paludis-41e6de161a3701068edf7373e4869da494db1ee3.tar.xz
Add TargetDepTag and extra members to DependencyDepTag. Indicate which dependents are really pulling in a new package, versus which are satisfied by the currently installed version.
-rw-r--r--paludis/dep_list/Makefile.am4
-rw-r--r--paludis/dep_list/condition_tracker.cc131
-rw-r--r--paludis/dep_list/condition_tracker.hh68
-rw-r--r--paludis/dep_list/dep_list.cc76
-rw-r--r--paludis/dep_list/dep_list.hh9
-rw-r--r--paludis/dep_list/dep_list_TEST.cc111
-rw-r--r--paludis/dep_list/show_suggest_visitor.cc38
-rw-r--r--paludis/dep_list/show_suggest_visitor.hh6
-rw-r--r--paludis/dep_list/uninstall_list.cc88
-rw-r--r--paludis/dep_list/uninstall_list.hh4
-rw-r--r--paludis/dep_tag-fwd.hh1
-rw-r--r--paludis/dep_tag.cc96
-rw-r--r--paludis/dep_tag.hh59
-rw-r--r--paludis/portage_dep_parser.cc96
-rw-r--r--paludis/tasks/install_task.cc13
-rw-r--r--paludis/tasks/uninstall_task.cc16
-rw-r--r--ruby/dep_tag.cc59
-rw-r--r--ruby/dep_tag_TEST.rb36
-rw-r--r--src/output/console_install_task.cc37
-rw-r--r--src/output/console_install_task.hh2
20 files changed, 785 insertions, 165 deletions
diff --git a/paludis/dep_list/Makefile.am b/paludis/dep_list/Makefile.am
index a119515..959e380 100644
--- a/paludis/dep_list/Makefile.am
+++ b/paludis/dep_list/Makefile.am
@@ -19,6 +19,7 @@ paludis_dep_list_include_HEADERS = \
query_visitor.hh \
show_suggest_visitor.hh \
uninstall_list.hh \
+ condition_tracker.hh \
exceptions.hh \
options.hh \
dep_list-sr.hh \
@@ -34,7 +35,8 @@ libpaludisdeplist_la_SOURCES = \
uninstall_list.cc uninstall_list.hh \
range_rewriter.cc range_rewriter.hh \
query_visitor.cc query_visitor.hh \
- show_suggest_visitor.cc show_suggest_visitor.hh
+ show_suggest_visitor.cc show_suggest_visitor.hh \
+ condition_tracker.cc condition_tracker.hh
libpaludisdeplist_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
diff --git a/paludis/dep_list/condition_tracker.cc b/paludis/dep_list/condition_tracker.cc
new file mode 100644
index 0000000..887b499
--- /dev/null
+++ b/paludis/dep_list/condition_tracker.cc
@@ -0,0 +1,131 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 David Leverton <levertond@googlemail.com>
+ *
+ * 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 <paludis/dep_list/condition_tracker.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/dep_spec.hh>
+
+using namespace paludis;
+using namespace tr1::placeholders;
+
+ConditionTracker::ConditionTracker(
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions) :
+ base(new ConstTreeSequence<DependencySpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec))),
+ adder(tr1::bind(&ConstTreeSequence<DependencySpecTree, AllDepSpec>::add, base, _1))
+{
+ conditions->accept(*this);
+}
+
+ConditionTracker::~ConditionTracker()
+{
+}
+
+template <typename T_>
+tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >
+ConditionTracker::do_add_sequence(const T_ & node)
+{
+ adder(tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, T_> >(
+ new ConstTreeSequence<DependencySpecTree, T_>(
+ tr1::static_pointer_cast<T_>(node.clone()))));
+ return base;
+}
+
+template <typename T_>
+tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >
+ConditionTracker::do_add_leaf(const T_ & node)
+{
+ adder(tr1::shared_ptr<TreeLeaf<DependencySpecTree, T_> >(
+ new TreeLeaf<DependencySpecTree, T_>(
+ tr1::static_pointer_cast<T_>(node.clone()))));
+ return base;
+}
+
+tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >
+ConditionTracker::add_condition(const AnyDepSpec & any)
+{
+ return do_add_sequence(any);
+}
+
+tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >
+ConditionTracker::add_condition(const UseDepSpec & use)
+{
+ return do_add_sequence(use);
+}
+
+tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >
+ConditionTracker::add_condition(const PackageDepSpec & pkg)
+{
+ return do_add_leaf(pkg);
+}
+
+tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >
+ConditionTracker::add_condition(const BlockDepSpec & block)
+{
+ return do_add_leaf(block);
+}
+
+template <typename T_>
+void
+ConditionTracker::do_visit_sequence(const T_ & node,
+ DependencySpecTree::ConstSequenceIterator begin,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, T_> > a(
+ new ConstTreeSequence<DependencySpecTree, T_>(
+ tr1::static_pointer_cast<T_>(node.clone())));
+ adder(a);
+ adder = tr1::bind(&ConstTreeSequence<DependencySpecTree, T_>::add, a, _1);
+ if (begin != end)
+ {
+ begin->accept(*this);
+ if (++begin != end)
+ throw InternalError(PALUDIS_HERE, "ConditionTracker saw a sequence with more than one element");
+ }
+}
+
+void
+ConditionTracker::visit_sequence(const AnyDepSpec & node,
+ DependencySpecTree::ConstSequenceIterator begin,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ do_visit_sequence(node, begin, end);
+}
+
+void
+ConditionTracker::visit_sequence(const UseDepSpec & node,
+ DependencySpecTree::ConstSequenceIterator begin,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ do_visit_sequence(node, begin, end);
+}
+
+void
+ConditionTracker::visit_leaf(const PackageDepSpec &)
+{
+ throw InternalError(PALUDIS_HERE, "ConditionTracker saw a PackageDepSpec");
+}
+
+void
+ConditionTracker::visit_leaf(const BlockDepSpec &)
+{
+ throw InternalError(PALUDIS_HERE, "ConditionTracker saw a BlockDepSpec");
+}
+
diff --git a/paludis/dep_list/condition_tracker.hh b/paludis/dep_list/condition_tracker.hh
new file mode 100644
index 0000000..b6ab244
--- /dev/null
+++ b/paludis/dep_list/condition_tracker.hh
@@ -0,0 +1,68 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 David Leverton <levertond@googlemail.com>
+ *
+ * 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_DEP_LIST_CONDITION_TRACKER_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_CONDITION_TRACKER_HH 1
+
+#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/visitor.hh>
+#include <paludis/dep_spec-fwd.hh>
+
+namespace paludis
+{
+ class ConditionTracker :
+ public ConstVisitor<DependencySpecTree>,
+ public ConstVisitor<DependencySpecTree>::VisitConstSequence<ConditionTracker, AllDepSpec>
+ {
+ private:
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > base;
+ tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<DependencySpecTree> >)> adder;
+
+ template <typename T_>
+ void do_visit_sequence(const T_ &,
+ DependencySpecTree::ConstSequenceIterator,
+ DependencySpecTree::ConstSequenceIterator);
+
+ template <typename T_>
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > do_add_sequence(const T_ &);
+ template <typename T_>
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > do_add_leaf(const T_ &);
+
+ public:
+ ConditionTracker(tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >);
+
+ virtual ~ConditionTracker();
+
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > add_condition(const AnyDepSpec &);
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > add_condition(const UseDepSpec &);
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > add_condition(const PackageDepSpec &);
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > add_condition(const BlockDepSpec &);
+
+ using ConstVisitor<DependencySpecTree>::VisitConstSequence<ConditionTracker, AllDepSpec>::visit_sequence;
+
+ virtual void visit_sequence(const AnyDepSpec &, DependencySpecTree::ConstSequenceIterator, DependencySpecTree::ConstSequenceIterator);
+ virtual void visit_sequence(const UseDepSpec &, DependencySpecTree::ConstSequenceIterator, DependencySpecTree::ConstSequenceIterator);
+
+ virtual void visit_leaf(const PackageDepSpec &) PALUDIS_ATTRIBUTE((noreturn));
+ virtual void visit_leaf(const BlockDepSpec &) PALUDIS_ATTRIBUTE((noreturn));
+ };
+}
+
+#endif
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc
index 5de4820..b9a9056 100644
--- a/paludis/dep_list/dep_list.cc
+++ b/paludis/dep_list/dep_list.cc
@@ -22,6 +22,7 @@
#include <paludis/dep_list/query_visitor.hh>
#include <paludis/dep_list/range_rewriter.hh>
#include <paludis/dep_list/show_suggest_visitor.hh>
+#include <paludis/dep_list/condition_tracker.hh>
#include <paludis/dep_spec.hh>
#include <paludis/dep_spec_flattener.hh>
@@ -305,10 +306,16 @@ struct DepList::AddVisitor :
{
DepList * const d;
tr1::shared_ptr<const DestinationsCollection> destinations;
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions;
- AddVisitor(DepList * const dd, tr1::shared_ptr<const DestinationsCollection> ddd) :
+ AddVisitor(DepList * const dd, tr1::shared_ptr<const DestinationsCollection> ddd,
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > c =
+ (tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec))))) :
d(dd),
- destinations(ddd)
+ destinations(ddd),
+ conditions(c)
{
}
@@ -332,6 +339,9 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
{
Context context("When adding PackageDepSpec '" + stringify(a) + "':");
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, d->_imp->opts->dependency_tags ? ConditionTracker(conditions).add_condition(a) : conditions);
+
/* find already installed things */
// TODO: check destinations
tr1::shared_ptr<const PackageDatabaseEntryCollection> already_installed(d->_imp->env->package_database()->query(
@@ -358,7 +368,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
if (d->_imp->opts->dependency_tags && d->_imp->current_pde())
existing_merge_list_entry->tags->insert(DepTagEntry::create()
- .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*d->_imp->current_pde())))
+ .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*d->_imp->current_pde(), a, conditions)))
.generation(d->_imp->merge_list_generation));
/* add an appropriate destination */
@@ -445,7 +455,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
{
if (! (d->_imp->env->mask_reasons(*p, override_options).subtract(mask_mask).any()))
{
- d->add_error_package(*p, dlk_masked);
+ d->add_error_package(*p, dlk_masked, a, conditions);
best_visible_candidate = &*p;
break;
}
@@ -507,7 +517,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
Log::get_instance()->message(ll_warning, lc_context, "No visible packages matching '"
+ stringify(a) + "', falling back to installed package '"
+ stringify(*already_installed->last()) + "'");
- d->add_already_installed_package(*already_installed->last(), a.tag(), destinations);
+ d->add_already_installed_package(*already_installed->last(), a.tag(), a, conditions, destinations);
return;
}
}
@@ -539,7 +549,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
Log::get_instance()->message(ll_debug, lc_context, "Taking installed package '"
+ stringify(*already_installed_in_same_slot->last()) + "' over '" +
best_visible_candidate_as_string + "'");
- d->add_already_installed_package(*already_installed_in_same_slot->last(), a.tag(), destinations);
+ d->add_already_installed_package(*already_installed_in_same_slot->last(), a.tag(), a, conditions, destinations);
return;
}
else
@@ -556,7 +566,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
Log::get_instance()->message(ll_debug, lc_context, "Taking installed package '"
+ stringify(*already_installed->last()) + "' over '" + best_visible_candidate_as_string
+ "' (in different slot)");
- d->add_already_installed_package(*already_installed->last(), a.tag(), destinations);
+ d->add_already_installed_package(*already_installed->last(), a.tag(), a, conditions, destinations);
return;
}
else
@@ -617,7 +627,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
;
}
- d->add_package(*best_visible_candidate, a.tag(), destinations);
+ d->add_package(*best_visible_candidate, a.tag(), a, conditions, destinations);
}
void
@@ -625,6 +635,9 @@ DepList::AddVisitor::visit_sequence(const UseDepSpec & a,
DependencySpecTree::ConstSequenceIterator cur,
DependencySpecTree::ConstSequenceIterator end)
{
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, d->_imp->opts->dependency_tags ? ConditionTracker(conditions).add_condition(a) : conditions);
+
if (d->_imp->opts->use == dl_use_deps_standard)
{
if ((d->_imp->current_pde() ? d->_imp->env->query_use(a.flag(), *d->_imp->current_pde()) : false) ^ a.inverse())
@@ -650,7 +663,7 @@ DepList::AddVisitor::visit_sequence(const UseDepSpec & a,
}
void
-DepList::AddVisitor::visit_sequence(const AnyDepSpec &,
+DepList::AddVisitor::visit_sequence(const AnyDepSpec & a,
DependencySpecTree::ConstSequenceIterator cur,
DependencySpecTree::ConstSequenceIterator end)
{
@@ -667,10 +680,13 @@ DepList::AddVisitor::visit_sequence(const AnyDepSpec &,
{
Context context("When using rewritten range '" + stringify(*r.spec()) + "':");
TreeLeaf<DependencySpecTree, PackageDepSpec> rr(r.spec());
- d->add_not_top_level(rr, destinations);
+ d->add_not_top_level(rr, destinations, conditions);
return;
}
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, d->_imp->opts->dependency_tags ? ConditionTracker(conditions).add_condition(a) : conditions);
+
/* see if any of our children is already installed. if any is, add it so that
* any upgrades kick in */
for (DependencySpecTree::ConstSequenceIterator c(cur) ; c != end ; ++c)
@@ -681,7 +697,7 @@ DepList::AddVisitor::visit_sequence(const AnyDepSpec &,
if (d->already_installed(*c, destinations))
{
Context context("When using already installed group to resolve dependencies:");
- d->add_not_top_level(*c, destinations);
+ d->add_not_top_level(*c, destinations, conditions);
return;
}
}
@@ -702,7 +718,7 @@ DepList::AddVisitor::visit_sequence(const AnyDepSpec &,
Save<bool> save_t(&d->_imp->throw_on_blocker,
dl_blocks_discard_completely != d->_imp->opts->blocks);
Save<DepListOverrideMasks> save_o(&d->_imp->opts->override_masks, DepListOverrideMasks());
- d->add_not_top_level(*c, destinations);
+ d->add_not_top_level(*c, destinations, conditions);
return;
}
catch (const DepListError &)
@@ -723,7 +739,7 @@ DepList::AddVisitor::visit_sequence(const AnyDepSpec &,
Save<bool> save_t(&d->_imp->throw_on_blocker,
dl_blocks_discard_completely != d->_imp->opts->blocks);
Save<DepListOverrideMasks> save_o(&d->_imp->opts->override_masks, DepListOverrideMasks());
- d->add_not_top_level(*c, destinations);
+ d->add_not_top_level(*c, destinations, conditions);
return;
}
catch (const DepListError &)
@@ -740,7 +756,7 @@ DepList::AddVisitor::visit_sequence(const AnyDepSpec &,
if (! is_viable_any_child(*d->_imp->env, d->_imp->current_pde(), *c))
continue;
- d->add_not_top_level(*c, destinations);
+ d->add_not_top_level(*c, destinations, conditions);
return;
}
}
@@ -756,6 +772,9 @@ DepList::AddVisitor::visit_leaf(const BlockDepSpec & a)
Context context("When checking BlockDepSpec '!" + stringify(*a.blocked_spec()) + "':");
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, d->_imp->opts->dependency_tags ? ConditionTracker(conditions).add_condition(a) : conditions);
+
bool check_whole_list(false);
std::list<MergeList::const_iterator> will_be_installed;
tr1::shared_ptr<const PackageDatabaseEntryCollection> already_installed;
@@ -850,7 +869,7 @@ DepList::AddVisitor::visit_leaf(const BlockDepSpec & a)
break;
case dl_blocks_accumulate:
- d->add_error_package(*aa, dlk_block);
+ d->add_error_package(*aa, dlk_block, *a.blocked_spec(), conditions);
break;
case last_dl_blocks:
@@ -941,15 +960,18 @@ DepList::add_in_role(DependencySpecTree::ConstItem & spec, const std::string & r
tr1::shared_ptr<const DestinationsCollection> destinations)
{
Context context("When adding " + role + ":");
- add_not_top_level(spec, destinations);
+ add_not_top_level(spec, destinations,
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(tr1::shared_ptr<AllDepSpec>(new AllDepSpec))));
}
void
-DepList::add_not_top_level(DependencySpecTree::ConstItem & spec, tr1::shared_ptr<const DestinationsCollection> destinations)
+DepList::add_not_top_level(DependencySpecTree::ConstItem & spec, tr1::shared_ptr<const DestinationsCollection> destinations,
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions)
{
DepListTransaction transaction(_imp->merge_list, _imp->merge_list_index, _imp->merge_list_generation);
- AddVisitor visitor(this, destinations);
+ AddVisitor visitor(this, destinations, conditions);
spec.accept(visitor);
transaction.commit();
}
@@ -976,6 +998,7 @@ DepList::add(const PackageDepSpec & spec, tr1::shared_ptr<const DestinationsColl
void
DepList::add_package(const PackageDatabaseEntry & p, tr1::shared_ptr<const DepTag> tag,
+ const PackageDepSpec & pds, tr1::shared_ptr<DependencySpecTree::ConstItem> conditions,
tr1::shared_ptr<const DestinationsCollection> destinations)
{
Context context("When adding package '" + stringify(p) + "':");
@@ -1010,7 +1033,7 @@ DepList::add_package(const PackageDatabaseEntry & p, tr1::shared_ptr<const DepTa
if (_imp->opts->dependency_tags && _imp->current_pde())
our_merge_entry_position->tags->insert(DepTagEntry::create()
- .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde(), pds, conditions)))
.generation(_imp->merge_list_generation));
Save<MergeList::const_iterator> save_current_merge_list_entry(&_imp->current_merge_list_entry,
@@ -1086,7 +1109,7 @@ DepList::add_package(const PackageDatabaseEntry & p, tr1::shared_ptr<const DepTa
Context c("When showing suggestions:");
Save<MergeList::iterator> suggest_save_merge_list_insert_position(&_imp->merge_list_insert_position,
next(our_merge_entry_position));
- ShowSuggestVisitor visitor(this, destinations, _imp->env, _imp->current_pde());
+ ShowSuggestVisitor visitor(this, destinations, _imp->env, _imp->current_pde(), _imp->opts->dependency_tags);
metadata->deps_interface->suggested_depend()->accept(visitor);
}
@@ -1116,7 +1139,8 @@ DepList::add_package(const PackageDatabaseEntry & p, tr1::shared_ptr<const DepTa
}
void
-DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKind kind)
+DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKind kind,
+ const PackageDepSpec & pds, tr1::shared_ptr<DependencySpecTree::ConstItem> conditions)
{
std::pair<MergeListIndex::iterator, MergeListIndex::const_iterator> pp(
_imp->merge_list_index.equal_range(p.name));
@@ -1127,7 +1151,7 @@ DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKin
{
if (_imp->current_pde())
pp.first->second->tags->insert(DepTagEntry::create()
- .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde(), pds, conditions)))
.generation(_imp->merge_list_generation));
return;
}
@@ -1148,7 +1172,7 @@ DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKin
if (_imp->current_pde())
our_merge_entry_position->tags->insert(DepTagEntry::create()
- .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde(), pds, conditions)))
.generation(_imp->merge_list_generation));
_imp->merge_list_index.insert(std::make_pair(p.name, our_merge_entry_position));
@@ -1156,6 +1180,7 @@ DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKin
void
DepList::add_suggested_package(const PackageDatabaseEntry & p,
+ const PackageDepSpec & pds, tr1::shared_ptr<DependencySpecTree::ConstItem> conditions,
const tr1::shared_ptr<const DestinationsCollection> destinations)
{
std::pair<MergeListIndex::iterator, MergeListIndex::const_iterator> pp(
@@ -1184,7 +1209,7 @@ DepList::add_suggested_package(const PackageDatabaseEntry & p,
if (_imp->current_pde())
our_merge_entry_position->tags->insert(DepTagEntry::create()
- .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde(), pds, conditions)))
.generation(_imp->merge_list_generation));
_imp->merge_list_index.insert(std::make_pair(p.name, our_merge_entry_position));
@@ -1246,6 +1271,7 @@ DepList::add_postdeps(DependencySpecTree::ConstItem & d, const DepListDepsOption
void
DepList::add_already_installed_package(const PackageDatabaseEntry & p, tr1::shared_ptr<const DepTag> tag,
+ const PackageDepSpec & pds, tr1::shared_ptr<DependencySpecTree::ConstItem> conditions,
const tr1::shared_ptr<const DestinationsCollection> destinations)
{
Context context("When adding installed package '" + stringify(p) + "':");
@@ -1273,7 +1299,7 @@ DepList::add_already_installed_package(const PackageDatabaseEntry & p, tr1::shar
if (_imp->opts->dependency_tags && _imp->current_pde())
our_merge_entry->tags->insert(DepTagEntry::create()
- .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .tag(tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde(), pds, conditions)))
.generation(_imp->merge_list_generation));
Save<MergeList::const_iterator> save_current_merge_list_entry(&_imp->current_merge_list_entry,
diff --git a/paludis/dep_list/dep_list.hh b/paludis/dep_list/dep_list.hh
index 28a62a2..ff899a4 100644
--- a/paludis/dep_list/dep_list.hh
+++ b/paludis/dep_list/dep_list.hh
@@ -78,18 +78,21 @@ namespace paludis
* Add a package to the list.
*/
void add_package(const PackageDatabaseEntry &, tr1::shared_ptr<const DepTag>,
+ const PackageDepSpec &, tr1::shared_ptr<DependencySpecTree::ConstItem>,
tr1::shared_ptr<const DestinationsCollection> destinations);
/**
* Add an already installed package to the list.
*/
void add_already_installed_package(const PackageDatabaseEntry &, tr1::shared_ptr<const DepTag>,
+ const PackageDepSpec &, tr1::shared_ptr<DependencySpecTree::ConstItem>,
tr1::shared_ptr<const DestinationsCollection> destinations);
/**
* Add an error package to the list.
*/
- void add_error_package(const PackageDatabaseEntry &, const DepListEntryKind);
+ void add_error_package(const PackageDatabaseEntry &, const DepListEntryKind,
+ const PackageDepSpec &, tr1::shared_ptr<DependencySpecTree::ConstItem>);
/**
* Add predependencies.
@@ -110,7 +113,8 @@ namespace paludis
bool is_top_level_target(const PackageDatabaseEntry &) const;
void add_not_top_level(DependencySpecTree::ConstItem &,
- tr1::shared_ptr<const DestinationsCollection> target_destinations);
+ tr1::shared_ptr<const DestinationsCollection> target_destinations,
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions);
public:
///\name Basic operations
@@ -176,6 +180,7 @@ namespace paludis
* Add a suggested package to the list.
*/
void add_suggested_package(const PackageDatabaseEntry &,
+ const PackageDepSpec &, tr1::shared_ptr<DependencySpecTree::ConstItem>,
tr1::shared_ptr<const DestinationsCollection> destinations);
///\name Iterate over our dependency list entries.
diff --git a/paludis/dep_list/dep_list_TEST.cc b/paludis/dep_list/dep_list_TEST.cc
index 216ad94..218d020 100644
--- a/paludis/dep_list/dep_list_TEST.cc
+++ b/paludis/dep_list/dep_list_TEST.cc
@@ -19,6 +19,7 @@
#include "dep_list_TEST.hh"
#include <paludis/util/visitor-impl.hh>
+#include <paludis/dep_spec_pretty_printer.hh>
using namespace paludis;
using namespace test;
@@ -1656,5 +1657,115 @@ namespace test_cases
"cat/zero-1:0::repo");
}
} test_dep_list_upgrade_reinstall_scm;
+
+ /**
+ * \test Test DepList dependency tags.
+ */
+ struct DepListTestCaseDependencyTags : TestCase
+ {
+ DepListTestCaseDependencyTags() : TestCase("dep list dependency tags") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(1, repo);
+ repo->add_version("cat", "one", "1")->deps_interface->set_build_depend("cat/three");
+ repo->add_version("cat", "two", "1")->deps_interface->set_build_depend("enabled? ( || ( ( <cat/three-1 cat/three:0 =cat/four-1 ) cat/five ) )");
+ repo->add_version("cat", "three", "0.9");
+ repo->add_version("cat", "four", "1");
+
+ tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, RepositoryName("installed_repo")));
+ env.package_database()->add_repository(2, installed_repo);
+
+ DepList d1(&env, DepListOptions());
+ d1.options()->dependency_tags = true;
+ PackageDepSpec with_target_tag("cat/one", pds_pm_permissive);
+ with_target_tag.set_tag(tr1::shared_ptr<const DepTag>(new TargetDepTag));
+ d1.add(with_target_tag, env.default_destinations());
+ PackageDepSpec with_set_tag("cat/two", pds_pm_permissive);
+ with_set_tag.set_tag(tr1::shared_ptr<const DepTag>(new GeneralSetDepTag(SetName("set"), "test")));
+ d1.add(with_set_tag, env.default_destinations());
+
+ TEST_CHECK_EQUAL(join(d1.begin(), d1.end(), " "), "cat/three-0.9:0::repo cat/one-1:0::repo "
+ "cat/four-1:0::repo cat/two-1:0::repo");
+
+ // tags for cat/three
+ DepList::Iterator it(d1.begin());
+ tr1::shared_ptr<DepListEntryTags> tags(it->tags);
+ TEST_CHECK_EQUAL(tags->size(), 3U);
+ bool cat_three_has_tag_from_cat_one(false);
+ bool cat_three_has_first_tag_from_cat_two(false);
+ bool cat_three_has_second_tag_from_cat_two(false);
+
+ for (DepListEntryTags::Iterator tag_it(tags->begin()),
+ tag_it_end(tags->end()); tag_it_end != tag_it; ++tag_it)
+ {
+ if ("dependency" != tag_it->tag->category())
+ continue;
+ tr1::shared_ptr<const DependencyDepTag> tag(
+ tr1::static_pointer_cast<const DependencyDepTag>(tag_it->tag));
+
+ if ("cat/one-1::repo" == tag->short_text())
+ {
+ cat_three_has_tag_from_cat_one = true;
+ TEST_CHECK_STRINGIFY_EQUAL(*tag->dependency(), "cat/three");
+ DepSpecPrettyPrinter pretty(0, false);
+ tag->conditions()->accept(pretty);
+ TEST_CHECK_STRINGIFY_EQUAL(pretty, "cat/three");
+ }
+
+ else if ("cat/two-1::repo" == tag->short_text())
+ {
+ if ("<cat/three-1" == stringify(*tag->dependency()))
+ {
+ cat_three_has_first_tag_from_cat_two = true;
+ DepSpecPrettyPrinter pretty(0, false);
+ tag->conditions()->accept(pretty);
+ TEST_CHECK_STRINGIFY_EQUAL(pretty, "enabled? ( || ( <cat/three-1 ) )");
+ }
+ else if ("cat/three:0" == stringify(*tag->dependency()))
+ {
+ cat_three_has_second_tag_from_cat_two = true;
+ DepSpecPrettyPrinter pretty(0, false);
+ tag->conditions()->accept(pretty);
+ TEST_CHECK_STRINGIFY_EQUAL(pretty, "enabled? ( || ( cat/three:0 ) )");
+ }
+ }
+ }
+
+ TEST_CHECK(cat_three_has_tag_from_cat_one);
+ TEST_CHECK(cat_three_has_first_tag_from_cat_two);
+ TEST_CHECK(cat_three_has_second_tag_from_cat_two);
+
+ // tags for cat/one
+ ++it;
+ tags = it->tags;
+ TEST_CHECK_EQUAL(tags->size(), 1U);
+ TEST_CHECK_EQUAL(tags->begin()->tag->category(), "target");
+
+ // tags for cat/four
+ ++it;
+ tags = it->tags;
+ TEST_CHECK_EQUAL(tags->size(), 1U);
+ TEST_CHECK_EQUAL(tags->begin()->tag->category(), "dependency");
+ tr1::shared_ptr<const DependencyDepTag> deptag(
+ tr1::static_pointer_cast<const DependencyDepTag>(tags->begin()->tag));
+ TEST_CHECK_EQUAL(deptag->short_text(), "cat/two-1::repo");
+ TEST_CHECK_STRINGIFY_EQUAL(*deptag->dependency(), "=cat/four-1");
+ DepSpecPrettyPrinter pretty(0, false);
+ deptag->conditions()->accept(pretty);
+ TEST_CHECK_STRINGIFY_EQUAL(pretty, "enabled? ( || ( =cat/four-1 ) )");
+
+ // tags for cat/two
+ ++it;
+ tags = it->tags;
+ TEST_CHECK_EQUAL(tags->size(), 1U);
+ TEST_CHECK_EQUAL(tags->begin()->tag->category(), "general");
+ TEST_CHECK_EQUAL(tags->begin()->tag->short_text(), "set");
+ }
+ } test_dep_list_dependency_tags;
}
diff --git a/paludis/dep_list/show_suggest_visitor.cc b/paludis/dep_list/show_suggest_visitor.cc
index fa04a21..5996f9e 100644
--- a/paludis/dep_list/show_suggest_visitor.cc
+++ b/paludis/dep_list/show_suggest_visitor.cc
@@ -19,9 +19,11 @@
#include <paludis/dep_list/show_suggest_visitor.hh>
#include <paludis/dep_list/dep_list.hh>
+#include <paludis/dep_list/condition_tracker.hh>
#include <paludis/dep_spec.hh>
#include <paludis/package_database.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/save.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
@@ -36,21 +38,27 @@ namespace paludis
tr1::shared_ptr<const DestinationsCollection> destinations;
const Environment * const environment;
const PackageDatabaseEntry * const pde;
+ bool dependency_tags;
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions;
Implementation(DepList * const d, tr1::shared_ptr<const DestinationsCollection> dd,
- const Environment * const e, const PackageDatabaseEntry * const p) :
+ const Environment * const e, const PackageDatabaseEntry * const p, bool t) :
dep_list(d),
destinations(dd),
environment(e),
- pde(p)
+ pde(p),
+ dependency_tags(t),
+ conditions(tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec))))
{
}
};
}
ShowSuggestVisitor::ShowSuggestVisitor(DepList * const d, tr1::shared_ptr<const DestinationsCollection> dd,
- const Environment * const e, const PackageDatabaseEntry * const p) :
- PrivateImplementationPattern<ShowSuggestVisitor>(new Implementation<ShowSuggestVisitor>(d, dd, e, p))
+ const Environment * const e, const PackageDatabaseEntry * const p, bool t) :
+ PrivateImplementationPattern<ShowSuggestVisitor>(new Implementation<ShowSuggestVisitor>(d, dd, e, p, t))
{
}
@@ -63,11 +71,27 @@ ShowSuggestVisitor::visit_sequence(const UseDepSpec & a,
DependencySpecTree::ConstSequenceIterator cur,
DependencySpecTree::ConstSequenceIterator end)
{
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &_imp->conditions, _imp->dependency_tags ?
+ ConditionTracker(_imp->conditions).add_condition(a) : _imp->conditions);
+
if ((_imp->pde ? _imp->environment->query_use(a.flag(), *_imp->pde) : false) ^ a.inverse())
std::for_each(cur, end, accept_visitor(*this));
}
void
+ShowSuggestVisitor::visit_sequence(const AnyDepSpec & a,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+{
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &_imp->conditions, _imp->dependency_tags ?
+ ConditionTracker(_imp->conditions).add_condition(a) : _imp->conditions);
+
+ std::for_each(cur, end, accept_visitor(*this));
+}
+
+void
ShowSuggestVisitor::visit_leaf(const BlockDepSpec &)
{
}
@@ -77,6 +101,10 @@ ShowSuggestVisitor::visit_leaf(const PackageDepSpec & a)
{
Context context("When adding suggested dep '" + stringify(a) + "':");
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &_imp->conditions, _imp->dependency_tags ?
+ ConditionTracker(_imp->conditions).add_condition(a) : _imp->conditions);
+
tr1::shared_ptr<const PackageDatabaseEntryCollection> matches(_imp->environment->package_database()->query(
a, is_installable_only, qo_order_by_version));
if (matches->empty())
@@ -91,7 +119,7 @@ ShowSuggestVisitor::visit_leaf(const PackageDepSpec & a)
if (_imp->environment->mask_reasons(*m).any())
continue;
- _imp->dep_list->add_suggested_package(*m, _imp->destinations);
+ _imp->dep_list->add_suggested_package(*m, a, _imp->conditions, _imp->destinations);
return;
}
diff --git a/paludis/dep_list/show_suggest_visitor.hh b/paludis/dep_list/show_suggest_visitor.hh
index 2a96ac6..84525f4 100644
--- a/paludis/dep_list/show_suggest_visitor.hh
+++ b/paludis/dep_list/show_suggest_visitor.hh
@@ -43,7 +43,7 @@ namespace paludis
///\{
ShowSuggestVisitor(DepList * const dd, tr1::shared_ptr<const DestinationsCollection> ddd,
- const Environment * const, const PackageDatabaseEntry * const);
+ const Environment * const, const PackageDatabaseEntry * const, bool);
~ShowSuggestVisitor();
///\}
@@ -58,9 +58,11 @@ namespace paludis
void visit_sequence(const UseDepSpec &,
DependencySpecTree::ConstSequenceIterator,
DependencySpecTree::ConstSequenceIterator);
+ void visit_sequence(const AnyDepSpec &,
+ DependencySpecTree::ConstSequenceIterator,
+ DependencySpecTree::ConstSequenceIterator);
using ConstVisitor<DependencySpecTree>::VisitConstSequence<ShowSuggestVisitor, AllDepSpec>::visit_sequence;
- using ConstVisitor<DependencySpecTree>::VisitConstSequence<ShowSuggestVisitor, AnyDepSpec>::visit_sequence;
///\}
};
diff --git a/paludis/dep_list/uninstall_list.cc b/paludis/dep_list/uninstall_list.cc
index a70bb11..c95c5f7 100644
--- a/paludis/dep_list/uninstall_list.cc
+++ b/paludis/dep_list/uninstall_list.cc
@@ -22,10 +22,12 @@
using namespace paludis;
#include <paludis/dep_list/uninstall_list-sr.cc>
+#include <paludis/dep_list/condition_tracker.hh>
#include <paludis/environment.hh>
#include <paludis/util/collection_concrete.hh>
#include <paludis/util/join.hh>
#include <paludis/util/log.hh>
+#include <paludis/util/save.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/hashed_containers.hh>
@@ -64,7 +66,7 @@ namespace paludis
UninstallListOptions options;
std::list<UninstallListEntry> uninstall_list;
- mutable MakeHashedMap<PackageDatabaseEntry, tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> >::Type
+ mutable MakeHashedMap<PackageDatabaseEntry, tr1::shared_ptr<const DepListEntryTags> >::Type
dep_collector_cache;
Implementation(const Environment * const e, const UninstallListOptions & o) :
@@ -104,14 +106,14 @@ UninstallList::~UninstallList()
}
void
-UninstallList::add(const PackageDatabaseEntry & e, const PackageDatabaseEntry * const t)
+UninstallList::add(const PackageDatabaseEntry & e, tr1::shared_ptr<DepTag> t)
{
std::list<UninstallListEntry>::iterator i;
if (_imp->uninstall_list.end() != ((i = std::find_if(_imp->uninstall_list.begin(),
_imp->uninstall_list.end(), MatchUninstallListEntry(e)))))
{
if (t)
- i->tags->insert(tr1::shared_ptr<DepTag>(new DependencyDepTag(*t)));
+ i->tags->insert(t);
return;
}
@@ -157,7 +159,7 @@ UninstallList::add_unused()
for (PackageDatabaseEntryCollection::Iterator i(unused->begin()),
i_end(unused->end()) ; i != i_end ; ++i)
- add_package(*i, 0);
+ add_package(*i, tr1::shared_ptr<DepTag>());
}
UninstallList::Iterator
@@ -179,7 +181,7 @@ UninstallListOptions::UninstallListOptions() :
}
void
-UninstallList::add_package(const PackageDatabaseEntry & e, const PackageDatabaseEntry * t)
+UninstallList::add_package(const PackageDatabaseEntry & e, tr1::shared_ptr<DepTag> t)
{
Context context("When adding package '" + stringify(e) + "' to the uninstall list:");
@@ -191,7 +193,7 @@ UninstallList::add_package(const PackageDatabaseEntry & e, const PackageDatabase
e, m->virtual_interface, tr1::shared_ptr<SortedCollection<tr1::shared_ptr<DepTag> > >(
new SortedCollection<tr1::shared_ptr<DepTag> >::Concrete))));
if (t)
- i->tags->insert(tr1::shared_ptr<DepTag>(new DependencyDepTag(*t)));
+ i->tags->insert(t);
}
void
@@ -245,30 +247,52 @@ namespace
ConstVisitor<DependencySpecTree>::VisitConstSequence<DepCollector, AnyDepSpec>
{
using ConstVisitor<DependencySpecTree>::VisitConstSequence<DepCollector, AllDepSpec>::visit_sequence;
- using ConstVisitor<DependencySpecTree>::VisitConstSequence<DepCollector, AnyDepSpec>::visit_sequence;
const Environment * const env;
const PackageDatabaseEntry pkg;
- tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> matches;
+ tr1::shared_ptr<DepListEntryTags> matches;
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > conditions;
+
DepCollector(const Environment * const ee, const PackageDatabaseEntry & e) :
env(ee),
pkg(e),
- matches(new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete)
+ matches(new DepListEntryTags::Concrete),
+ conditions(tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec))))
{
}
void visit_leaf(const PackageDepSpec & a)
{
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, ConditionTracker(conditions).add_condition(a));
+
tr1::shared_ptr<const PackageDatabaseEntryCollection> m(env->package_database()->query(
a, is_installed_only, qo_order_by_version));
- matches->insert(m->begin(), m->end());
+ for (PackageDatabaseEntryCollection::Iterator it = m->begin(), it_end = m->end();
+ it_end != it; ++it)
+ matches->insert(DepTagEntry(tr1::shared_ptr<const DepTag>(new DependencyDepTag(*it, a, conditions)), 0));
+ }
+
+ void visit_sequence(const AnyDepSpec & a,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+ {
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, ConditionTracker(conditions).add_condition(a));
+
+ std::for_each(cur, end, accept_visitor(*this));
}
void visit_sequence(const UseDepSpec & u,
DependencySpecTree::ConstSequenceIterator cur,
DependencySpecTree::ConstSequenceIterator end)
{
+ Save<tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > > save_c(
+ &conditions, ConditionTracker(conditions).add_condition(u));
+
if (env->query_use(UseFlagName(u.flag()), pkg) ^ u.inverse())
std::for_each(cur, end, accept_visitor(*this));
}
@@ -276,11 +300,6 @@ namespace
void visit_leaf(const BlockDepSpec &)
{
}
-
- void visit(const PlainTextDepSpec * const) PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "Got PlainTextDepSpec?");
- }
};
}
@@ -297,8 +316,7 @@ UninstallList::collect_depped_upon(tr1::shared_ptr<const ArbitrarilyOrderedPacka
{
Context local_context("When collecting depended upon packages for '" + stringify(*i) + "':");
- MakeHashedMap<PackageDatabaseEntry,
- tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> >::Type::const_iterator
+ MakeHashedMap<PackageDatabaseEntry, tr1::shared_ptr<const DepListEntryTags> >::Type::const_iterator
cache(_imp->dep_collector_cache.find(*i));
if (cache == _imp->dep_collector_cache.end())
@@ -314,10 +332,12 @@ UninstallList::collect_depped_upon(tr1::shared_ptr<const ArbitrarilyOrderedPacka
metadata->deps_interface->suggested_depend()->accept(c);
}
cache = _imp->dep_collector_cache.insert(std::make_pair(*i,
- tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>(c.matches))).first;
+ tr1::shared_ptr<const DepListEntryTags>(c.matches))).first;
}
- result->insert(cache->second->begin(), cache->second->end());
+ for (DepListEntryTags::Iterator it(cache->second->begin()), it_end(cache->second->end());
+ it_end != it; ++it)
+ result->insert(tr1::static_pointer_cast<const DependencyDepTag>(it->tag)->package());
}
return result;
@@ -378,7 +398,7 @@ UninstallList::add_unused_dependencies()
_imp->uninstall_list.end(), MatchUninstallListEntry(*i)))
continue;
- add_package(*i, 0);
+ add_package(*i, tr1::shared_ptr<DepTag>());
added = true;
}
}
@@ -395,8 +415,7 @@ UninstallList::add_dependencies(const PackageDatabaseEntry & e)
{
Context local_context("When seeing whether '" + stringify(*i) + "' has a dep:");
- MakeHashedMap<PackageDatabaseEntry,
- tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> >::Type::const_iterator
+ MakeHashedMap<PackageDatabaseEntry, tr1::shared_ptr<const DepListEntryTags> >::Type::const_iterator
cache(_imp->dep_collector_cache.find(*i));
if (cache == _imp->dep_collector_cache.end())
@@ -412,16 +431,27 @@ UninstallList::add_dependencies(const PackageDatabaseEntry & e)
metadata->deps_interface->suggested_depend()->accept(c);
}
cache = _imp->dep_collector_cache.insert(std::make_pair(*i,
- tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>(c.matches))).first;
+ tr1::shared_ptr<const DepListEntryTags>(c.matches))).first;
}
- if (cache->second->end() == cache->second->find(e))
- continue;
-
- Log::get_instance()->message(ll_debug, lc_context, "Adding '" + stringify(*i) +
- "' because it depends upon '" + stringify(e) + "'");
+ bool logged(false);
+ for (DepListEntryTags::Iterator it(cache->second->begin()), it_end(cache->second->end());
+ it_end != it; ++it)
+ {
+ tr1::shared_ptr<const DependencyDepTag> tag(tr1::static_pointer_cast<const DependencyDepTag>(it->tag));
+ if (tag->package() == e)
+ {
+ if (! logged)
+ {
+ Log::get_instance()->message(ll_debug, lc_context, "Adding '" + stringify(*i) +
+ "' because it depends upon '" + stringify(e) + "'");
+ logged = true;
+ }
+ add(*i, tr1::shared_ptr<DependencyDepTag>(
+ new DependencyDepTag(tag->package(), *tag->dependency(), tag->conditions())));
+ }
+ }
- add(*i, &e);
}
}
diff --git a/paludis/dep_list/uninstall_list.hh b/paludis/dep_list/uninstall_list.hh
index 74a5d7f..9d72e8d 100644
--- a/paludis/dep_list/uninstall_list.hh
+++ b/paludis/dep_list/uninstall_list.hh
@@ -45,7 +45,7 @@ namespace paludis
public InstantiationPolicy<UninstallList, instantiation_method::NonCopyableTag>
{
private:
- void add_package(const PackageDatabaseEntry &, const PackageDatabaseEntry *);
+ void add_package(const PackageDatabaseEntry &, tr1::shared_ptr<DepTag>);
void move_package_to_end(const PackageDatabaseEntry &);
void add_unused_dependencies();
void add_dependencies(const PackageDatabaseEntry &);
@@ -74,7 +74,7 @@ namespace paludis
/**
* Add a package, optionally with a reason.
*/
- void add(const PackageDatabaseEntry &, const PackageDatabaseEntry * const = 0);
+ void add(const PackageDatabaseEntry &, tr1::shared_ptr<DepTag> = tr1::shared_ptr<DepTag>());
/**
* Add any unused packages that are dependencies of packages to uninstall.
diff --git a/paludis/dep_tag-fwd.hh b/paludis/dep_tag-fwd.hh
index be5697c..e676eb8 100644
--- a/paludis/dep_tag-fwd.hh
+++ b/paludis/dep_tag-fwd.hh
@@ -35,6 +35,7 @@ namespace paludis
class GLSADepTag;
class GeneralSetDepTag;
class DependencyDepTag;
+ class TargetDepTag;
class DepTagVisitorTypes;
diff --git a/paludis/dep_tag.cc b/paludis/dep_tag.cc
index 7cc0444..9f24258 100644
--- a/paludis/dep_tag.cc
+++ b/paludis/dep_tag.cc
@@ -18,6 +18,8 @@
*/
#include "dep_tag.hh"
+#include <paludis/dep_spec.hh>
+#include <paludis/dep_spec_pretty_printer.hh>
#include <paludis/util/virtual_constructor-impl.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/instantiation_policy-impl.hh>
@@ -39,10 +41,12 @@ template class ConstAcceptInterface<DepTagVisitorTypes>;
template class ConstAcceptInterfaceVisitsThis<DepTagVisitorTypes, GeneralSetDepTag>;
template class ConstAcceptInterfaceVisitsThis<DepTagVisitorTypes, GLSADepTag>;
template class ConstAcceptInterfaceVisitsThis<DepTagVisitorTypes, DependencyDepTag>;
+template class ConstAcceptInterfaceVisitsThis<DepTagVisitorTypes, TargetDepTag>;
template class Visits<const GeneralSetDepTag>;
template class Visits<const GLSADepTag>;
template class Visits<const DependencyDepTag>;
+template class Visits<const TargetDepTag>;
template class InstantiationPolicy<DepTagCategoryMaker, instantiation_method::SingletonTag>;
@@ -53,8 +57,6 @@ namespace
/**
* Create the DepTagCategory for GLSAs.
*
- * \see register_glsa_dep_tag
- *
* \ingroup grpdeptag
*/
tr1::shared_ptr<const DepTagCategory>
@@ -71,8 +73,6 @@ namespace
/**
* Create the DepTagCategory for general sets.
*
- * \see register_general_set_dep_tag
- *
* \ingroup grpdeptag
*/
tr1::shared_ptr<const DepTagCategory>
@@ -89,8 +89,6 @@ namespace
/**
* Create the DepTagCategory for dependency sets.
*
- * \see register_dependency_set_dep_tag
- *
* \ingroup grpdeptag
*/
tr1::shared_ptr<const DepTagCategory>
@@ -103,6 +101,22 @@ namespace
"",
""));
}
+
+ /**
+ * Create the DepTagCategory for targets.
+ *
+ * \ingroup grpdeptag
+ */
+ tr1::shared_ptr<const DepTagCategory>
+ make_target_dep_tag()
+ {
+ return tr1::shared_ptr<const DepTagCategory>(new DepTagCategory(
+ false,
+ "target",
+ "Targets",
+ "",
+ ""));
+ }
}
DepTagCategory::DepTagCategory(
@@ -161,16 +175,22 @@ DepTag::~DepTag()
{
}
+std::string
+DepTag::full_text() const
+{
+ return short_text();
+}
+
bool
DepTag::operator== (const DepTag & other) const
{
- return short_text() == other.short_text();
+ return full_text() == other.full_text();
}
bool
DepTag::operator< (const DepTag & other) const
{
- return short_text() < other.short_text();
+ return full_text() < other.full_text();
}
GLSADepTag::GLSADepTag(const std::string & id, const std::string & our_glsa_title) :
@@ -221,9 +241,30 @@ GeneralSetDepTag::source() const
return _source;
}
-DependencyDepTag::DependencyDepTag(const PackageDatabaseEntry & pde) :
- _dbe(pde)
+DependencyDepTag::DependencyDepTag(const PackageDatabaseEntry & pde, const PackageDepSpec & spec,
+ tr1::shared_ptr<DependencySpecTree::ConstItem> cond) :
+ _dbe(pde),
+ _cond(cond)
{
+ tr1::shared_ptr<PackageDepSpec> cloned_spec(tr1::static_pointer_cast<PackageDepSpec>(spec.clone()));
+ cloned_spec->set_tag(tr1::shared_ptr<const DepTag>());
+ _spec = cloned_spec;
+}
+
+std::string
+DependencyDepTag::full_text() const
+{
+ if (_str.empty())
+ {
+ _str.append(stringify(_dbe));
+ _str.append(",");
+ _str.append(stringify(*_spec));
+ _str.append(",");
+ DepSpecPrettyPrinter pretty(0, false);
+ _cond->accept(pretty);
+ _str.append(stringify(pretty));
+ }
+ return _str;
}
std::string
@@ -238,10 +279,45 @@ DependencyDepTag::category() const
return "dependency";
}
+PackageDatabaseEntry
+DependencyDepTag::package() const
+{
+ return _dbe;
+}
+
+tr1::shared_ptr<const PackageDepSpec>
+DependencyDepTag::dependency() const
+{
+ return _spec;
+}
+
+tr1::shared_ptr<DependencySpecTree::ConstItem>
+DependencyDepTag::conditions() const
+{
+ return _cond;
+}
+
+TargetDepTag::TargetDepTag()
+{
+}
+
+std::string
+TargetDepTag::short_text() const
+{
+ return "target";
+}
+
+std::string
+TargetDepTag::category() const
+{
+ return "target";
+}
+
DepTagCategoryMaker::DepTagCategoryMaker()
{
register_maker("glsa", &make_glsa_dep_tag);
register_maker("general", &make_general_set_dep_tag);
register_maker("dependency", &make_dependency_set_dep_tag);
+ register_maker("target", &make_target_dep_tag);
}
diff --git a/paludis/dep_tag.hh b/paludis/dep_tag.hh
index c5304bd..097df71 100644
--- a/paludis/dep_tag.hh
+++ b/paludis/dep_tag.hh
@@ -28,6 +28,7 @@
#include <paludis/dep_tag-fwd.hh>
#include <paludis/package_database_entry.hh>
+#include <paludis/dep_spec-fwd.hh>
#include <paludis/util/instantiation_policy.hh>
#include <paludis/util/visitor.hh>
#include <paludis/util/virtual_constructor.hh>
@@ -53,7 +54,8 @@ namespace paludis
DepTag,
GLSADepTag,
GeneralSetDepTag,
- DependencyDepTag
+ DependencyDepTag,
+ TargetDepTag
>
{
};
@@ -159,6 +161,7 @@ namespace paludis
class GLSADepTag;
class GeneralSetDepTag;
class DependencyDepTag;
+ class TargetDepTag;
/**
* A DepTag can be associated with a PackageDepSpec, and is transferred
@@ -176,6 +179,12 @@ namespace paludis
public virtual ConstAcceptInterface<DepTagVisitorTypes>
{
protected:
+ /**
+ * Return a string containing all our state, for
+ * comparison with other tags.
+ */
+ virtual std::string full_text() const;
+
///\name Basic operations
///\{
@@ -283,18 +292,64 @@ namespace paludis
{
private:
const PackageDatabaseEntry _dbe;
+ tr1::shared_ptr<const PackageDepSpec> _spec;
+ tr1::shared_ptr<DependencySpecTree::ConstItem> _cond;
+ mutable std::string _str;
+
+ void _make_str() const;
+
+ protected:
+ virtual std::string full_text() const;
+
public:
///\name Basic operations
///\{
- DependencyDepTag(const PackageDatabaseEntry & dbe);
+ DependencyDepTag(const PackageDatabaseEntry & dbe, const PackageDepSpec & spec, tr1::shared_ptr<DependencySpecTree::ConstItem>);
///\}
virtual std::string short_text() const;
virtual std::string category() const;
+
+ /**
+ * The PackageDatabaseEntry that contains our dependency.
+ */
+ PackageDatabaseEntry package() const;
+
+ /**
+ * The PackageDepSpec that pulled us in.
+ */
+ tr1::shared_ptr<const PackageDepSpec> dependency() const;
+
+ /**
+ * The AllDepSpecs and UseDepSpecs that our dependency is conditional upon.
+ */
+ tr1::shared_ptr<DependencySpecTree::ConstItem> conditions() const;
+ };
+
+ /**
+ * DepTag subclass for explicit targets.
+ *
+ * \ingroup grpdeptag
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE TargetDepTag :
+ public DepTag,
+ public ConstAcceptInterfaceVisitsThis<DepTagVisitorTypes, TargetDepTag>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ TargetDepTag();
+
+ ///\}
+
+ virtual std::string short_text() const;
+ virtual std::string category() const;
};
#include <paludis/dep_tag-sr.hh>
diff --git a/paludis/portage_dep_parser.cc b/paludis/portage_dep_parser.cc
index 7349bad..297be48 100644
--- a/paludis/portage_dep_parser.cc
+++ b/paludis/portage_dep_parser.cc
@@ -23,6 +23,7 @@
#include <paludis/portage_dep_parser.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/stringify.hh>
+#include <paludis/util/tr1_functional.hh>
#include <paludis/util/visitor-impl.hh>
#include <stack>
@@ -62,38 +63,7 @@ namespace
dps_had_text_arrow_text
};
- template <typename H_>
- struct Composite
- {
- virtual tr1::shared_ptr<typename H_::ConstItem> as_const_item() const = 0;
- virtual void add(tr1::shared_ptr<ConstAcceptInterface<H_> >) = 0;
-
- virtual ~Composite()
- {
- }
- };
-
- template <typename H_, typename E_>
- struct RealComposite :
- Composite<H_>
- {
- tr1::shared_ptr<ConstTreeSequence<H_, E_> > _i;
-
- virtual tr1::shared_ptr<typename H_::ConstItem> as_const_item() const
- {
- return tr1::static_pointer_cast<typename H_::ConstItem>(_i);
- }
-
- virtual void add(tr1::shared_ptr<ConstAcceptInterface<H_> > i)
- {
- _i->add(i);
- }
-
- RealComposite(tr1::shared_ptr<ConstTreeSequence<H_, E_> > e) :
- _i(e)
- {
- }
- };
+ using namespace tr1::placeholders;
struct ParsePackageDepSpec
{
@@ -106,15 +76,15 @@ namespace
template <typename H_>
void
- add(const std::string & s, tr1::shared_ptr<Composite<H_> > & p) const
+ add(const std::string & s, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
{
- p->add(tr1::shared_ptr<TreeLeaf<H_, PackageDepSpec> >(new TreeLeaf<H_, PackageDepSpec>(
+ p(tr1::shared_ptr<TreeLeaf<H_, PackageDepSpec> >(new TreeLeaf<H_, PackageDepSpec>(
tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(s, _parse_mode)))));
}
template <typename H_>
void
- add_arrow(const std::string & lhs, const std::string & rhs, tr1::shared_ptr<Composite<H_> > &) const
+ add_arrow(const std::string & lhs, const std::string & rhs, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
{
throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
}
@@ -131,20 +101,20 @@ namespace
template <typename H_>
void
- add(const std::string & s, tr1::shared_ptr<Composite<H_> > & p) const
+ add(const std::string & s, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
{
if (s.empty() || '!' != s.at(0))
- p->add(tr1::shared_ptr<TreeLeaf<H_, PackageDepSpec> >(new TreeLeaf<H_, PackageDepSpec>(
+ p(tr1::shared_ptr<TreeLeaf<H_, PackageDepSpec> >(new TreeLeaf<H_, PackageDepSpec>(
tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(s, _parse_mode)))));
else
- p->add(tr1::shared_ptr<TreeLeaf<H_, BlockDepSpec> >(new TreeLeaf<H_, BlockDepSpec>(
+ p(tr1::shared_ptr<TreeLeaf<H_, BlockDepSpec> >(new TreeLeaf<H_, BlockDepSpec>(
tr1::shared_ptr<BlockDepSpec>(new BlockDepSpec(
tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(s.substr(1), _parse_mode)))))));
}
template <typename H_>
void
- add_arrow(const std::string & lhs, const std::string & rhs, tr1::shared_ptr<Composite<H_> > &) const
+ add_arrow(const std::string & lhs, const std::string & rhs, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
{
throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
}
@@ -154,15 +124,15 @@ namespace
{
template <typename H_>
void
- add(const std::string & s, tr1::shared_ptr<Composite<H_> > & p) const
+ add(const std::string & s, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
{
- p->add(tr1::shared_ptr<TreeLeaf<H_, PlainTextDepSpec> >(new TreeLeaf<H_, PlainTextDepSpec>(
+ p(tr1::shared_ptr<TreeLeaf<H_, PlainTextDepSpec> >(new TreeLeaf<H_, PlainTextDepSpec>(
tr1::shared_ptr<PlainTextDepSpec>(new PlainTextDepSpec(s)))));
}
template <typename H_>
void
- add_arrow(const std::string & lhs, const std::string & rhs, tr1::shared_ptr<Composite<H_> > &) const
+ add_arrow(const std::string & lhs, const std::string & rhs, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
{
throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
}
@@ -179,18 +149,18 @@ namespace
template <typename H_>
void
- add(const std::string & s, tr1::shared_ptr<Composite<H_> > & p) const
+ add(const std::string & s, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
{
- p->add(tr1::shared_ptr<TreeLeaf<H_, URIDepSpec> >(new TreeLeaf<H_, URIDepSpec>(
+ p(tr1::shared_ptr<TreeLeaf<H_, URIDepSpec> >(new TreeLeaf<H_, URIDepSpec>(
tr1::shared_ptr<URIDepSpec>(new URIDepSpec(s)))));
}
template <typename H_>
void
- add_arrow(const std::string & lhs, const std::string & rhs, tr1::shared_ptr<Composite<H_> > & p) const
+ add_arrow(const std::string & lhs, const std::string & rhs, tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
{
if (_supports_arrow)
- p->add(tr1::shared_ptr<TreeLeaf<H_, URIDepSpec> >(new TreeLeaf<H_, URIDepSpec>(
+ p(tr1::shared_ptr<TreeLeaf<H_, URIDepSpec> >(new TreeLeaf<H_, URIDepSpec>(
tr1::shared_ptr<URIDepSpec>(new URIDepSpec(lhs + " -> " + rhs)))));
else
throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this EAPI");
@@ -201,7 +171,7 @@ namespace
struct HandleUse
{
static void handle(const std::string & s, const std::string & i,
- std::stack<std::pair<tr1::shared_ptr<Composite<H_> >, bool> > & stack)
+ std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > & stack)
{
std::string f(i);
bool inv(f.length() && ('!' == f.at(0)));
@@ -219,8 +189,9 @@ namespace
tr1::shared_ptr<ConstTreeSequence<H_, UseDepSpec> > a(
new ConstTreeSequence<H_, UseDepSpec>(tr1::shared_ptr<UseDepSpec>(
new UseDepSpec(UseFlagName(f), inv))));
- stack.top().first->add(a);
- stack.push(std::make_pair(tr1::shared_ptr<Composite<H_> >(new RealComposite<H_, UseDepSpec>(a)), false));
+ stack.top().first(a);
+ stack.push(std::make_pair(tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
+ tr1::bind(&ConstTreeSequence<H_, UseDepSpec>::add, a, _1)), false));
}
};
@@ -228,7 +199,7 @@ namespace
struct HandleUse<H_, false>
{
static void handle(const std::string & s, const std::string &,
- std::stack<std::pair<tr1::shared_ptr<Composite<H_> >, bool> > &)
+ std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > &)
{
throw DepStringParseError(s, "use? group is not allowed here");
}
@@ -237,19 +208,20 @@ namespace
template <typename H_, bool>
struct HandleAny
{
- static void handle(const std::string &, std::stack<std::pair<tr1::shared_ptr<Composite<H_> >, bool> > & stack)
+ static void handle(const std::string &, std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > & stack)
{
tr1::shared_ptr<ConstTreeSequence<H_, AnyDepSpec> > a(new ConstTreeSequence<H_, AnyDepSpec>(
tr1::shared_ptr<AnyDepSpec>(new AnyDepSpec)));
- stack.top().first->add(a);
- stack.push(std::make_pair(tr1::shared_ptr<Composite<H_> >(new RealComposite<H_, AnyDepSpec>(a)), true));
+ stack.top().first(a);
+ stack.push(std::make_pair(tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
+ tr1::bind(&ConstTreeSequence<H_, AnyDepSpec>::add, a, _1)), true));
}
};
template <typename H_>
struct HandleAny<H_, false>
{
- static void handle(const std::string & s, std::stack<std::pair<tr1::shared_ptr<Composite<H_> >, bool> > &)
+ static void handle(const std::string & s, std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > &)
{
throw DepStringParseError(s, "|| is not allowed here");
}
@@ -280,10 +252,11 @@ PortageDepParser::_parse(const std::string & s, bool disallow_any_use, const I_
{
Context context("When parsing dependency string '" + s + "':");
- std::stack<std::pair<tr1::shared_ptr<Composite<H_> >, bool> > stack;
- stack.push(std::make_pair(tr1::shared_ptr<RealComposite<H_, AllDepSpec> >(new RealComposite<H_, AllDepSpec>(
- tr1::shared_ptr<ConstTreeSequence<H_, AllDepSpec> >(new ConstTreeSequence<H_, AllDepSpec>(
- tr1::shared_ptr<AllDepSpec>(new AllDepSpec))))), false));
+ tr1::shared_ptr<ConstTreeSequence<H_, AllDepSpec> > result(
+ new ConstTreeSequence<H_, AllDepSpec>(tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
+ std::stack<std::pair<tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > stack;
+ stack.push(std::make_pair(tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
+ tr1::bind(&ConstTreeSequence<H_, AllDepSpec>::add, result, _1)), false));
std::string arrow_lhs;
PortageDepParserState state(dps_initial);
@@ -331,8 +304,8 @@ PortageDepParser::_parse(const std::string & s, bool disallow_any_use, const I_
{
tr1::shared_ptr<ConstTreeSequence<H_, AllDepSpec> > a(new ConstTreeSequence<H_, AllDepSpec>(
tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
- stack.top().first->add(a);
- stack.push(std::make_pair(tr1::shared_ptr<Composite<H_> >(new RealComposite<H_, AllDepSpec>(a)), false));
+ stack.top().first(a);
+ stack.push(std::make_pair(tr1::function<void (tr1::shared_ptr<ConstAcceptInterface<H_> >)>(tr1::bind(&ConstTreeSequence<H_, AllDepSpec>::add, a, _1)), false));
state = dps_had_paren;
}
continue;
@@ -571,11 +544,10 @@ PortageDepParser::_parse(const std::string & s, bool disallow_any_use, const I_
throw DepStringParseError(s, "Unexpected end of string");
}
- tr1::shared_ptr<Composite<H_> > result(stack.top().first);
stack.pop();
if (! stack.empty())
throw DepStringNestingError(s);
- return result->as_const_item();
+ return result;
}
tr1::shared_ptr<DependencySpecTree::ConstItem>
diff --git a/paludis/tasks/install_task.cc b/paludis/tasks/install_task.cc
index 1a09e57..c420c3d 100644
--- a/paludis/tasks/install_task.cc
+++ b/paludis/tasks/install_task.cc
@@ -145,17 +145,22 @@ InstallTask::add_target(const std::string & target)
_imp->dep_list.options()->target_type = dl_target_package;
if (std::string::npos != target.find('/'))
+ {
+ tr1::shared_ptr<PackageDepSpec> spec(new PackageDepSpec(target, pds_pm_permissive));
+ spec->set_tag(tr1::shared_ptr<const DepTag>(new TargetDepTag));
_imp->targets->add(tr1::shared_ptr<TreeLeaf<SetSpecTree, PackageDepSpec> >(
- new TreeLeaf<SetSpecTree, PackageDepSpec>(tr1::shared_ptr<PackageDepSpec>(
- new PackageDepSpec(target, pds_pm_permissive)))));
+ new TreeLeaf<SetSpecTree, PackageDepSpec>(spec)));
+ }
else
{
QualifiedPackageName q(_imp->env->package_database()->fetch_unique_qualified_package_name(
PackageNamePart(target)));
modified_target = stringify(q);
+ tr1::shared_ptr<PackageDepSpec> spec(
+ new PackageDepSpec(tr1::shared_ptr<QualifiedPackageName>(new QualifiedPackageName(q))));
+ spec->set_tag(tr1::shared_ptr<const DepTag>(new TargetDepTag));
_imp->targets->add(tr1::shared_ptr<TreeLeaf<SetSpecTree, PackageDepSpec> >(
- new TreeLeaf<SetSpecTree, PackageDepSpec>(tr1::shared_ptr<PackageDepSpec>(
- new PackageDepSpec(tr1::shared_ptr<QualifiedPackageName>(new QualifiedPackageName(q)))))));
+ new TreeLeaf<SetSpecTree, PackageDepSpec>(spec)));
}
}
diff --git a/paludis/tasks/uninstall_task.cc b/paludis/tasks/uninstall_task.cc
index 98b3453..b0d91d7 100644
--- a/paludis/tasks/uninstall_task.cc
+++ b/paludis/tasks/uninstall_task.cc
@@ -108,7 +108,9 @@ UninstallTask::add_target(const std::string & target)
throw HadBothPackageAndSetTargets();
_imp->had_package_targets = true;
- _imp->targets.push_back(tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(target, pds_pm_permissive)));
+ tr1::shared_ptr<PackageDepSpec> pds(new PackageDepSpec(target, pds_pm_permissive));
+ pds->set_tag(tr1::shared_ptr<const DepTag>(new TargetDepTag));
+ _imp->targets.push_back(pds);
}
else
try
@@ -135,10 +137,12 @@ UninstallTask::add_target(const std::string & target)
throw HadBothPackageAndSetTargets();
_imp->had_package_targets = false;
- _imp->targets.push_back(tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
+ tr1::shared_ptr<PackageDepSpec> pds(new PackageDepSpec(
tr1::shared_ptr<QualifiedPackageName>(new QualifiedPackageName(
_imp->env->package_database()->fetch_unique_qualified_package_name(
- PackageNamePart(target)))))));
+ PackageNamePart(target))))));
+ pds->set_tag(tr1::shared_ptr<const DepTag>(new TargetDepTag));
+ _imp->targets.push_back(pds);
}
}
catch (const SetNameError &)
@@ -147,10 +151,12 @@ UninstallTask::add_target(const std::string & target)
throw HadBothPackageAndSetTargets();
_imp->had_package_targets = false;
- _imp->targets.push_back(tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
+ tr1::shared_ptr<PackageDepSpec> pds(new PackageDepSpec(
tr1::shared_ptr<QualifiedPackageName>(new QualifiedPackageName(
_imp->env->package_database()->fetch_unique_qualified_package_name(
- PackageNamePart(target)))))));
+ PackageNamePart(target))))));
+ pds->set_tag(tr1::shared_ptr<const DepTag>(new TargetDepTag));
+ _imp->targets.push_back(pds);
}
_imp->raw_targets.push_back(target);
diff --git a/ruby/dep_tag.cc b/ruby/dep_tag.cc
index e05b4b6..03a6ae2 100644
--- a/ruby/dep_tag.cc
+++ b/ruby/dep_tag.cc
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2007 Richard Brown <rbrown@gentoo.org>
+ * Copyright (c) 2007 David Leverton <levertond@googlemail.com>
*
* 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
@@ -32,6 +33,7 @@ namespace
static VALUE c_dependency_dep_tag;
static VALUE c_glsa_dep_tag;
static VALUE c_general_set_dep_tag;
+ static VALUE c_target_dep_tag;
struct V :
ConstVisitor<DepTagVisitorTypes>
{
@@ -60,14 +62,14 @@ namespace
value = Data_Wrap_Struct(c_general_set_dep_tag, 0, &Common<tr1::shared_ptr<const GeneralSetDepTag> >::free,
new tr1::shared_ptr<const GeneralSetDepTag>(tr1::static_pointer_cast<const GeneralSetDepTag>(mm)));
}
- };
+ void visit(const TargetDepTag &)
+ {
+ value = Data_Wrap_Struct(c_target_dep_tag, 0, &Common<tr1::shared_ptr<const TargetDepTag> >::free,
+ new tr1::shared_ptr<const TargetDepTag>(tr1::static_pointer_cast<const TargetDepTag>(mm)));
+ }
+ };
- VALUE
- dep_tag_init(VALUE self, VALUE)
- {
- return self;
- }
VALUE
dep_tag_init_1(int, VALUE*, VALUE self)
@@ -76,14 +78,24 @@ namespace
}
VALUE
- dependency_dep_tag_new(VALUE self, VALUE pde)
+ dependency_dep_tag_new(int argc, VALUE * argv, VALUE self)
{
+ if (2 != argc)
+ rb_raise(rb_eArgError, "DependencyDepTag expects two arguments, but got %d", argc);
+
tr1::shared_ptr<const DependencyDepTag> * ptr(0);
try
{
- ptr = new tr1::shared_ptr<const DependencyDepTag>(new DependencyDepTag(value_to_package_database_entry(pde)));
+ ptr = new tr1::shared_ptr<const DependencyDepTag>(
+ new DependencyDepTag(value_to_package_database_entry(argv[0]),
+ *value_to_package_dep_spec(argv[1]),
+ // XXX make this an argument, once the new
+ // visitors are Rubified
+ tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> >(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec)))));
VALUE tdata(Data_Wrap_Struct(self, 0, &Common<tr1::shared_ptr<const DependencyDepTag> >::free, ptr));
- rb_obj_call_init(tdata, 1, &pde);
+ rb_obj_call_init(tdata, argc, argv);
return tdata;
}
catch (const std::exception & e)
@@ -135,6 +147,24 @@ namespace
}
}
+ VALUE
+ target_dep_tag_new(VALUE self)
+ {
+ tr1::shared_ptr<const TargetDepTag> * ptr(0);
+ try
+ {
+ ptr = new tr1::shared_ptr<const TargetDepTag>(new TargetDepTag);
+ VALUE tdata(Data_Wrap_Struct(self, 0, &Common<tr1::shared_ptr<const TargetDepTag> >::free, ptr));
+ rb_obj_call_init(tdata, 0, 0);
+ return tdata;
+ }
+ catch (const std::exception & e)
+ {
+ delete ptr;
+ exception_to_ruby_exception(e);
+ }
+ }
+
/*
* Document-method: short_text
*
@@ -201,8 +231,7 @@ namespace
* DepTag subclass for dependencies.
*/
c_dependency_dep_tag = rb_define_class_under(paludis_module(), "DependencyDepTag", c_dep_tag);
- rb_define_singleton_method(c_dependency_dep_tag, "new", RUBY_FUNC_CAST(&dependency_dep_tag_new), 1);
- rb_define_method(c_dependency_dep_tag, "initialize", RUBY_FUNC_CAST(&dep_tag_init), 1);
+ rb_define_singleton_method(c_dependency_dep_tag, "new", RUBY_FUNC_CAST(&dependency_dep_tag_new), -1);
/*
* Document-class: Paludis::GLSADepTag
@@ -223,6 +252,14 @@ namespace
rb_define_singleton_method(c_general_set_dep_tag, "new", RUBY_FUNC_CAST(&general_set_dep_tag_new), -1);
rb_define_method(c_general_set_dep_tag, "source", RUBY_FUNC_CAST((&DepTagThings<GeneralSetDepTag,
&GeneralSetDepTag::source>::fetch)), 0);
+
+ /*
+ * Document-class: Paludis::TargetDepTag
+ *
+ * DepTag subclass for general sets.
+ */
+ c_target_dep_tag = rb_define_class_under(paludis_module(), "TargetDepTag", c_dep_tag);
+ rb_define_singleton_method(c_target_dep_tag, "new", RUBY_FUNC_CAST(&target_dep_tag_new), 0);
}
}
diff --git a/ruby/dep_tag_TEST.rb b/ruby/dep_tag_TEST.rb
index 2da0d3f..2573429 100644
--- a/ruby/dep_tag_TEST.rb
+++ b/ruby/dep_tag_TEST.rb
@@ -31,7 +31,8 @@ module Paludis
class TestCase_DependencyDepTag < Test::Unit::TestCase
def get_dt
- DependencyDepTag.new(PackageDatabaseEntry.new('foo/var','0','moo'))
+ DependencyDepTag.new(PackageDatabaseEntry.new('foo/var','0','moo'),
+ PackageDepSpec.new('foo/bar', PackageDepSpecParseMode::Permissive))
end
def test_create
@@ -44,10 +45,14 @@ module Paludis
end
assert_raise ArgumentError do
- DependencyDepTag.new('a','b')
+ DependencyDepTag.new('a','b','c')
end
assert_raise TypeError do
+ DependencyDepTag.new('a','b')
+ end
+
+ assert_raise ArgumentError do
DependencyDepTag.new(1)
end
end
@@ -132,5 +137,32 @@ module Paludis
end
end
end
+
+ class TestCase_TargetDepTag < Test::Unit::TestCase
+ def get_dt
+ TargetDepTag.new
+ end
+
+ def test_create
+ assert_kind_of TargetDepTag, get_dt
+ end
+
+ def test_create_error
+ assert_raise ArgumentError do
+ TargetDepTag.new(1)
+ end
+ end
+
+ def test_respond_to
+ dt = get_dt
+ {
+ :short_text => 'target',
+ :category=>'target',
+ }.each do |method, val|
+ assert_respond_to dt, method
+ assert_equal val, dt.send(method)
+ end
+ end
+ end
end
diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc
index c0c610f..8390dda 100644
--- a/src/output/console_install_task.cc
+++ b/src/output/console_install_task.cc
@@ -685,6 +685,11 @@ DepTagSummaryDisplayer::visit(const DependencyDepTag &)
}
void
+DepTagSummaryDisplayer::visit(const TargetDepTag &)
+{
+}
+
+void
DepTagSummaryDisplayer::visit(const GeneralSetDepTag & tag)
{
std::string desc;
@@ -991,6 +996,7 @@ ConsoleInstallTask::display_merge_list_entry_tags(const DepListEntry & d, const
return;
std::string deps;
+ std::set<std::string> dependents, unsatisfied_dependents;
unsigned c(0), max_c(want_full_install_reasons() ? std::numeric_limits<long>::max() : 3);
for (SortedCollection<DepTagEntry>::Iterator
@@ -1001,19 +1007,39 @@ ConsoleInstallTask::display_merge_list_entry_tags(const DepListEntry & d, const
if (tag->tag->category() != "dependency")
continue;
+ tr1::shared_ptr<const PackageDepSpec> spec(
+ tr1::static_pointer_cast<const DependencyDepTag>(tag->tag)->dependency());
+ if (d.kind != dlk_masked && d.kind != dlk_block && environment()->package_database()->query(
+ query::Matches(*spec) & query::RepositoryHasInstalledInterface(), qo_whatever)->empty())
+ unsatisfied_dependents.insert(tag->tag->short_text());
+ else
+ dependents.insert(tag->tag->short_text());
+ }
+
+ for (std::set<std::string>::iterator it(unsatisfied_dependents.begin()),
+ it_end(unsatisfied_dependents.end()); it_end != it; ++it)
if (++c < max_c)
{
- deps.append(tag->tag->short_text());
+ deps.append("*");
+ deps.append(*it);
+ deps.append(", ");
+ }
+ for (std::set<std::string>::iterator it(dependents.begin()),
+ it_end(dependents.end()); it_end != it; ++it)
+ if (unsatisfied_dependents.end() == unsatisfied_dependents.find(*it) &&
+ ++c < max_c)
+ {
+ deps.append(*it);
deps.append(", ");
}
- }
if (! deps.empty())
{
if (c >= max_c)
deps.append(stringify(c - max_c + 1) + " more, ");
- deps.erase(deps.length() - 2);
+ if (! deps.empty())
+ deps.erase(deps.length() - 2);
if (! deps.empty())
switch (m)
@@ -1075,6 +1101,11 @@ EntryDepTagDisplayer::visit(const DependencyDepTag &)
}
void
+EntryDepTagDisplayer::visit(const TargetDepTag &)
+{
+}
+
+void
EntryDepTagDisplayer::visit(const GeneralSetDepTag & tag)
{
text() = tag.short_text(); // + "<" + tag->source() + ">";
diff --git a/src/output/console_install_task.hh b/src/output/console_install_task.hh
index 9d94bb0..f59009f 100644
--- a/src/output/console_install_task.hh
+++ b/src/output/console_install_task.hh
@@ -57,6 +57,7 @@ namespace paludis
void visit(const GLSADepTag &);
void visit(const DependencyDepTag &);
void visit(const GeneralSetDepTag &);
+ void visit(const TargetDepTag &);
ConsoleInstallTask * task()
{
@@ -77,6 +78,7 @@ namespace paludis
void visit(const GLSADepTag & tag);
void visit(const DependencyDepTag &);
void visit(const GeneralSetDepTag & tag);
+ void visit(const TargetDepTag &);
std::string & text()
{