aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-10-06 16:11:51 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-10-06 16:11:51 +0000
commit3d41292de354ac973dce67c37cba059602ac68f4 (patch)
treec6f431ee413db0e5dc978271caf4bd43ffd6660e
parent00c33c637aa1fba6e9d01dead358429435410ae1 (diff)
downloadpaludis-3d41292de354ac973dce67c37cba059602ac68f4.tar.gz
paludis-3d41292de354ac973dce67c37cba059602ac68f4.tar.xz
New deplist code. Much cleaner than before. No support for tags yet.
-rw-r--r--paludis/Makefile.am.m41
-rw-r--r--paludis/dep_list.cc1163
-rw-r--r--paludis/dep_list.hh240
-rw-r--r--paludis/dep_list.sr39
-rw-r--r--paludis/dep_list_TEST.cc171
-rw-r--r--paludis/dep_list_entry.sr25
-rw-r--r--paludis/files.m43
-rw-r--r--paludis/match_package.cc13
-rw-r--r--paludis/repositories/virtuals/virtuals_repository.cc70
-rw-r--r--paludis/tasks/install_task.cc126
-rw-r--r--paludis/tasks/install_task.hh11
-rw-r--r--paludis/util/counted_ptr.hh4
-rw-r--r--src/adjutrix/display_default_system_resolution.cc9
-rw-r--r--src/paludis/command_line.cc83
-rw-r--r--src/paludis/command_line.hh29
-rw-r--r--src/paludis/install.cc154
16 files changed, 1055 insertions, 1086 deletions
diff --git a/paludis/Makefile.am.m4 b/paludis/Makefile.am.m4
index 80c686b..7acad31 100644
--- a/paludis/Makefile.am.m4
+++ b/paludis/Makefile.am.m4
@@ -20,6 +20,7 @@ $1_TEST_LDADD = \
$(top_builddir)/paludis/util/libpaludisutil.la \
$(top_builddir)/paludis/environment/test/libpaludistestenvironment.la \
$(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
$(DYNAMIC_LD_LIBS)
$1_TEST_CXXFLAGS = -I$(top_srcdir)
')dnl
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index ad15742..75fb384 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -35,846 +35,721 @@
using namespace paludis;
-#include <paludis/dep_list_entry-sr.cc>
-
-std::ostream &
-paludis::operator<< (std::ostream & s, const DepListEntry & e)
-{
- s << e.name << "-" << e.version << ":"
- << e.metadata->slot << "::" << e.repository;
- return s;
-}
+#include <paludis/dep_list-sr.cc>
DepListError::DepListError(const std::string & m) throw () :
Exception(m)
{
}
-DepListStackTooDeepError::DepListStackTooDeepError(int level) throw () :
- DepListError("DepList stack too deep (" + stringify(level) + " entries)")
-{
-}
-
-NoResolvableOptionError::NoResolvableOptionError() throw () :
- DepListError("No resolvable || ( ) option")
+AllMaskedError::AllMaskedError(const std::string & q) throw () :
+ DepListError("Error searching for '" + q + "': no available versions"),
+ _query(q)
{
}
-template <typename I_>
-NoResolvableOptionError::NoResolvableOptionError(I_ i, I_ end) throw () :
- DepListError("No resolvable || ( ) option." + (i == end ?
- std::string("") : " Failure messages are '" + join(i, end, "', '") + "'"))
+UseRequirementsNotMetError::UseRequirementsNotMetError(const std::string & q) throw () :
+ DepListError("Error searching for '" + q + "': use requirements are not met"),
+ _query(q)
{
}
-AllMaskedError::AllMaskedError(const std::string & our_query) throw () :
- DepListError("Error searching for '" + our_query + "': no available versions"),
- _query(our_query)
-{
-}
-
-UseRequirementsNotMetError::UseRequirementsNotMetError(const std::string & our_query) throw () :
- DepListError("Error searching for '" + our_query + "': use requirements are not met"),
- _query(our_query)
+BlockError::BlockError(const std::string & msg) throw () :
+ DepListError("Block: " + msg)
{
}
-BlockError::BlockError(const std::string & msg) throw () :
- DepListError("Block: " + msg)
+CircularDependencyError::CircularDependencyError(const std::string & msg) throw () :
+ DepListError("Circular dependency: " + msg)
{
}
-template <typename I_>
-CircularDependencyError::CircularDependencyError(I_ begin, const I_ end) throw () :
- DepListError("Circular dependency: " + join(begin, end, " -> ")),
- _cycle_size(std::distance(begin, end))
+DepListOptions::DepListOptions() :
+ reinstall(dl_reinstall_never),
+ target_type(dl_target_package),
+ upgrade(dl_upgrade_always),
+ installed_deps_pre(dl_deps_discard),
+ installed_deps_runtime(dl_deps_try_post),
+ installed_deps_post(dl_deps_try_post),
+ uninstalled_deps_pre(dl_deps_pre),
+ uninstalled_deps_runtime(dl_deps_pre_or_post),
+ uninstalled_deps_post(dl_deps_post),
+ circular(dl_circular_error)
{
+ /* when changing the above, also see src/paludis/command_line.cc. */
}
namespace paludis
{
- /**
- * Implementation data for DepList.
- */
+ typedef std::list<DepListEntry> MergeList;
+
template<>
struct Implementation<DepList> :
- InstantiationPolicy<Implementation<DepList>, instantiation_method::NonCopyableTag>,
InternalCounted<Implementation<DepList> >
{
- ///\name Provided data
- ///{
- const Environment * const environment;
- ///}
-
- ///\name Generated data
- ///{
- std::list<DepListEntry> merge_list;
- std::list<DepListEntry>::iterator merge_list_insert_pos;
- bool check_existing_only;
- bool match_found;
- const DepListEntry * current_package;
- ///}
-
- ///\name Settings
- ///{
- DepListRdependOption rdepend_post;
- bool recursive_deps;
- bool drop_circular;
- bool drop_self_circular;
- bool drop_all;
- bool ignore_installed;
- bool reinstall;
- bool no_unnecessary_upgrades;
- ///}
-
- ///\name Stack
- ///{
- int stack_depth;
- int max_stack_depth;
- ///}
-
- /// Constructor.
- Implementation(const Environment * const e) :
- environment(e),
- check_existing_only(false),
- match_found(false),
- current_package(0),
- rdepend_post(dlro_as_needed),
- recursive_deps(true),
- drop_circular(false),
- drop_self_circular(false),
- drop_all(false),
- ignore_installed(false),
- reinstall(true),
- stack_depth(0),
- max_stack_depth(100)
+ const Environment * const env;
+ DepListOptions opts;
+
+ MergeList merge_list;
+ MergeList::const_iterator current_merge_list_entry;
+ MergeList::iterator merge_list_insert_position;
+ long merge_list_generation;
+
+ const PackageDatabaseEntry * current_pde() const
{
+ if (current_merge_list_entry != merge_list.end())
+ return &current_merge_list_entry->package;
+ return 0;
}
- };
-}
-DepList::DepList(const Environment * const e) :
- PrivateImplementationPattern<DepList>(new Implementation<DepList>(e))
-{
-}
-
-DepList::~DepList()
-{
+ Implementation(const Environment * const e, const DepListOptions & o) :
+ env(e),
+ opts(o),
+ current_merge_list_entry(merge_list.end()),
+ merge_list_insert_position(merge_list.end()),
+ merge_list_generation(0)
+ {
+ }
+ };
}
namespace
{
- struct IsSkip
+ struct GenerationGreaterThan
{
+ long g;
+
+ GenerationGreaterThan(long gg) :
+ g(gg)
+ {
+ }
+
bool operator() (const DepListEntry & e) const
{
- return e.flags[dlef_skip];
+ return e.generation > g;
}
};
-}
-
-void
-DepList::add(DepAtom::ConstPointer atom)
-{
- Context context("When adding dependencies:");
-
- std::list<DepListEntry> save_merge_list(_imp->merge_list.begin(),
- _imp->merge_list.end());
-
- _imp->merge_list_insert_pos = _imp->merge_list.end();
- _add(atom);
- try
+ class DepListTransaction
{
- std::list<DepListEntry>::iterator i(_imp->merge_list.begin());
- _imp->merge_list_insert_pos = _imp->merge_list.end();
- while (i != _imp->merge_list.end())
- {
- if (! i->flags[dlef_has_predeps] && ! _imp->drop_all)
- throw InternalError(PALUDIS_HERE, "dle_has_predeps not set for " + stringify(*i));
+ protected:
+ MergeList & _list;
+ long & _generation;
+ int _initial_generation;
+ bool _committed;
+
+ public:
+ DepListTransaction(MergeList & l, long & g) :
+ _list(l),
+ _generation(g),
+ _initial_generation(g),
+ _committed(false)
+ {
+ ++_generation;
+ }
- else if (! i->flags[dlef_has_trypredeps] && ! _imp->drop_all)
+ void commit()
{
- Save<const DepListEntry *> save_current_package(
- &_imp->current_package, &*i);
- _add_in_role(_imp->environment->package_database()->fetch_repository(
- i->repository)->version_metadata(
- i->name, i->version)->deps.run_depend(),
- "runtime dependencies");
- i->flags.set(dlef_has_trypredeps);
+ _committed = true;
}
- else if (! i->flags[dlef_has_postdeps] && ! _imp->drop_all)
+ ~DepListTransaction()
{
- Save<const DepListEntry *> save_current_package(
- &_imp->current_package, &*i);
- _add_in_role(_imp->environment->package_database()->fetch_repository(
- i->repository)->version_metadata(
- i->name, i->version)->deps.post_depend(),
- "post dependencies");
- i->flags.set(dlef_has_postdeps);
+ if (! _committed)
+ _list.remove_if(GenerationGreaterThan(_initial_generation));
}
- else
- ++i;
- }
+ };
- /* remove skip entries */
- _imp->merge_list.remove_if(IsSkip());
- }
- catch (...)
+ struct MatchDepListEntryAgainstPackageDepAtom
{
- _imp->merge_list.swap(save_merge_list);
- throw;
- }
-}
+ const Environment * const env;
+ const PackageDepAtom * const a;
-void
-DepList::_add_raw(const DepAtom * const atom)
-{
-#if 0
- /// \bug VV this is debug code. remove it once we're sure this works
- std::list<DepListEntry> backup_merge_list(_imp->merge_list.begin(),
- _imp->merge_list.end());
-#endif
-
- /* keep track of stack depth */
- Save<int> old_stack_depth(&_imp->stack_depth,
- _imp->stack_depth + 1);
- if (_imp->stack_depth > _imp->max_stack_depth)
- throw DepListStackTooDeepError(_imp->stack_depth);
-
- /* we need to make sure that merge_list doesn't get h0rked in the
- * event of a failure. */
- bool merge_list_was_empty(_imp->merge_list.empty()), irange_begin_is_begin(false);
- std::list<DepListEntry>::iterator save_last, save_first, save_irange_begin, save_irange_end;
- if (! merge_list_was_empty)
- {
- save_first = _imp->merge_list.begin();
- save_last = previous(_imp->merge_list.end());
+ MatchDepListEntryAgainstPackageDepAtom(const Environment * const ee,
+ const PackageDepAtom * const aa) :
+ env(ee),
+ a(aa)
+ {
+ }
- save_irange_end = _imp->merge_list_insert_pos;
- if (_imp->merge_list_insert_pos == _imp->merge_list.begin())
- irange_begin_is_begin = true;
- else
- save_irange_begin = previous(_imp->merge_list_insert_pos);
- }
+ bool operator() (const DepListEntry & e)
+ {
+ return match_package(env, a, e);
+ }
+ };
- try
+ struct IsViableAnyDepAtomChild
{
- atom->accept(this);
- }
- catch (const InternalError &)
- {
- throw;
- }
- catch (...)
- {
- if (merge_list_was_empty)
- _imp->merge_list.clear();
- else
+ const Environment * const env;
+ const PackageDatabaseEntry * const pde;
+
+ IsViableAnyDepAtomChild(const Environment * const e, const PackageDatabaseEntry * const p) :
+ env(e),
+ pde(p)
{
- _imp->merge_list.erase(next(save_last), _imp->merge_list.end());
- _imp->merge_list.erase(_imp->merge_list.begin(), save_first);
- _imp->merge_list.erase(
- irange_begin_is_begin ? _imp->merge_list.begin() : next(save_irange_begin),
- save_irange_end);
}
-#if 0
- /// \bug VV this is debug code. remove it once we're sure this works
- if (backup_merge_list != _imp->merge_list)
+ bool operator() (PackageDepAtom::ConstPointer atom)
{
- Log::get_instance()->message(ll_warning, "Old merge_list: " + join(backup_merge_list.begin(),
- backup_merge_list.end(), " -> "));
- Log::get_instance()->message(ll_warning, "New merge_list: " + join(_imp->merge_list.begin(),
- _imp->merge_list.end(), " -> "));
- throw InternalError(PALUDIS_HERE, "merge list restore failed");
+ const UseDepAtom * const u(atom->as_use_dep_atom());
+ if (0 != u)
+ return env->query_use(u->flag(), pde) ^ u->inverse();
+ else
+ return true;
}
-#endif
- throw;
- }
+ };
}
+struct DepList::QueryVisitor :
+ DepAtomVisitorTypes::ConstVisitor
+{
+ bool result;
+ const DepList * const d;
+
+ QueryVisitor(const DepList * const dd) :
+ result(true),
+ d(dd)
+ {
+ }
+
+ void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const PackageDepAtom * const);
+ void visit(const UseDepAtom * const);
+ void visit(const AnyDepAtom * const);
+ void visit(const BlockDepAtom * const);
+ void visit(const AllDepAtom * const);
+};
+
void
-DepList::_add_in_role_raw(const DepAtom * const atom, const std::string & role)
+DepList::QueryVisitor::visit(const PlainTextDepAtom * const)
{
- Context context("When adding " + role + ":");
- _add_raw(atom);
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
}
-DepList::Iterator
-DepList::begin() const
-{
- return Iterator(_imp->merge_list.begin());
+void
+DepList::QueryVisitor::visit(const PackageDepAtom * const a)
+{
+ /* a pda matches either if we're already installed, or if we will be installed
+ * by the time the current point in the dep list is reached. */
+
+ if (! d->_imp->env->package_database()->query(*a, is_installed_only)->empty())
+ result = true;
+ else if (d->_imp->merge_list.end() != std::find_if(
+ d->_imp->merge_list.begin(),
+ d->_imp->merge_list.end(),
+ MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, a)))
+ result = true;
+ else
+ result = false;
}
-DepList::Iterator
-DepList::end() const
+void
+DepList::QueryVisitor::visit(const UseDepAtom * const a)
{
- return Iterator(_imp->merge_list.end());
+ /* for use? ( ) dep atoms, return true if we're not enabled, so that
+ * weird || ( ) cases work. */
+ if (d->_imp->env->query_use(a->flag(), d->_imp->current_pde()) ^ a->inverse())
+ {
+ result = true;
+ for (CompositeDepAtom::Iterator c(a->begin()), c_end(a->end()) ; c != c_end ; ++c)
+ {
+ (*c)->accept(this);
+ if (! result)
+ return;
+ }
+ }
+ else
+ result = true;
}
void
-DepList::visit(const AllDepAtom * const v)
+DepList::QueryVisitor::visit(const AnyDepAtom * const a)
{
- std::for_each(v->begin(), v->end(), accept_visitor(
- static_cast<DepAtomVisitorTypes::ConstVisitor *>(this)));
+ /* empty || ( ) must resolve to true */
+ std::list<DepAtom::ConstPointer> viable_children;
+ std::copy(a->begin(), a->end(), filter_inserter(std::back_inserter(viable_children),
+ IsViableAnyDepAtomChild(d->_imp->env, d->_imp->current_pde())));
+
+ result = true;
+ for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
+ {
+ (*c)->accept(this);
+ if (result)
+ return;
+ }
}
-#ifndef DOXYGEN
-struct DepListEntryMatcher :
- public std::unary_function<bool, const DepListEntry &>
+void
+DepList::QueryVisitor::visit(const BlockDepAtom * const a)
{
- const Environment * const env;
- const PackageDepAtom & atom;
+ a->blocked_atom()->accept(this);
+ result = !result;
+}
- DepListEntryMatcher(const Environment * const e, const PackageDepAtom & p) :
- env(e),
- atom(p)
+void
+DepList::QueryVisitor::visit(const AllDepAtom * const a)
+{
+ for (CompositeDepAtom::Iterator c(a->begin()), c_end(a->end()) ; c != c_end ; ++c)
{
+ (*c)->accept(this);
+ if (! result)
+ return;
}
+}
+
+struct DepList::AddVisitor :
+ DepAtomVisitorTypes::ConstVisitor
+{
+ DepList * const d;
- bool operator() (const DepListEntry & e) const
+ AddVisitor(DepList * const dd) :
+ d(dd)
{
- return match_package(env, atom, e);
}
+
+ void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const PackageDepAtom * const);
+ void visit(const UseDepAtom * const);
+ void visit(const AnyDepAtom * const);
+ void visit(const BlockDepAtom * const);
+ void visit(const AllDepAtom * const);
};
-#endif
void
-DepList::visit(const PackageDepAtom * const p)
+DepList::AddVisitor::visit(const PlainTextDepAtom * const)
{
- Context context("When resolving package dependency '" + stringify(*p) + "':");
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
+}
- PackageDatabaseEntryCollection::ConstPointer installed(
- _imp->environment->package_database()->query(*p, is_installed_only));
+void
+DepList::AddVisitor::visit(const PackageDepAtom * const a)
+{
+ Context context("When adding PackageDepAtom '" + stringify(*a) + "':");
- /* if we're installed and we don't want to upgrade unnecessarily,
- * stop if we're not on a top level target */
- if ((! installed->empty()) && (_imp->no_unnecessary_upgrades))
- if (0 != _imp->current_package)
- return;
+ /* find already installed things */
+ PackageDatabaseEntryCollection::ConstPointer already_installed(d->_imp->env->package_database()->query(
+ *a, is_installed_only));
/* are we already on the merge list? */
+ MergeList::const_iterator existing_merge_list_entry(std::find_if(d->_imp->merge_list.begin(),
+ d->_imp->merge_list.end(), MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, a)));
+ if (existing_merge_list_entry != d->_imp->merge_list.end())
{
- std::list<DepListEntry>::iterator i;
- if (_imp->merge_list.end() != ((i = std::find_if(
- _imp->merge_list.begin(),
- _imp->merge_list.end(),
- DepListEntryMatcher(_imp->environment, *p)))))
+ /* have our deps been merged already, or is this a circular dep? */
+ if (dle_no_deps == existing_merge_list_entry->state)
{
- /* what's our status? */
- if (! i->flags[dlef_has_predeps])
+ /* is a sufficiently good version installed? */
+ if (! already_installed->empty())
+ return;
+
+ if (d->_imp->opts.circular == dl_circular_discard)
{
- if (! installed->empty())
- return;
-
- else if (_imp->drop_circular)
- {
- if (_imp->current_package)
- Log::get_instance()->message(ll_warning, lc_context, "Dropping circular dependency on " +
- stringify(_imp->current_package->name) + "-" +
- stringify(_imp->current_package->version));
- return;
- }
-
- else if (_imp->current_package && _imp->drop_self_circular &&
- match_package(_imp->environment, p, _imp->current_package))
- {
- Log::get_instance()->message(ll_warning, lc_context, "Dropping self-circular dependency on " +
- stringify(_imp->current_package->name) + "-" +
- stringify(_imp->current_package->version));
- return;
- }
-
- else
- throw CircularDependencyError(i, next(i));
+ Log::get_instance()->message(ll_warning, lc_context, "Dropping circular dependency on '"
+ + stringify(existing_merge_list_entry->package) + "'");
+ return;
}
-
- if (p->tag())
- i->tag->insert(p->tag());
- return;
+ throw CircularDependencyError("Atom '" + stringify(*a) + "' matched by merge list entry '" +
+ stringify(existing_merge_list_entry->package) + "', which does not yet have its "
+ "dependencies installed");
}
+ else
+ return;
}
- /* are we allowed to install things? */
- if (_imp->check_existing_only)
- {
- _imp->match_found = ! installed->empty();
- return;
- }
-
- /* find the matching package */
- const PackageDatabaseEntry * match(0);
- VersionMetadata::ConstPointer metadata(0);
- PackageDatabaseEntryCollection::Pointer matches(0);
-
- matches = _imp->environment->package_database()->query(*p, is_uninstalled_only);
- for (PackageDatabaseEntryCollection::ReverseIterator e(matches->rbegin()),
- e_end(matches->rend()) ; e != e_end ; ++e)
- {
- /* if we're already installed, only include us if we're a better version or
- * if we're a top level target */
- /// \todo SLOTs?
- if ((! _imp->ignore_installed) && ((0 != _imp->current_package) || (! _imp->reinstall)))
- if (! installed->empty())
- if (e->version <= installed->last()->version)
- continue;
-
- /* check masks */
- if (_imp->environment->mask_reasons(*e).any())
- continue;
-
- metadata = _imp->environment->package_database()->fetch_repository(
- e->repository)->version_metadata(e->name, e->version);
- match = &*e;
- break;
- }
+ /* find installable candidates, and find the best visible candidate */
+ const PackageDatabaseEntry * best_visible_candidate(0);
+ PackageDatabaseEntryCollection::ConstPointer installable_candidates(
+ d->_imp->env->package_database()->query(*a, is_uninstalled_only));
- std::list<DepListEntry>::iterator merge_entry;
- SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Pointer tags(
- new SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Concrete);
- if (p->tag())
- tags->insert(p->tag());
- if (! match)
- {
- if (! installed->empty())
+ for (PackageDatabaseEntryCollection::ReverseIterator p(installable_candidates->rbegin()),
+ p_end(installable_candidates->rend()) ; p != p_end ; ++p)
+ if (! d->_imp->env->mask_reasons(*p).any())
{
- if (_imp->recursive_deps)
- {
- metadata = _imp->environment->package_database()->fetch_repository(
- installed->last()->repository)->version_metadata(
- installed->last()->name, installed->last()->version);
- DepListEntryFlags flags;
- flags.set(dlef_has_predeps);
- flags.set(dlef_skip);
- merge_entry = _imp->merge_list.insert(_imp->merge_list_insert_pos,
- DepListEntry(installed->last()->name,
- installed->last()->version, metadata,
- installed->last()->repository, flags, tags));
- }
- else
- return;
+ best_visible_candidate = &*p;
+ break;
}
- else if (p->use_requirements_ptr())
+
+ /* no installable candidates. if we're already installed, that's ok,
+ * otherwise error. */
+ if (! best_visible_candidate)
+ {
+ if (already_installed->empty())
{
- /* if we *could* have a match except for the AllMaskedError,
- * throw a UseRequirementsNotMetError error instead. */
- if (! _imp->environment->package_database()->query(
- p->without_use_requirements(), is_either)->empty())
- throw UseRequirementsNotMetError(stringify(*p));
+ if (a->use_requirements_ptr() && d->_imp->env->package_database()->query(
+ a->without_use_requirements(), is_either))
+ throw UseRequirementsNotMetError(stringify(*a));
else
- throw AllMaskedError(stringify(*p));
+ throw AllMaskedError(stringify(*a));
}
else
- throw AllMaskedError(stringify(*p));
- }
- else
- {
- DepListEntryFlags flags;
- merge_entry = _imp->merge_list.insert(_imp->merge_list_insert_pos,
- DepListEntry(match->name, match->version,
- metadata, match->repository, flags, tags));
- }
-
- /* if we provide things, also insert them. */
- if ((metadata->get_ebuild_interface()) && ! merge_entry->flags[dlef_skip])
- {
- DepAtom::ConstPointer provide(metadata->get_ebuild_interface()->provide());
-
- CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
-
- if (_imp->current_package)
- e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
- new PackageDatabaseEntry(
- _imp->current_package->name,
- _imp->current_package->version,
- _imp->current_package->repository));
-
- DepAtomFlattener f(_imp->environment, e.raw_pointer(), provide);
-
- for (DepAtomFlattener::Iterator pr(f.begin()), pr_end(f.end()) ; pr != pr_end ; ++pr)
{
- PackageDepAtom pp(QualifiedPackageName((*pr)->text()));
- if (_imp->merge_list.end() != std::find_if(
- _imp->merge_list.begin(), _imp->merge_list.end(),
- DepListEntryMatcher(_imp->environment, pp)))
- continue;
-
-#if 0
- VersionMetadata::Pointer p_metadata(new VersionMetadata::Ebuild(
- merge_entry->metadata->deps.parser));
- p_metadata->slot = merge_entry->metadata->slot;
- p_metadata->get_ebuild_interface()->virtual_for = stringify(merge_entry->name);
-#else
- VersionMetadata::ConstPointer p_metadata(0);
- try
- {
- p_metadata = _imp->environment->package_database()->fetch_repository(RepositoryName(
- "virtuals"))->version_metadata(pp.package(), merge_entry->version);
- }
- catch (const NoSuchPackageError & err)
- {
- Log::get_instance()->message(ll_warning, lc_context, "Error '" + stringify(err.message()) + "' ("
- + stringify(err.what()) + ") when looking for virtual '" + stringify(pp.package())
- + "' for merge entry '" + stringify(*merge_entry));
- }
-#endif
-
- if (p_metadata)
- {
- DepListEntryFlags flags;
- flags.set(dlef_has_predeps);
- flags.set(dlef_has_trypredeps);
- flags.set(dlef_has_postdeps);
- _imp->merge_list.insert(next(merge_entry),
- DepListEntry(pp.package(), merge_entry->version,
- p_metadata, RepositoryName("virtuals"), flags,
- SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Pointer(
- new SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Concrete)));
- }
+ 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());
+ return;
}
}
- Save<std::list<DepListEntry>::iterator> old_merge_list_insert_pos(
- &_imp->merge_list_insert_pos, merge_entry);
-
- Context resolved_context("Dependency resolution is '" + stringify(*merge_entry) + "':");
-
- /* new current package */
- Save<const DepListEntry *> old_current_package(&_imp->current_package,
- &*merge_entry);
-
- /* merge depends */
- if ((! merge_entry->flags[dlef_has_predeps]) && ! (_imp->drop_all))
- _add_in_role(metadata->deps.build_depend(), "build dependencies");
- merge_entry->flags.set(dlef_has_predeps);
-
- /* merge rdepends */
- if (! merge_entry->flags[dlef_has_trypredeps] && dlro_always != _imp->rdepend_post
- && ! _imp->drop_all)
+ SlotName slot(d->_imp->env->package_database()->fetch_repository(best_visible_candidate->repository)->
+ version_metadata(best_visible_candidate->name, best_visible_candidate->version)->slot);
+ PackageDatabaseEntryCollection::Pointer already_installed_in_same_slot(
+ new PackageDatabaseEntryCollection::Concrete);
+ for (PackageDatabaseEntryCollection::Iterator aa(already_installed->begin()),
+ aa_end(already_installed->end()) ; aa != aa_end ; ++aa)
+ if (d->_imp->env->package_database()->fetch_repository(aa->repository)->
+ version_metadata(aa->name, aa->version)->slot == slot)
+ already_installed_in_same_slot->insert(*aa);
+
+ /* we have an already installed version. do we want to use it? */
+ if (! already_installed_in_same_slot->empty())
{
- try
- {
- _add_in_role(metadata->deps.run_depend(), "runtime dependencies");
- merge_entry->flags.set(dlef_has_trypredeps);
- }
- catch (const CircularDependencyError &)
+ if (d->prefer_installed_over_uninstalled(*already_installed_in_same_slot->last(), *best_visible_candidate))
{
- if (dlro_never == _imp->rdepend_post)
- throw;
- else if (_imp->current_package)
- Log::get_instance()->message(ll_warning, lc_context, "Couldn't resolve runtime dependencies "
- "for " + stringify(_imp->current_package->name) + "-" +
- stringify(_imp->current_package->version) + " as build dependencies, "
- "trying them as post dependencies");
+ Log::get_instance()->message(ll_debug, lc_context, "Taking installed package '"
+ + stringify(*already_installed_in_same_slot->last()) + "' over '" + stringify(*best_visible_candidate) + "'");
+ d->add_already_installed_package(*already_installed_in_same_slot->last());
+ return;
}
+ else
+ Log::get_instance()->message(ll_debug, lc_context, "Not taking installed package '"
+ + stringify(*already_installed_in_same_slot->last()) + "' over '" + stringify(*best_visible_candidate) + "'");
}
+ else
+ Log::get_instance()->message(ll_debug, lc_context, "No installed packages in SLOT '"
+ + stringify(slot) + "', taking uninstalled package '" + stringify(*best_visible_candidate) + "'");
+
+ d->add_package(*best_visible_candidate);
}
void
-DepList::visit(const UseDepAtom * const u)
+DepList::AddVisitor::visit(const UseDepAtom * const a)
{
- CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
-
- if (_imp->current_package)
- e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
- new PackageDatabaseEntry(
- _imp->current_package->name,
- _imp->current_package->version,
- _imp->current_package->repository));
-
- if (_imp->environment->query_use(u->flag(), e.raw_pointer()) ^ u->inverse())
- std::for_each(u->begin(), u->end(), std::bind1st(std::mem_fun(&DepList::_add), this));
+ if (d->_imp->env->query_use(a->flag(), d->_imp->current_pde()) ^ a->inverse())
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
}
-#ifndef DOXYGEN
-struct IsViable :
- public std::unary_function<bool, DepAtom::ConstPointer>
-{
- const Implementation<DepList> & _impl;
- CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e;
-
- IsViable(const Implementation<DepList> & impl) :
- _impl(impl),
- e(0)
- {
- if (_impl.current_package)
- e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
- new PackageDatabaseEntry(
- _impl.current_package->name,
- _impl.current_package->version,
- _impl.current_package->repository));
- }
-
- bool operator() (DepAtom::ConstPointer a)
- {
- const UseDepAtom * const u(a->as_use_dep_atom());
- if (0 != u)
- return _impl.environment->query_use(u->flag(), e.raw_pointer()) ^ u->inverse();
- else
- return true;
- }
-};
-#endif
-
void
-DepList::visit(const AnyDepAtom * const a)
-{
- /* try to resolve each of our children in return. note the annoying
- * special case for use? () flags:
- *
- * || ( ) -> nothing
- * || ( off1? ( blah1 ) off2? ( blah2 ) blah3 ) -> blah3
- * || ( off1? ( blah1 ) off2? ( blah2 ) ) -> nothing
- * || ( ( off1? ( blah1 ) ) blah2 ) -> nothing
- *
- * we handle this by keeping a list of 'viable children'.
- */
-
+DepList::AddVisitor::visit(const AnyDepAtom * const a)
+{
+ /* annoying requirement: || ( foo? ( ... ) ) resolves to empty if !foo. */
std::list<DepAtom::ConstPointer> viable_children;
- std::copy(a->begin(), a->end(), filter_inserter(
- std::back_inserter(viable_children), IsViable(*_imp)));
+ std::copy(a->begin(), a->end(), filter_inserter(std::back_inserter(viable_children),
+ IsViableAnyDepAtomChild(d->_imp->env, d->_imp->current_pde())));
if (viable_children.empty())
- {
- if (_imp->current_package)
- Log::get_instance()->message(ll_qa, lc_context, "Package '" + stringify(*_imp->current_package)
- + "' has suspicious || ( ) block that resolves to empty");
return;
- }
- bool found(false);
- std::list<DepAtom::ConstPointer>::iterator found_i;
- for (std::list<DepAtom::ConstPointer>::iterator i(viable_children.begin()),
- i_end(viable_children.end()) ; i != i_end ; ++i)
+ /* see if any of our children is already installed. if any is, add it so that
+ * any upgrades kick in */
+ for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
{
- Save<bool> save_check(&_imp->check_existing_only, true);
- Save<bool> save_match(&_imp->match_found, true);
- _add(*i);
- if ((found = _imp->match_found))
+ if (d->already_installed(*c))
{
- found_i = i;
- break;
+ d->add(*c);
+ return;
}
}
- if (found)
- {
- if (_imp->recursive_deps && ! _imp->check_existing_only)
- _add(*found_i);
- return;
- }
- if (_imp->check_existing_only)
- {
- _imp->match_found = false;
- return;
- }
-
- /* try to merge each of our viable children in turn. */
- std::list<std::string> errors;
- for (CompositeDepAtom::Iterator i(viable_children.begin()), i_end(viable_children.end()) ;
- i != i_end ; ++i)
+ /* install first available viable option */
+ for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
{
try
{
- _add(*i);
+ d->add(*c);
return;
}
- catch (const DepListStackTooDeepError &)
- {
- /* don't work around a stack too deep error. our item may be
- * resolvable with a deeper stack. */
- throw;
- }
catch (const DepListError & e)
{
- errors.push_back(e.message() + " (" + e.what() + ")");
}
}
- /* no match */
- throw NoResolvableOptionError(errors.begin(), errors.end());
+ Log::get_instance()->message(ll_warning, lc_context, "No resolvable item in || ( ) block. Using "
+ "first item for error message");
+ d->add(*viable_children.begin());
}
void
-DepList::visit(const BlockDepAtom * const d)
+DepList::AddVisitor::visit(const BlockDepAtom * const a)
{
- Context context("When checking block '!" + stringify(*(d->blocked_atom())) + "':");
+ if (! d->already_installed(a->blocked_atom()))
+ return;
+
+ Context context("When checking BlockDepAtom '!" + stringify(*a->blocked_atom()) + "':");
/* special case: the provider of virtual/blah can DEPEND upon !virtual/blah. */
/* special case: foo/bar can DEPEND upon !foo/bar. */
- /* are we already installed? */
- PackageDatabaseEntryCollection::ConstPointer installed(_imp->environment->package_database()->
- query(d->blocked_atom(), is_installed_only));
- if (! installed->empty())
+ if (d->_imp->current_pde())
{
- if (! _imp->current_package)
- throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by installed package '"
- + stringify(*installed->last()) + "' (no current package)");
+ if (d->_imp->current_pde()->name == a->blocked_atom()->package())
+ {
+ Log::get_instance()->message(ll_debug, lc_context, "Ignoring self block '"
+ + stringify(*a->blocked_atom()) + "' for package '"
+ + stringify(*d->_imp->current_pde()) + "'");
+ return;
+ }
- for (PackageDatabaseEntryCollection::Iterator ii(installed->begin()),
- ii_end(installed->end()) ; ii != ii_end ; ++ii)
+ VersionMetadata::ConstPointer metadata(d->_imp->env->package_database()->fetch_repository(
+ d->_imp->current_pde()->repository)->version_metadata(d->_imp->current_pde()->name,
+ d->_imp->current_pde()->version));
+ if (metadata->get_ebuild_interface())
{
- if (_imp->current_package->name == ii->name)
+ bool skip(false);
+ DepAtomFlattener f(d->_imp->env, d->_imp->current_pde(), metadata->get_ebuild_interface()->provide());
+ for (DepAtomFlattener::Iterator i(f.begin()), i_end(f.end()) ; i != i_end && ! skip ; ++i)
+ if ((*i)->text() == stringify(a->blocked_atom()->package()))
+ skip = true;
+
+ if (skip)
{
- Log::get_instance()->message(ll_qa, lc_context, "Package '" + stringify(*_imp->current_package)
- + "' has suspicious block upon '!" + stringify(*d->blocked_atom()) + "'");
- continue;
+ Log::get_instance()->message(ll_debug, lc_context,
+ "Ignoring self block (via PROVIDE) '" + stringify(*a->blocked_atom())
+ + "' for package '" + stringify(*d->_imp->current_pde()) + "'");
+ return;
}
+ }
+ }
- DepAtom::ConstPointer provide(new AllDepAtom);
- if (_imp->current_package->metadata->get_ebuild_interface())
- provide = _imp->current_package->metadata->get_ebuild_interface()->provide();
+ throw BlockError(stringify(*a->blocked_atom()));
+}
- CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
+void
+DepList::AddVisitor::visit(const AllDepAtom * const a)
+{
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+}
- e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
- new PackageDatabaseEntry(
- _imp->current_package->name,
- _imp->current_package->version,
- _imp->current_package->repository));
+DepList::DepList(const Environment * const e, const DepListOptions & o) :
+ PrivateImplementationPattern<DepList>(new Implementation<DepList>(e, o)),
+ options(_imp->opts)
+{
+}
- DepAtomFlattener f(_imp->environment, e.raw_pointer(), provide);
+DepList::~DepList()
+{
+}
- bool skip(false);
- for (IndirectIterator<DepAtomFlattener::Iterator, const StringDepAtom> i(f.begin()),
- i_end(f.end()) ; i != i_end ; ++i)
- if (QualifiedPackageName(i->text()) == d->blocked_atom()->package())
- {
- skip = true;
- break;
- }
+void
+DepList::add_in_role(DepAtom::ConstPointer atom, const std::string & role)
+{
+ Context context("When adding " + role + ":");
+ add(atom);
+}
- if (skip)
- Log::get_instance()->message(ll_qa, lc_context, "Ignoring block on '" +
- stringify(*(d->blocked_atom())) + "' in '" +
- stringify(*_imp->current_package) +
- "' which is blocked by installed package '" + stringify(*ii) +
- "' due to PROVIDE");
- else
- throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by installed package '"
- + stringify(*installed->last()) + "' when trying to install package '" +
- stringify(*_imp->current_package) + "'");
- }
- }
+void
+DepList::add(DepAtom::ConstPointer atom)
+{
+ DepListTransaction transaction(_imp->merge_list, _imp->merge_list_generation);
+ AddVisitor visitor(this);
+ atom->accept(&visitor);
+ transaction.commit();
+}
- /* will we be installed by this point? */
- std::list<DepListEntry>::iterator m(_imp->merge_list.begin());
- while (m != _imp->merge_list.end())
- {
- if (_imp->merge_list.end() != ((m = std::find_if(m, _imp->merge_list.end(),
- DepListEntryMatcher(_imp->environment, *(d->blocked_atom()))))))
- {
- if (! _imp->current_package)
- throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by pending package '"
- + stringify(*m) + "' (no current package)");
+void
+DepList::add_package(const PackageDatabaseEntry & p)
+{
+ Context context("When adding package '" + stringify(p) + "':");
- if (*_imp->current_package == *m)
- {
- Log::get_instance()->message(ll_qa,lc_context, "Package '" + stringify(*_imp->current_package)
- + "' has suspicious block upon '!" + stringify(*d->blocked_atom()) + "'");
- ++m;
- continue;
- }
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position);
- DepAtom::ConstPointer provide(new AllDepAtom);
- if (_imp->current_package->metadata->get_ebuild_interface())
- provide = _imp->current_package->metadata->get_ebuild_interface()->provide();
+ VersionMetadata::ConstPointer metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version));
- CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e(0);
+ /* create our merge list entry. insert pre deps before ourself in the list. insert
+ * post deps after ourself, and after any provides. */
+ MergeList::iterator our_merge_entry_position(
+ _imp->merge_list.insert(_imp->merge_list_insert_position,
+ DepListEntry::create()
+ .package(p)
+ .metadata(metadata)
+ .generation(_imp->merge_list_generation)
+ .state(dle_no_deps)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .already_installed(false))),
+ our_merge_entry_post_position(our_merge_entry_position);
- e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
- new PackageDatabaseEntry(
- _imp->current_package->name,
- _imp->current_package->version,
- _imp->current_package->repository));
+ Save<MergeList::const_iterator> save_current_merge_list_entry(&_imp->current_merge_list_entry,
+ our_merge_entry_position);
- DepAtomFlattener f(_imp->environment, e.raw_pointer(), provide);
+ _imp->merge_list_insert_position = our_merge_entry_position;
- bool skip(false);
- for (IndirectIterator<DepAtomFlattener::Iterator, const StringDepAtom> i(f.begin()),
- i_end(f.end()) ; i != i_end ; ++i)
- if (QualifiedPackageName(i->text()) == d->blocked_atom()->package())
- {
- skip = true;
- break;
- }
+ /* add provides */
+ if (metadata->get_ebuild_interface())
+ {
+ DepAtomFlattener f(_imp->env, _imp->current_pde(), metadata->get_ebuild_interface()->provide());
+ for (DepAtomFlattener::Iterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
+ {
+ PackageDepAtom::Pointer pp(new PackageDepAtom("=" + (*i)->text() + "-" + stringify(p.version)));
+ if (_imp->merge_list.end() != std::find_if(_imp->merge_list.begin(),
+ _imp->merge_list.end(), MatchDepListEntryAgainstPackageDepAtom(_imp->env,
+ pp.raw_pointer())))
+ continue;
- if (skip)
- Log::get_instance()->message(ll_qa, lc_context, "Ignoring block on '" +
- stringify(*(d->blocked_atom())) + "' in '" +
- stringify(*_imp->current_package) +
- "' which is blocked by pending package '" + stringify(*m) +
- "' due to PROVIDE");
+ VersionMetadata::ConstPointer m(0);
+
+ if (_imp->env->package_database()->fetch_repository(RepositoryName("virtuals"))->has_version(
+ QualifiedPackageName((*i)->text()), p.version))
+ m = _imp->env->package_database()->fetch_repository(RepositoryName("virtuals"))->version_metadata(
+ QualifiedPackageName((*i)->text()), p.version);
else
- throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by pending package '"
- + stringify(*m) + "' when trying to install '"
- + stringify(*_imp->current_package) + "'");
+ {
+ VersionMetadata::Pointer mm(0);
+ mm.assign(new VersionMetadata::Virtual(metadata->deps.parser,
+ PackageDatabaseEntry(p.name, p.version, RepositoryName("virtuals"))));
+ mm->slot = metadata->slot;
+ m = mm;
+ }
- ++m;
+ our_merge_entry_post_position = _imp->merge_list.insert(next(our_merge_entry_post_position),
+ DepListEntry(DepListEntry::create()
+ .package(PackageDatabaseEntry((*i)->text(), p.version, RepositoryName("virtuals")))
+ .metadata(m)
+ .generation(_imp->merge_list_generation)
+ .state(dle_has_all_deps)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .already_installed(false)));
}
}
-}
-void
-DepList::set_rdepend_post(const DepListRdependOption value)
-{
- _imp->rdepend_post = value;
-}
+ /* add pre dependencies */
+ add_predeps(metadata->deps.build_depend(), _imp->opts.uninstalled_deps_pre, "build");
+ add_predeps(metadata->deps.run_depend(), _imp->opts.uninstalled_deps_runtime, "run");
+ add_predeps(metadata->deps.post_depend(), _imp->opts.uninstalled_deps_post, "post");
-void
-DepList::set_drop_circular(const bool value)
-{
- _imp->drop_circular = value;
+ our_merge_entry_position->state = dle_has_pre_deps;
+ _imp->merge_list_insert_position = next(our_merge_entry_post_position);
+
+ add_postdeps(metadata->deps.build_depend(), _imp->opts.uninstalled_deps_pre, "build");
+ add_postdeps(metadata->deps.run_depend(), _imp->opts.uninstalled_deps_runtime, "run");
+ add_postdeps(metadata->deps.post_depend(), _imp->opts.uninstalled_deps_post, "post");
+
+ our_merge_entry_position->state = dle_has_all_deps;
}
void
-DepList::set_drop_self_circular(const bool value)
+DepList::add_predeps(DepAtom::ConstPointer d, const DepListDepsOption opt, const std::string & s)
{
- _imp->drop_self_circular = value;
+ if (dl_deps_pre == opt || dl_deps_pre_or_post == opt)
+ {
+ try
+ {
+ add_in_role(d, s + " dependencies as pre dependencies");
+ }
+ catch (const DepListError & e)
+ {
+ if (dl_deps_pre == opt)
+ throw;
+ else
+ Log::get_instance()->message(ll_warning, lc_context, "Dropping " + s + " dependencies to "
+ "post dependencies because of exception '" + e.message() + "' (" + e.what() + ")");
+ }
+ }
}
void
-DepList::set_drop_all(const bool value)
+DepList::add_postdeps(DepAtom::ConstPointer d, const DepListDepsOption opt, const std::string & s)
{
- _imp->drop_all = value;
+ if (dl_deps_pre_or_post == opt || dl_deps_post == opt || dl_deps_try_post == opt)
+ {
+ try
+ {
+ add_in_role(d, s + " dependencies as post dependencies");
+ }
+ catch (const DepListError & e)
+ {
+ if (dl_deps_try_post != opt)
+ throw;
+ else
+ Log::get_instance()->message(ll_warning, lc_context, "Ignoring " + s +
+ " dependencies due to exception '" + e.message() + "' (" + e.what() + ")");
+ }
+ }
}
void
-DepList::set_ignore_installed(const bool value)
+DepList::add_already_installed_package(const PackageDatabaseEntry & p)
{
- _imp->ignore_installed = value;
+ Context context("When adding installed package '" + stringify(p) + "':");
+
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position);
+ VersionMetadata::ConstPointer metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version));
+
+ MergeList::iterator our_merge_entry(_imp->merge_list.insert(_imp->merge_list_insert_position,
+ DepListEntry::create()
+ .package(p)
+ .metadata(metadata)
+ .generation(_imp->merge_list_generation)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .state(dle_has_pre_deps)
+ .already_installed(true)));
+
+ Save<MergeList::const_iterator> save_current_merge_list_entry(&_imp->current_merge_list_entry,
+ our_merge_entry);
+
+ add_predeps(metadata->deps.build_depend(), _imp->opts.installed_deps_pre, "build");
+ add_predeps(metadata->deps.run_depend(), _imp->opts.installed_deps_runtime, "run");
+ add_predeps(metadata->deps.post_depend(), _imp->opts.installed_deps_post, "post");
+
+ our_merge_entry->state = dle_has_pre_deps;
+ _imp->merge_list_insert_position = next(our_merge_entry);
+
+ add_postdeps(metadata->deps.build_depend(), _imp->opts.installed_deps_pre, "build");
+ add_postdeps(metadata->deps.run_depend(), _imp->opts.installed_deps_runtime, "run");
+ add_postdeps(metadata->deps.post_depend(), _imp->opts.installed_deps_post, "post");
}
-void
-DepList::set_recursive_deps(const bool value)
+bool
+DepList::prefer_installed_over_uninstalled(const PackageDatabaseEntry & installed,
+ const PackageDatabaseEntry & uninstalled)
{
- _imp->recursive_deps = value;
+ if (dl_target_package == _imp->opts.target_type)
+ if (! _imp->current_pde())
+ return false;
+
+ if (dl_reinstall_always == _imp->opts.reinstall)
+ return false;
+
+ if (dl_upgrade_as_needed == _imp->opts.upgrade)
+ return true;
+
+ /* use != rather than > to correctly force a downgrade when packages are
+ * removed. */
+ if (uninstalled.version != installed.version)
+ return false;
+
+ /* todo: check dl_reinstall_if_use_changed */
+
+ return true;
}
-void
-DepList::set_max_stack_depth(const int value)
+bool
+DepList::already_installed(DepAtom::ConstPointer atom) const
{
- _imp->max_stack_depth = value;
+ return already_installed(atom.raw_pointer());
}
-void
-DepList::visit(const PlainTextDepAtom * const t)
+bool
+DepList::already_installed(const DepAtom * const atom) const
{
- throw InternalError(PALUDIS_HERE, "Got unexpected PlainTextDepAtom '" + t->text() + "'");
+ QueryVisitor visitor(this);
+ atom->accept(&visitor);
+ return visitor.result;
}
-void
-DepList::set_reinstall(const bool value)
+DepList::Iterator
+DepList::begin() const
{
- _imp->reinstall = value;
+ return Iterator(_imp->merge_list.begin());
}
-void
-DepList::set_no_unnecessary_upgrades(const bool value)
+DepList::Iterator
+DepList::end() const
{
- _imp->no_unnecessary_upgrades = value;
+ return Iterator(_imp->merge_list.end());
}
diff --git a/paludis/dep_list.hh b/paludis/dep_list.hh
index 7ce3482..a8c4b92 100644
--- a/paludis/dep_list.hh
+++ b/paludis/dep_list.hh
@@ -35,87 +35,64 @@
namespace paludis
{
- /**
- * Flags for a DepListEntry.
- *
- * \see DepListEntry
- * \ingroup grpdepresolver
- */
- enum DepListEntryFlag
+ enum DepListTargetType
{
- dlef_has_predeps,
- dlef_has_trypredeps,
- dlef_has_postdeps,
- dlef_skip,
- last_dlef
+ dl_target_package,
+ dl_target_set
};
- /**
- * Flags for a DepListEntry.
- *
- * \ingroup grpdepresolver
- */
- typedef std::bitset<last_dlef> DepListEntryFlags;
-
-#include <paludis/dep_list_entry-sr.hh>
-
- /**
- * A DepListEntry can be written to a stream.
- *
- * \ingroup grpdepresolver
- */
- std::ostream & operator<< (std::ostream &, const DepListEntry &);
+ enum DepListReinstallOption
+ {
+ dl_reinstall_never,
+ dl_reinstall_always,
+ dl_reinstall_if_use_changed
+ };
- /**
- * Thrown if an error occurs whilst building a DepList.
- *
- * \ingroup grpdepresolver
- * \ingroup grpexceptions
- */
- class DepListError : public Exception
+ enum DepListUpgradeOption
{
- protected:
- ///\name Basic operations
- ///\{
+ dl_upgrade_always,
+ dl_upgrade_as_needed
+ };
- DepListError(const std::string &) throw ();
+ enum DepListDepsOption
+ {
+ dl_deps_discard,
+ dl_deps_pre,
+ dl_deps_pre_or_post,
+ dl_deps_post,
+ dl_deps_try_post
+ };
- ///\}
+ enum DepListCircularOption
+ {
+ dl_circular_error,
+ dl_circular_discard
};
- /**
- * Thrown if a DepList's add stack gets too deep.
- *
- * \ingroup grpdepresolver
- * \ingroup grpexceptions
- */
- class DepListStackTooDeepError : public DepListError
+ enum DepListEntryState
{
- public:
- ///\name Basic operations
- ///\{
+ dle_no_deps,
+ dle_has_pre_deps,
+ dle_has_all_deps
+ };
- DepListStackTooDeepError(int level) throw ();
+ typedef SortedCollection<DepTag::ConstPointer, DepTag::Comparator> DepListEntryTags;
- ///\}
- };
+#include <paludis/dep_list-sr.hh>
/**
- * Thrown if no entry in a || ( ) block is resolvable.
+ * Thrown if an error occurs whilst building a DepList.
*
* \ingroup grpdepresolver
* \ingroup grpexceptions
*/
- class NoResolvableOptionError : public DepListError
+ class DepListError : public Exception
{
- public:
+ protected:
///\name Basic operations
///\{
- NoResolvableOptionError() throw ();
-
- template <typename I_>
- NoResolvableOptionError(I_ i, I_ end) throw ();
+ DepListError(const std::string &) throw ();
///\}
};
@@ -210,49 +187,13 @@ namespace paludis
*/
class CircularDependencyError : public DepListError
{
- private:
- unsigned _cycle_size;
-
public:
///\name Basic operations
///\{
- template <typename I_>
- CircularDependencyError(I_ begin, const I_ end) throw ();
+ CircularDependencyError(const std::string & msg) throw ();
///\}
-
- /**
- * How large is our circular dependency cycle?
- */
- unsigned cycle_size() const
- {
- return _cycle_size;
- }
- };
-
- /**
- * Used in DepList::set_rdepend_post.
- *
- * \ingroup grpdepresolver
- */
- enum DepListRdependOption
- {
- /**
- * RDEPENDs are always merged before the package; abort if this fails.
- */
- dlro_never,
-
- /**
- * RDEPENDs can be merged after the package, just before PDEPEND, if this is
- * necessary for correct resolution
- */
- dlro_as_needed,
-
- /**
- * RDEPENDs are always merged with PDEPENDs.
- */
- dlro_always
};
/**
@@ -262,113 +203,62 @@ namespace paludis
*/
class DepList :
private InstantiationPolicy<DepList, instantiation_method::NonCopyableTag>,
- private PrivateImplementationPattern<DepList>,
- protected DepAtomVisitorTypes::ConstVisitor
+ private PrivateImplementationPattern<DepList>
{
- private:
- void _add_raw(const DepAtom * const);
-
- void _add(DepAtom::ConstPointer a)
- {
- _add_raw(a.raw_pointer());
- }
-
- void _add_in_role_raw(const DepAtom * const, const std::string & role);
+ protected:
+ class AddVisitor;
+ class QueryVisitor;
- void _add_in_role(DepAtom::ConstPointer a, const std::string & role)
- {
- _add_in_role_raw(a.raw_pointer(), role);
- }
+ friend class AddVisitor;
+ friend class QueryVisitor;
- protected:
- ///\name Visit functions
- ///{
- void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn));
- void visit(const PackageDepAtom * const);
- void visit(const UseDepAtom * const);
- void visit(const AnyDepAtom * const);
- void visit(const BlockDepAtom * const);
- void visit(const AllDepAtom * const);
- ///}
+ void add_in_role(DepAtom::ConstPointer, const std::string & role);
+ bool prefer_installed_over_uninstalled(const PackageDatabaseEntry &,
+ const PackageDatabaseEntry &);
+ void add_package(const PackageDatabaseEntry &);
+ void add_already_installed_package(const PackageDatabaseEntry &);
+ void add_predeps(DepAtom::ConstPointer, const DepListDepsOption, const std::string &);
+ void add_postdeps(DepAtom::ConstPointer, const DepListDepsOption, const std::string &);
public:
///\name Basic operations
///\{
- DepList(const Environment * const);
+ DepList(const Environment * const, const DepListOptions &);
virtual ~DepList();
///\}
/**
- * Add the packages required to resolve an additional dependency
- * atom.
+ * Our options.
*/
- void add(DepAtom::ConstPointer);
-
- ///\name Iterate over our dependency list entries.
- ///\{
-
- typedef libwrapiter::ForwardIterator<DepList, const DepListEntry> Iterator;
-
- Iterator begin() const;
-
- Iterator end() const;
-
- ///\}
-
- ///\name Behaviour options
- ///\{
-
- /**
- * Behaviour: determines when RDEPEND entries can be treated as PDEPEND.
- */
- void set_rdepend_post(const DepListRdependOption value);
-
- /**
- * Behaviour: if set, a package that depends directly upon itself
- * will be accepted.
- */
- void set_drop_self_circular(const bool value);
+ DepListOptions & options;
/**
- * Behaviour: if set, any circular dependencies are treated as if
- * they do not exist.
+ * Add the packages required to resolve an additional dependency
+ * atom.
*/
- void set_drop_circular(const bool value);
+ void add(DepAtom::ConstPointer);
/**
- * Behaviour: if set, any dependencies are treated as if
- * they do not exist.
+ * Is an atom structure already installed?
*/
- void set_drop_all(const bool value);
+ bool already_installed(DepAtom::ConstPointer) const;
/**
- * Behaviour: ignore installed packages.
+ * Is an atom structure already installed (overloaded for raw pointer)?
*/
- void set_ignore_installed(const bool value);
+ bool already_installed(const DepAtom * const) const;
- /**
- * Behaviour: check nth level dependencies for packages that are
- * already installed.
- */
- void set_recursive_deps(const bool value);
+ ///\name Iterate over our dependency list entries.
+ ///\{
- /**
- * Behaviour: set the maximum stack depth.
- */
- void set_max_stack_depth(const int value);
+ typedef libwrapiter::ForwardIterator<DepList, const DepListEntry> Iterator;
- /**
- * Behaviour: set whether we reinstall first level deps.
- */
- void set_reinstall(const bool value);
+ Iterator begin() const;
- /**
- * Behaviour: set whether we upgrade unnecessarily.
- */
- void set_no_unnecessary_upgrades(const bool value);
+ Iterator end() const;
///\}
};
diff --git a/paludis/dep_list.sr b/paludis/dep_list.sr
new file mode 100644
index 0000000..090ceae
--- /dev/null
+++ b/paludis/dep_list.sr
@@ -0,0 +1,39 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_DepListOptions()
+{
+ key reinstall DepListReinstallOption
+ key target_type DepListTargetType
+ key upgrade DepListUpgradeOption
+
+ key installed_deps_pre DepListDepsOption
+ key installed_deps_runtime DepListDepsOption
+ key installed_deps_post DepListDepsOption
+
+ key uninstalled_deps_pre DepListDepsOption
+ key uninstalled_deps_runtime DepListDepsOption
+ key uninstalled_deps_post DepListDepsOption
+
+ key circular DepListCircularOption
+
+ extra_constructors <<END
+ DepListOptions();
+END
+
+ allow_named_args
+}
+
+make_class_DepListEntry()
+{
+ key package PackageDatabaseEntry
+ key metadata VersionMetadata::ConstPointer
+ key tags DepListEntryTags::Pointer
+
+ key generation long
+ key state DepListEntryState
+ key already_installed bool
+
+ allow_named_args
+}
+
diff --git a/paludis/dep_list_TEST.cc b/paludis/dep_list_TEST.cc
index b1a27af..c24a4f6 100644
--- a/paludis/dep_list_TEST.cc
+++ b/paludis/dep_list_TEST.cc
@@ -20,15 +20,28 @@
#include <paludis/paludis.hh>
#include <paludis/repositories/fake/fake_repository.hh>
#include <paludis/repositories/fake/fake_installed_repository.hh>
+#include <paludis/repositories/virtuals/virtuals_repository.hh>
#include <paludis/environment/test/test_environment.hh>
#include <test/test_framework.hh>
#include <test/test_runner.hh>
#include <string>
#include <list>
+#include <ostream>
using namespace paludis;
using namespace test;
+namespace paludis
+{
+ std::ostream &
+ operator<< (std::ostream & s, const DepListEntry & e)
+ {
+ s << e.package.name << "-" << e.package.version << ":" <<
+ e.metadata->slot << "::" << e.package.repository;
+ return s;
+ }
+}
+
namespace test_cases
{
/**
@@ -39,14 +52,13 @@ namespace test_cases
class DepListTestCaseBase :
public TestCase
{
-#ifndef DOXYGEN
protected:
TestEnvironment env;
FakeRepository::Pointer repo;
+ VirtualsRepository::Pointer virtuals_repo;
std::list<std::string> expected;
std::string merge_target;
bool done_populate;
-#endif
/**
* Constructor.
@@ -55,9 +67,11 @@ namespace test_cases
TestCase("dep list " + stringify(i)),
env(),
repo(new FakeRepository(RepositoryName("repo"))),
+ virtuals_repo(new VirtualsRepository(&env)),
done_populate(false)
{
env.package_database()->add_repository(repo);
+ env.package_database()->add_repository(virtuals_repo);
}
/**
@@ -76,7 +90,7 @@ namespace test_cases
virtual void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
d.add(PortageDepParser::parse(merge_target));
TEST_CHECK(true);
@@ -992,7 +1006,7 @@ namespace test_cases
void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
TEST_CHECK(d.begin() == d.end());
}
@@ -1020,7 +1034,7 @@ namespace test_cases
void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
TEST_CHECK(d.begin() == d.end());
}
@@ -1088,7 +1102,7 @@ namespace test_cases
void populate_expected()
{
merge_target="cat/one";
- expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
expected.push_back("cat/one-1:0::repo");
}
} test_dep_list_43;
@@ -1177,7 +1191,7 @@ namespace test_cases
void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
TEST_CHECK(d.begin() == d.end());
}
@@ -1204,7 +1218,7 @@ namespace test_cases
void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
TEST_CHECK(d.begin() == d.end());
}
@@ -1273,7 +1287,7 @@ namespace test_cases
void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
TEST_CHECK(d.begin() == d.end());
}
@@ -1300,13 +1314,144 @@ namespace test_cases
void check_lists()
{
TEST_CHECK(true);
- DepList d(&env);
+ DepList d(&env, DepListOptions());
TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
TEST_CHECK(d.begin() == d.end());
}
} test_dep_list_52;
/**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase53 : DepListTestCase<53>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_53;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase54 : DepListTestCase<54>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_54;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase55 : DepListTestCase<55>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/one";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_55;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase56 : DepListTestCase<56>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two || ( cat/three cat/four )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->provide_string = "cat/four";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/four-1:0::virtuals");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_56;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase57 : DepListTestCase<57>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/one";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_57;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase58 : DepListTestCase<58>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->get_ebuild_interface()->provide_string = "cat/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/two-1:0::virtuals");
+ }
+ } test_dep_list_58;
+
+ /**
* \test Test DepList transactional add behaviour.
*
* \ingroup Test
@@ -1329,7 +1474,7 @@ namespace test_cases
repo->add_version("cat", "six", "1");
repo->add_version("cat", "seven", "1")->deps.build_depend_string = "cat/doesnotexist";
- DepList d(&env);
+ DepList d(&env, DepListOptions());
d.add(PortageDepParser::parse("cat/one"));
TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "),
"cat/four-1:0::repo cat/two-1:0::repo cat/three-1:0::repo cat/one-1:0::repo");
@@ -1364,7 +1509,7 @@ namespace test_cases
repo->add_version("cat", "six", "1");
repo->add_version("cat", "seven", "1")->deps.post_depend_string = "cat/doesnotexist";
- DepList d(&env);
+ DepList d(&env, DepListOptions());
d.add(PortageDepParser::parse("cat/one"));
TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "),
"cat/four-1:0::repo cat/two-1:0::repo cat/three-1:0::repo cat/one-1:0::repo");
@@ -1398,7 +1543,7 @@ namespace test_cases
env.package_database()->add_repository(installed_repo);
installed_repo->add_version("cat", "one", "2");
- DepList d(&env);
+ DepList d(&env, DepListOptions());
d.add(PortageDepParser::parse("cat/one"));
TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "), "cat/one-1:0::repo");
}
diff --git a/paludis/dep_list_entry.sr b/paludis/dep_list_entry.sr
deleted file mode 100644
index 2dfeef2..0000000
--- a/paludis/dep_list_entry.sr
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-# vim: set sw=4 sts=4 et :
-
-make_class_DepListEntry()
-{
- key name QualifiedPackageName
- key version VersionSpec
- key metadata VersionMetadata::ConstPointer
- key repository RepositoryName
- key flags DepListEntryFlags
- key tag "SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Pointer"
-
- doxygen_comment << "END"
- /**
- * Holds a single entry in a DepList.
- *
- * \see DepList
- * \ingroup grpdepresolver
- */
-END
-
- comparison_operators equality all
-}
-
-
diff --git a/paludis/files.m4 b/paludis/files.m4
index 1bc9b9d..cf1a608 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -14,8 +14,7 @@ add(`contents', `hh', `cc')
add(`dep_atom', `hh', `cc', `test')
add(`dep_atom_flattener', `hh', `cc')
add(`dep_atom_pretty_printer', `hh', `cc')
-add(`dep_list', `hh', `cc', `test')
-add(`dep_list_entry', `sr')
+add(`dep_list', `hh', `cc', `test', `sr')
add(`dep_tag', `hh', `cc')
add(`ebin', `hh', `cc', `sr')
add(`ebuild', `hh', `cc', `sr')
diff --git a/paludis/match_package.cc b/paludis/match_package.cc
index 4d78457..b0e25ab 100644
--- a/paludis/match_package.cc
+++ b/paludis/match_package.cc
@@ -89,15 +89,15 @@ match_package_internals::do_match(
const PackageDepAtom * const atom,
const DepListEntry * const entry)
{
- if (atom->package() != entry->name)
+ if (atom->package() != entry->package.name)
return false;
- if (atom->version_spec_ptr() && ! (((entry->version).*
+ if (atom->version_spec_ptr() && ! (((entry->package.version).*
(atom->version_operator().as_version_spec_operator()))
(*atom->version_spec_ptr())))
return false;
- if (atom->repository_ptr() && (*atom->repository_ptr() != entry->repository))
+ if (atom->repository_ptr() && (*atom->repository_ptr() != entry->package.repository))
return false;
if (atom->slot_ptr() && (*atom->slot_ptr() != entry->metadata->slot))
@@ -105,9 +105,6 @@ match_package_internals::do_match(
if (atom->use_requirements_ptr())
{
- PackageDatabaseEntry e(entry->name, entry->version,
- entry->repository);
-
for (UseRequirements::Iterator u(atom->use_requirements_ptr()->begin()),
u_end(atom->use_requirements_ptr()->end()) ; u != u_end ; ++u)
{
@@ -117,12 +114,12 @@ match_package_internals::do_match(
continue;
case use_enabled:
- if (! env->query_use(u->first, &e))
+ if (! env->query_use(u->first, &entry->package))
return false;
continue;
case use_disabled:
- if (env->query_use(u->first, &e))
+ if (env->query_use(u->first, &entry->package))
return false;
continue;
}
diff --git a/paludis/repositories/virtuals/virtuals_repository.cc b/paludis/repositories/virtuals/virtuals_repository.cc
index 51145f3..631d958 100644
--- a/paludis/repositories/virtuals/virtuals_repository.cc
+++ b/paludis/repositories/virtuals/virtuals_repository.cc
@@ -82,39 +82,56 @@ VirtualsRepository::need_entries() const
Context context("When loading entries for virtuals repository:");
- /* Populate our _imp->entries. We need to iterate over each repository in
- * our env's package database, see if it has a virtuals interface, and if it
- * does create an entry for each virtual package. */
+ /* Determine our virtual name -> package mappings. */
+ std::map<QualifiedPackageName, PackageDepAtom::ConstPointer> virtual_to_real;
+
+ for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
+ r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
+ {
+ if (! (*r)->provides_interface)
+ continue;
+
+ RepositoryProvidesInterface::ProvidesCollection::ConstPointer provides(
+ (*r)->provides_interface->provided_packages());
+ for (RepositoryProvidesInterface::ProvidesCollection::Iterator p(provides->begin()),
+ p_end(provides->end()) ; p != p_end ; ++p)
+ virtual_to_real.insert(std::make_pair(p->virtual_name, PackageDepAtom::Pointer(
+ new PackageDepAtom(stringify(p->provided_by_name)))));
+ }
+
for (PackageDatabase::RepositoryIterator r(_imp->env->package_database()->begin_repositories()),
r_end(_imp->env->package_database()->end_repositories()) ; r != r_end ; ++r)
{
if (! (*r)->virtuals_interface)
continue;
- RepositoryVirtualsInterface::VirtualsCollection::ConstPointer pp(
+ RepositoryVirtualsInterface::VirtualsCollection::ConstPointer virtuals(
(*r)->virtuals_interface->virtual_packages());
+ for (RepositoryVirtualsInterface::VirtualsCollection::Iterator v(virtuals->begin()),
+ v_end(virtuals->end()) ; v != v_end ; ++v)
+ virtual_to_real.insert(std::make_pair(v->virtual_name, v->provided_by_atom));
+ }
+
+ /* Populate our _imp->entries. */
+ for (std::map<QualifiedPackageName, PackageDepAtom::ConstPointer>::const_iterator
+ v(virtual_to_real.begin()), v_end(virtual_to_real.end()) ; v != v_end ; ++v)
+ {
+ PackageDatabaseEntryCollection::ConstPointer matches(_imp->env->package_database()->query(v->second,
+ is_uninstalled_only));
+
+ if (matches->empty())
+ Log::get_instance()->message(ll_warning, lc_context, "No packages matching '"
+ + stringify(*v->second) + "' for virtual '"
+ + stringify(v->first));
- for (RepositoryVirtualsInterface::VirtualsCollection::Iterator p(
- pp->begin()), p_end(pp->end()) ; p != p_end ; ++p)
+ for (PackageDatabaseEntryCollection::Iterator m(matches->begin()), m_end(matches->end()) ;
+ m != m_end ; ++m)
{
- VersionSpecCollection::ConstPointer vv((*r)->version_specs(p->provided_by_atom->package()));
-
- /* following is debug, not warning, because of overlay style repos */
- if (vv->empty())
- Log::get_instance()->message(ll_debug, lc_context, "No packages matching '"
- + stringify(*p->provided_by_atom) + "' for virtual '"
- + stringify(p->virtual_name) + " ' in repository '"
- + stringify((*r)->name()) + "'");
-
- for (VersionSpecCollection::Iterator v(vv->begin()), v_end(vv->end()) ;
- v != v_end ; ++v)
- if (match_package(_imp->env, p->provided_by_atom, PackageDatabaseEntry(
- p->provided_by_atom->package(), *v, (*r)->name())))
- _imp->entries.push_back(VREntry::create()
- .virtual_name(p->virtual_name)
- .version(*v)
- .provided_by_name(p->provided_by_atom->package())
- .provided_by_repository((*r)->name()));
+ _imp->entries.push_back(VREntry::create()
+ .virtual_name(v->first)
+ .version(m->version)
+ .provided_by_name(m->name)
+ .provided_by_repository(m->repository));
}
}
@@ -160,6 +177,11 @@ VirtualsRepository::do_version_metadata(
if (p.first == p.second)
throw NoSuchPackageError(stringify(PackageDatabaseEntry(q, v, name())));
+ Log::get_instance()->message(ll_debug, lc_no_context, "VirtualsRepository::do_version_metadata("
+ + stringify(q) + ", " + stringify(v) + ") lookup using '"
+ + stringify(p.first->virtual_name) + "', '" + stringify(p.first->version) + "', '"
+ + stringify(p.first->provided_by_name) + "', '" + stringify(p.first->provided_by_repository) + "'");
+
return _imp->env->package_database()->fetch_repository(
p.first->provided_by_repository)->virtuals_interface->virtual_package_version_metadata(
RepositoryVirtualsEntry::create()
diff --git a/paludis/tasks/install_task.cc b/paludis/tasks/install_task.cc
index b788d0f..942797d 100644
--- a/paludis/tasks/install_task.cc
+++ b/paludis/tasks/install_task.cc
@@ -45,9 +45,9 @@ namespace paludis
bool had_set_targets;
bool had_package_targets;
- Implementation<InstallTask>(Environment * const e) :
+ Implementation<InstallTask>(Environment * const e, const DepListOptions & o) :
env(e),
- dep_list(e),
+ dep_list(e, o),
current_dep_list_entry(dep_list.begin()),
install_options(false, false),
targets(new AllDepAtom),
@@ -70,8 +70,8 @@ HadBothPackageAndSetTargets::HadBothPackageAndSetTargets() throw () :
{
}
-InstallTask::InstallTask(Environment * const env) :
- PrivateImplementationPattern<InstallTask>(new Implementation<InstallTask>(env))
+InstallTask::InstallTask(Environment * const env, const DepListOptions & options) :
+ PrivateImplementationPattern<InstallTask>(new Implementation<InstallTask>(env, options))
{
}
@@ -80,78 +80,6 @@ InstallTask::~InstallTask()
}
void
-InstallTask::set_rdepend_post(const DepListRdependOption value)
-{
- _imp->dep_list.set_rdepend_post(value);
-}
-
-void
-InstallTask::set_drop_self_circular(const bool value)
-{
- _imp->dep_list.set_drop_self_circular(value);
-}
-
-void
-InstallTask::set_drop_circular(const bool value)
-{
- _imp->dep_list.set_drop_circular(value);
-}
-
-void
-InstallTask::set_drop_all(const bool value)
-{
- _imp->dep_list.set_drop_all(value);
-}
-
-void
-InstallTask::set_ignore_installed(const bool value)
-{
- _imp->dep_list.set_ignore_installed(value);
-}
-
-void
-InstallTask::set_recursive_deps(const bool value)
-{
- _imp->dep_list.set_recursive_deps(value);
-}
-
-void
-InstallTask::set_max_stack_depth(const int value)
-{
- _imp->dep_list.set_max_stack_depth(value);
-}
-
-void
-InstallTask::set_no_unnecessary_upgrades(const bool value)
-{
- _imp->dep_list.set_no_unnecessary_upgrades(value);
-}
-
-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;
-}
-
-void
InstallTask::add_target(const std::string & target)
{
Context context("When adding install target '" + target + "':");
@@ -167,7 +95,7 @@ InstallTask::add_target(const std::string & target)
throw HadBothPackageAndSetTargets();
_imp->had_set_targets = true;
- _imp->dep_list.set_reinstall(false);
+ _imp->dep_list.options.target_type = dl_target_set;
_imp->targets->add_child(s);
}
else
@@ -176,6 +104,7 @@ InstallTask::add_target(const std::string & target)
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));
@@ -235,7 +164,8 @@ InstallTask::execute()
dep != dep_end ; ++dep)
{
_imp->current_dep_list_entry = dep;
- on_display_merge_list_entry(*dep);
+ if (! dep->already_installed)
+ on_display_merge_list_entry(*dep);
}
/* we're done displaying our task list */
@@ -266,11 +196,13 @@ InstallTask::execute()
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->name) + "-" +
- stringify(dep->version) + "::" +
- stringify(dep->repository));
+ 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)
@@ -286,14 +218,14 @@ InstallTask::execute()
/* fetch / install one item */
const RepositoryInstallableInterface * const installable_interface(
- _imp->env->package_database()->fetch_repository(dep->repository)->
+ _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->name, dep->version, _imp->install_options);
+ installable_interface->install(dep->package.name, dep->package.version, _imp->install_options);
}
catch (const PackageInstallActionError & e)
{
@@ -329,7 +261,7 @@ InstallTask::execute()
// 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->name) + ":" +
+ stringify(dep->package.name) + ":" +
stringify(dep->metadata->slot))),
is_installed_only));
@@ -337,7 +269,7 @@ InstallTask::execute()
PackageDatabaseEntryCollection::Concrete clean_list;
for (PackageDatabaseEntryCollection::Iterator c(collision_list->begin()),
c_end(collision_list->end()) ; c != c_end ; ++c)
- if (dep->version != c->version)
+ if (dep->package.version != c->version)
clean_list.insert(*c);
on_build_cleanlist_post(*dep);
@@ -421,3 +353,27 @@ 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/paludis/tasks/install_task.hh b/paludis/tasks/install_task.hh
index 187075b..34a4cd3 100644
--- a/paludis/tasks/install_task.hh
+++ b/paludis/tasks/install_task.hh
@@ -50,7 +50,7 @@ namespace paludis
///\name Basic operations
///\{
- InstallTask(Environment * const env);
+ InstallTask(Environment * const env, const DepListOptions & options);
///\}
@@ -65,15 +65,6 @@ namespace paludis
///\name DepList and Install behaviour options
///\{
- void set_rdepend_post(const DepListRdependOption value);
- void set_drop_self_circular(const bool value);
- void set_drop_circular(const bool value);
- void set_drop_all(const bool value);
- void set_ignore_installed(const bool value);
- void set_recursive_deps(const bool value);
- void set_max_stack_depth(const int value);
- void set_no_unnecessary_upgrades(const bool value);
-
void set_no_config_protect(const bool value);
void set_fetch_only(const bool value);
void set_pretend(const bool value);
diff --git a/paludis/util/counted_ptr.hh b/paludis/util/counted_ptr.hh
index 883ee47..6c3adc9 100644
--- a/paludis/util/counted_ptr.hh
+++ b/paludis/util/counted_ptr.hh
@@ -153,7 +153,7 @@ namespace paludis
{
}
- ~CountedPtrBase()
+ virtual ~CountedPtrBase()
{
}
@@ -246,7 +246,7 @@ namespace paludis
{
}
- ~CountedPtrBase()
+ virtual ~CountedPtrBase()
{
}
diff --git a/src/adjutrix/display_default_system_resolution.cc b/src/adjutrix/display_default_system_resolution.cc
index 57f1979..7ccbf45 100644
--- a/src/adjutrix/display_default_system_resolution.cc
+++ b/src/adjutrix/display_default_system_resolution.cc
@@ -66,17 +66,16 @@ namespace
cout << std::left << std::setw(20) << (desc + ":") << display_profile << endl;
- DepList d(&env);
- d.set_reinstall(false);
- d.set_drop_circular(true);
+ DepListOptions d_options;
+ d_options.circular = dl_circular_discard;
+ DepList d(&env, d_options);
try
{
d.add(env.package_set("system"));
for (DepList::Iterator e(d.begin()), e_end(d.end()) ; e != e_end ; ++e)
- cout << " " << e->name << "-" << e->version << ":" << e->metadata->slot << "::"
- << e->repository << endl;
+ cout << " " << e->package << ":" << e->metadata->slot << endl;
}
catch (const NoSuchPackageError & e)
{
diff --git a/src/paludis/command_line.cc b/src/paludis/command_line.cc
index 1bfcda7..b836569 100644
--- a/src/paludis/command_line.cc
+++ b/src/paludis/command_line.cc
@@ -81,20 +81,73 @@ CommandLine::CommandLine() :
dl_args(this, "DepList behaviour",
"Modify dependency list generation behaviour. Use with caution."),
- a_dl_rdepend_post(&dl_args, "dl-rdepend-post", '\0', "Treat RDEPEND like PDEPEND",
- paludis::args::EnumArg::EnumArgOptions("always", "Always")
- ("never", "Never")
- ("as-needed", "To resolve circular dependencies"),
- "as-needed"),
- a_dl_drop_self_circular(&dl_args, "dl-drop-self-circular", '\0', "Drop self-circular dependencies"),
- a_dl_drop_circular(&dl_args, "dl-drop-circular", '\0', "Drop circular dependencies"),
- a_dl_drop_all(&dl_args, "dl-drop-all", '0', "Drop all dependencies"),
- a_dl_ignore_installed(&dl_args, "dl-ignore-installed", 'e', "Ignore installed packages"),
- a_dl_no_recursive_deps(&dl_args, "dl-no-recursive-deps", '\0',
- "Don't check runtime dependencies for installed packages"),
- a_dl_max_stack_depth(&dl_args, "dl-max-stack-depth", '\0', "Maximum stack depth (default 100)"),
- a_dl_no_unnecessary_upgrades(&dl_args, "dl-no-unnecessary-upgrades", 'U',
- "Don't upgrade installed packages except where necessary as a dependency of another package"),
+
+ dl_reinstall(&dl_args, "dl-reinstall", '\0', "When to reinstall packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("never", "Never")
+ ("always", "Always"),
+ "never"),
+ dl_upgrade(&dl_args, "dl-upgrade", '\0', "When to upgrade packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("always", "Always")
+ ("as-needed", "As needed"),
+ "always"),
+
+ dl_installed_deps_pre(&dl_args, "dl-installed-deps-pre", '\0', "How to handle pre dependencies for installed packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("pre", "As pre dependencies")
+ ("pre-or-post", "As pre dependencies, or post depenencies where needed")
+ ("post", "As post dependencies")
+ ("try-post", "As post dependencies, with no error for failures")
+ ("discard", "Discard"),
+ "discard"),
+ dl_installed_deps_runtime(&dl_args, "dl-installed-deps-runtime", '\0', "How to handle runtime dependencies for installed packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("pre", "As pre dependencies")
+ ("pre-or-post", "As pre dependencies, or post depenencies where needed")
+ ("post", "As post dependencies")
+ ("try-post", "As post dependencies, with no error for failures")
+ ("discard", "Discard"),
+ "try-post"),
+ dl_installed_deps_post(&dl_args, "dl-installed-deps-post", '\0', "How to handle post dependencies for installed packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("pre", "As pre dependencies")
+ ("pre-or-post", "As pre dependencies, or post depenencies where needed")
+ ("post", "As post dependencies")
+ ("try-post", "As post dependencies, with no error for failures")
+ ("discard", "Discard"),
+ "try-post"),
+
+ dl_uninstalled_deps_pre(&dl_args, "dl-uninstalled-deps-pre", '\0', "How to handle pre dependencies for uninstalled packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("pre", "As pre dependencies")
+ ("pre-or-post", "As pre dependencies, or post depenencies where needed")
+ ("post", "As post dependencies")
+ ("try-post", "As post dependencies, with no error for failures")
+ ("discard", "Discard"),
+ "pre"),
+ dl_uninstalled_deps_runtime(&dl_args, "dl-uninstalled-deps-runtime", '\0', "How to handle runtime dependencies for uninstalled packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("pre", "As pre dependencies")
+ ("pre-or-post", "As pre dependencies, or post depenencies where needed")
+ ("post", "As post dependencies")
+ ("try-post", "As post dependencies, with no error for failures")
+ ("discard", "Discard"),
+ "pre-or-post"),
+ dl_uninstalled_deps_post(&dl_args, "dl-uninstalled-deps-post", '\0', "How to handle post dependencies for uninstalled packages",
+ paludis::args::EnumArg::EnumArgOptions
+ ("pre", "As pre dependencies")
+ ("pre-or-post", "As pre dependencies, or post depenencies where needed")
+ ("post", "As post dependencies")
+ ("try-post", "As post dependencies, with no error for failures")
+ ("discard", "Discard"),
+ "post"),
+
+ dl_circular(&dl_args, "dl-circular", '\0', "How to handle circular dependencies",
+ paludis::args::EnumArg::EnumArgOptions
+ ("error", "Raise an error")
+ ("discard", "Discard"),
+ "error"),
list_args(this, "List options",
"Options relevant for one or more of the --list actions."),
@@ -107,8 +160,6 @@ CommandLine::CommandLine() :
"Options relevant for the --owner actions."),
a_full_match(&owner_args, "full-match", '\0', "Match whole filename")
{
- a_dl_max_stack_depth.set_argument(100);
-
add_usage_line("--query [query options] target ...");
add_usage_line("--install [install options] target ...");
add_usage_line("--sync [target (leave blank for all)]");
diff --git a/src/paludis/command_line.hh b/src/paludis/command_line.hh
index f4c9f25..0f3440b 100644
--- a/src/paludis/command_line.hh
+++ b/src/paludis/command_line.hh
@@ -193,29 +193,18 @@ class CommandLine :
/// DepList behaviour arguments.
paludis::args::ArgsGroup dl_args;
- /// --dl-rdepend-post
- paludis::args::EnumArg a_dl_rdepend_post;
+ paludis::args::EnumArg dl_reinstall;
+ paludis::args::EnumArg dl_upgrade;
- /// --dl-drop-self-circular
- paludis::args::SwitchArg a_dl_drop_self_circular;
+ paludis::args::EnumArg dl_installed_deps_pre;
+ paludis::args::EnumArg dl_installed_deps_runtime;
+ paludis::args::EnumArg dl_installed_deps_post;
- /// --dl-drop-circular
- paludis::args::SwitchArg a_dl_drop_circular;
+ paludis::args::EnumArg dl_uninstalled_deps_pre;
+ paludis::args::EnumArg dl_uninstalled_deps_runtime;
+ paludis::args::EnumArg dl_uninstalled_deps_post;
- /// --dl-drop-all
- paludis::args::SwitchArg a_dl_drop_all;
-
- /// --dl-ignore-installed
- paludis::args::SwitchArg a_dl_ignore_installed;
-
- /// --dl-no-recursive-deps
- paludis::args::SwitchArg a_dl_no_recursive_deps;
-
- /// --dl-max-stack-depth
- paludis::args::IntegerArg a_dl_max_stack_depth;
-
- /// --dl-no-unnecessary-upgrades
- paludis::args::SwitchArg a_dl_no_unnecessary_upgrades;
+ paludis::args::EnumArg dl_circular;
/// }
diff --git a/src/paludis/install.cc b/src/paludis/install.cc
index f7ef3aa..dab08b9 100644
--- a/src/paludis/install.cc
+++ b/src/paludis/install.cc
@@ -81,8 +81,8 @@ namespace
std::set<DepTag::ConstPointer, DepTag::Comparator> _all_tags;
public:
- OurInstallTask() :
- InstallTask(DefaultEnvironment::get_instance()),
+ OurInstallTask(const DepListOptions & options) :
+ InstallTask(DefaultEnvironment::get_instance(), options),
_current_count(0),
_max_count(0),
_new_count(0),
@@ -113,8 +113,8 @@ namespace
virtual void on_build_cleanlist_pre(const DepListEntry & d)
{
cout << endl << colour(cl_heading, "Cleaning stale versions after installing " +
- stringify(d.name) + "-" + stringify(d.version) +
- "::" + stringify(d.repository)) << endl << endl;
+ stringify(d.package.name) + "-" + stringify(d.package.version) +
+ "::" + stringify(d.package.repository)) << endl << endl;
}
virtual void on_build_cleanlist_post(const DepListEntry &)
@@ -170,13 +170,13 @@ namespace
virtual void on_fetch_pre(const DepListEntry & d)
{
cout << colour(cl_heading, "Fetching " +
- stringify(d.name) + "-" + stringify(d.version) +
- "::" + stringify(d.repository)) << endl << endl;
+ stringify(d.package.name) + "-" + stringify(d.package.version) +
+ "::" + stringify(d.package.repository)) << endl << endl;
cerr << xterm_title("(" + stringify(++_current_count) + " of " +
stringify(_max_count + _max_virtual_count) + ") Fetching " +
- stringify(d.name) + "-" + stringify(d.version) +
- "::" + stringify(d.repository));
+ stringify(d.package.name) + "-" + stringify(d.package.version) +
+ "::" + stringify(d.package.repository));
}
virtual void on_fetch_post(const DepListEntry &)
@@ -194,13 +194,13 @@ namespace
virtual void on_install_pre(const DepListEntry & d)
{
cout << endl << colour(cl_heading, "Installing " +
- stringify(d.name) + "-" + stringify(d.version) +
- "::" + stringify(d.repository)) << endl << endl;
+ stringify(d.package.name) + "-" + stringify(d.package.version) +
+ "::" + stringify(d.package.repository)) << endl << endl;
cerr << xterm_title("(" + stringify(++_current_count) + " of " +
stringify(_max_count + _max_virtual_count) + ") Installing " +
- stringify(d.name) + "-" + stringify(d.version) +
- "::" + stringify(d.repository));
+ stringify(d.package.name) + "-" + stringify(d.package.version) +
+ "::" + stringify(d.package.repository));
}
virtual void on_install_post(const DepListEntry &)
@@ -381,29 +381,29 @@ namespace
void
OurInstallTask::on_display_merge_list_entry(const DepListEntry & d)
{
- Context context("When displaying entry '" + stringify(d) + "':");
+ Context context("When displaying entry '" + stringify(d.package) + "':");
- cout << "* " << colour(cl_package_name, d.name);
+ cout << "* " << colour(cl_package_name, d.package.name);
/* display version, unless it's 0 and our category is "virtual" */
- if ((VersionSpec("0") != d.version) ||
- CategoryNamePart("virtual") != d.name.category)
- cout << "-" << d.version;
+ if ((VersionSpec("0") != d.package.version) ||
+ CategoryNamePart("virtual") != d.package.name.category)
+ cout << "-" << d.package.version;
/* display repository, unless it's our main repository */
- if (DefaultEnvironment::get_instance()->package_database()->favourite_repository() != d.repository)
- cout << "::" << d.repository;
+ if (DefaultEnvironment::get_instance()->package_database()->favourite_repository() !=
+ d.package.repository)
+ cout << "::" << d.package.repository;
/* display slot name, unless it's 0 */
if (SlotName("0") != d.metadata->slot)
- cout << colour(cl_slot, " {:" + stringify(
- d.metadata->slot) + "}");
+ cout << colour(cl_slot, " {:" + stringify(d.metadata->slot) + "}");
/* indicate [U], [S] or [N]. display existing version, if we're
* already installed */
PackageDatabaseEntryCollection::Pointer existing(DefaultEnvironment::get_instance()->package_database()->
query(PackageDepAtom::Pointer(new PackageDepAtom(stringify(
- d.name))), is_installed_only));
+ d.package.name))), is_installed_only));
if (existing->empty())
{
@@ -422,7 +422,7 @@ namespace
else
{
existing = DefaultEnvironment::get_instance()->package_database()->query(PackageDepAtom::Pointer(
- new PackageDepAtom(stringify(d.name) + ":" +
+ new PackageDepAtom(stringify(d.package.name) + ":" +
stringify(d.metadata->slot))),
is_installed_only);
if (existing->empty())
@@ -439,7 +439,7 @@ namespace
++_max_count;
}
}
- else if (existing->last()->version < d.version)
+ else if (existing->last()->version < d.package.version)
{
cout << colour(cl_updatemode, " [U " + stringify(
existing->last()->version) + "]");
@@ -454,7 +454,7 @@ namespace
++_max_count;
}
}
- else if (existing->last()->version > d.version)
+ else if (existing->last()->version > d.package.version)
{
cout << colour(cl_updatemode, " [D " + stringify(
existing->last()->version) + "]");
@@ -487,19 +487,18 @@ namespace
}
/* fetch db entry */
- PackageDatabaseEntry p(PackageDatabaseEntry(d.name,
- d.version, d.repository));
+ PackageDatabaseEntry p(d.package);
/* display USE flags */
std::cout << make_pretty_use_flags_string(DefaultEnvironment::get_instance(), p, d.metadata);
/* display tag, add tag to our post display list */
- if (! d.tag->empty())
+ if (! d.tags->empty())
{
std::string tag_titles;
for (SortedCollection<DepTag::ConstPointer, DepTag::Comparator>::Iterator
- tag(d.tag->begin()),
- tag_end(d.tag->end()) ;
+ tag(d.tags->begin()),
+ tag_end(d.tags->end()) ;
tag != tag_end ; ++tag)
{
_all_tags.insert(*tag);
@@ -525,7 +524,7 @@ namespace
" --install --preserve-world --dl-drop-all --dl-no-recursive-deps";
for (DepList::Iterator i(task.current_dep_list_entry()), i_end(task.dep_list().end()) ;
i != i_end ; ++i)
- cerr << " =" << i->name << "-" << i->version << "::" << i->repository;
+ cerr << " =" << i->package.name << "-" << i->package.version << "::" << i->package.repository;
cerr << endl;
}
}
@@ -570,6 +569,23 @@ namespace
cerr << "Exiting with failure" << endl;
exit(EXIT_FAILURE);
}
+
+ DepListDepsOption
+ enum_arg_to_dep_list_deps_option(const args::EnumArg & arg)
+ {
+ if (arg.argument() == "pre")
+ return dl_deps_pre;
+ else if (arg.argument() == "pre-or-post")
+ return dl_deps_pre_or_post;
+ else if (arg.argument() == "post")
+ return dl_deps_post;
+ else if (arg.argument() == "try-post")
+ return dl_deps_try_post;
+ else if (arg.argument() == "discard")
+ return dl_deps_discard;
+ else
+ throw DoHelp("bad value for --" + arg.long_name());
+ }
}
int
@@ -579,23 +595,59 @@ do_install()
Context context("When performing install action from command line:");
- OurInstallTask task;
+ DepListOptions options;
- task.set_drop_self_circular(CommandLine::get_instance()->a_dl_drop_self_circular.specified());
- task.set_drop_circular(CommandLine::get_instance()->a_dl_drop_circular.specified());
- task.set_drop_all(CommandLine::get_instance()->a_dl_drop_all.specified());
- task.set_ignore_installed(CommandLine::get_instance()->a_dl_ignore_installed.specified());
- task.set_recursive_deps(! CommandLine::get_instance()->a_dl_no_recursive_deps.specified());
- task.set_max_stack_depth(CommandLine::get_instance()->a_dl_max_stack_depth.argument());
- task.set_no_unnecessary_upgrades(CommandLine::get_instance()->a_dl_no_unnecessary_upgrades.specified());
+ if (CommandLine::get_instance()->dl_reinstall.specified())
+ {
+ if (CommandLine::get_instance()->dl_reinstall.argument() == "never")
+ options.reinstall = dl_reinstall_never;
+ else if (CommandLine::get_instance()->dl_reinstall.argument() == "always")
+ options.reinstall = dl_reinstall_always;
+ else
+ throw DoHelp("bad value for --dl-reinstall");
+ }
- if (CommandLine::get_instance()->a_dl_rdepend_post.argument() == "always")
- task.set_rdepend_post(dlro_always);
- else if (CommandLine::get_instance()->a_dl_rdepend_post.argument() == "never")
- task.set_rdepend_post(dlro_never);
- else
- task.set_rdepend_post(dlro_as_needed);
+ if (CommandLine::get_instance()->dl_upgrade.specified())
+ {
+ if (CommandLine::get_instance()->dl_upgrade.argument() == "as-needed")
+ options.upgrade = dl_upgrade_as_needed;
+ else if (CommandLine::get_instance()->dl_upgrade.argument() == "always")
+ options.upgrade = dl_upgrade_always;
+ else
+ throw DoHelp("bad value for --dl-upgrade");
+ }
+ if (CommandLine::get_instance()->dl_circular.specified())
+ {
+ if (CommandLine::get_instance()->dl_circular.argument() == "discard")
+ options.circular = dl_circular_discard;
+ else if (CommandLine::get_instance()->dl_circular.argument() == "error")
+ options.circular = dl_circular_error;
+ else
+ throw DoHelp("bad value for --dl-circular");
+ }
+
+ if (CommandLine::get_instance()->dl_installed_deps_pre.specified())
+ options.installed_deps_pre = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_installed_deps_pre);
+ if (CommandLine::get_instance()->dl_installed_deps_runtime.specified())
+ options.installed_deps_runtime = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_installed_deps_runtime);
+ if (CommandLine::get_instance()->dl_installed_deps_post.specified())
+ options.installed_deps_post = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_installed_deps_post);
+
+ if (CommandLine::get_instance()->dl_uninstalled_deps_pre.specified())
+ options.uninstalled_deps_pre = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_uninstalled_deps_pre);
+ if (CommandLine::get_instance()->dl_uninstalled_deps_runtime.specified())
+ options.uninstalled_deps_runtime = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_uninstalled_deps_runtime);
+ if (CommandLine::get_instance()->dl_uninstalled_deps_post.specified())
+ options.uninstalled_deps_post = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_uninstalled_deps_post);
+
+ OurInstallTask task(options);
task.set_no_config_protect(CommandLine::get_instance()->a_no_config_protection.specified());
task.set_fetch_only(CommandLine::get_instance()->a_fetch.specified());
task.set_pretend(CommandLine::get_instance()->a_pretend.specified());
@@ -757,18 +809,6 @@ do_install()
return_code |= 1;
}
- catch (const DepListStackTooDeepError & e)
- {
- cout << endl;
- cerr << "DepList stack too deep error:" << endl;
- cerr << " * " << e.backtrace("\n * ") << e.message() << endl;
- cerr << endl;
- cerr << "Try '--dl-max-stack-depth " << std::max(
- CommandLine::get_instance()->a_dl_max_stack_depth.argument() * 2, 100)
- << "'." << endl << endl;
-
- return_code |= 1;
- }
catch (const DepListError & e)
{
cout << endl;