diff options
author | 2006-01-26 10:29:31 +0000 | |
---|---|---|
committer | 2006-01-26 10:29:31 +0000 | |
commit | 6470bc7028517d8db93b8725cf3570d313bc7a0c (patch) | |
tree | 6ffa22c37033d8733418ec2bc7ba5b8ea087592a | |
parent | 28c2c32e3f87d578dc6ce474df6611fa8acc039c (diff) | |
download | paludis-6470bc7028517d8db93b8725cf3570d313bc7a0c.tar.gz paludis-6470bc7028517d8db93b8725cf3570d313bc7a0c.tar.xz |
New dep resolver. Slightly less sucky than before.
-rw-r--r-- | paludis/dep_list.cc | 234 | ||||
-rw-r--r-- | paludis/dep_list.hh | 33 | ||||
-rw-r--r-- | paludis/dep_list_TEST.cc | 716 | ||||
-rw-r--r-- | src/install.cc | 21 |
4 files changed, 352 insertions, 652 deletions
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc index 4443681..08d678f 100644 --- a/paludis/dep_list.cc +++ b/paludis/dep_list.cc @@ -25,6 +25,7 @@ #include "dep_parser.hh" #include "filter_insert_iterator.hh" #include "indirect_iterator.hh" +#include "iterator_utilities.hh" #include "join.hh" #include "match_package.hh" #include "package_dep_atom.hh" @@ -35,6 +36,7 @@ #include <algorithm> #include <functional> #include <deque> +#include <vector> using namespace paludis; @@ -85,35 +87,47 @@ namespace paludis 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> pending_list; + std::list<DepListEntry>::iterator merge_list_insert_pos; bool check_existing_only; - bool in_pdepend; bool match_found; - const PackageDatabaseEntry * current_package; - int stack_depth; + const DepListEntry * current_package; + ///} + ///\name Settings + ///{ DepListRdependOption rdepend_post; + bool recursive_deps; bool drop_circular; bool drop_self_circular; bool ignore_installed; - bool recursive_deps; + ///} + + ///\name Stack + ///{ + int stack_depth; int max_stack_depth; + ///} + /// Constructor. Implementation(const Environment * const e) : environment(e), check_existing_only(false), - in_pdepend(false), match_found(false), current_package(0), - stack_depth(0), rdepend_post(dlro_as_needed), + recursive_deps(true), drop_circular(false), drop_self_circular(false), ignore_installed(false), - recursive_deps(false), + stack_depth(0), max_stack_depth(100) { } @@ -132,6 +146,43 @@ DepList::~DepList() void DepList::add(DepAtom::ConstPointer atom) { + _implementation->merge_list_insert_pos = _implementation->merge_list.end(); + _add(atom); + + std::list<DepListEntry>::iterator i(_implementation->merge_list.begin()); + _implementation->merge_list_insert_pos = _implementation->merge_list.end(); + while (i != _implementation->merge_list.end()) + { + if (! i->get<dle_has_predeps>()) + throw InternalError(PALUDIS_HERE, "dle_has_predeps not set for " + stringify(*i)); + + else if (! i->get<dle_has_trypredeps>()) + { + _implementation->current_package = &*i; + _add_in_role(DepParser::parse( + _implementation->environment->package_database()->fetch_metadata( + PackageDatabaseEntry(i->get<dle_name>(), i->get<dle_version>(), + i->get<dle_repository>()))->get(vmk_rdepend)), "RDEPEND"); + i->set<dle_has_trypredeps>(true); + } + + else if (! i->get<dle_has_postdeps>()) + { + _implementation->current_package = &*i; + _add_in_role(DepParser::parse( + _implementation->environment->package_database()->fetch_metadata( + PackageDatabaseEntry(i->get<dle_name>(), i->get<dle_version>(), + i->get<dle_repository>()))->get(vmk_pdepend)), "PDEPEND"); + i->set<dle_has_postdeps>(true); + } + else + ++i; + } +} + +void +DepList::_add(DepAtom::ConstPointer atom) +{ /* keep track of stack depth */ Save<int> old_stack_depth(&_implementation->stack_depth, _implementation->stack_depth + 1); @@ -141,8 +192,9 @@ DepList::add(DepAtom::ConstPointer atom) /* we need to make sure that merge_list doesn't get h0rked in the * event of a failure. */ bool merge_list_was_empty(_implementation->merge_list.empty()); - std::list<DepListEntry>::iterator m_save(merge_list_was_empty ? - _implementation->merge_list.end() : --(_implementation->merge_list.end())); + std::list<DepListEntry>::iterator save_end; + if (! merge_list_was_empty) + save_end = previous(_implementation->merge_list.end()); try { @@ -153,7 +205,7 @@ DepList::add(DepAtom::ConstPointer atom) if (merge_list_was_empty) _implementation->merge_list.clear(); else - _implementation->merge_list.erase(++m_save, _implementation->merge_list.end()); + _implementation->merge_list.erase(next(save_end), _implementation->merge_list.end()); throw; } } @@ -162,7 +214,7 @@ void DepList::_add_in_role(DepAtom::ConstPointer atom, const std::string & role) { Context context("When adding " + role + ":"); - add(atom); + _add(atom); } DepList::Iterator @@ -209,50 +261,28 @@ DepList::visit(const PackageDepAtom * const p) { Context context("When resolving package dependency '" + stringify(*p) + "':"); - bool already_there = false; - bool do_rdepend_post = (_implementation->rdepend_post == dlro_always); - - /* are we already installed? */ - if ((! _implementation->ignore_installed) && - (! _implementation->environment->installed_database()->query(p)->empty())) - already_there = true; + /// \todo check installed db - /* will we be installed by this point? */ - if ((! already_there) && (_implementation->merge_list.end() != std::find_if( - _implementation->merge_list.begin(), _implementation->merge_list.end(), - DepListEntryMatcher(_implementation->environment->package_database().raw_pointer(), *p)))) - return; - - if (already_there && ((! _implementation->recursive_deps) || (_implementation->check_existing_only))) - return; - - /* are we allowed to install things? */ - if (_implementation->check_existing_only && ! _implementation->in_pdepend) + /* are we already there? */ + std::list<DepListEntry>::iterator i; + if (_implementation->merge_list.end() != ((i = std::find_if( + _implementation->merge_list.begin(), + _implementation->merge_list.end(), + DepListEntryMatcher( + _implementation->environment->package_database().raw_pointer(), *p))))) { - _implementation->match_found = false; - return; - } - - /* are we pending? (circular dep check) */ - { - std::list<DepListEntry>::iterator i; - if (_implementation->pending_list.end() != ((i = std::find_if( - _implementation->pending_list.begin(), _implementation->pending_list.end(), - DepListEntryMatcher(_implementation->environment->package_database().raw_pointer(), *p))))) + /* what's our status? */ + if (! i->get<dle_has_predeps>()) { - std::deque<std::string> entries; - entries.push_front(stringify(*p)); - std::transform(_implementation->pending_list.begin(), ++i, - std::back_inserter(entries), &stringify<DepListEntry>); - if (_implementation->in_pdepend) - return; - else if (_implementation->drop_circular) + if (_implementation->drop_circular) return; - else if (_implementation->drop_self_circular && entries.size() <= 2) + else if (_implementation->merge_list.begin() == i && _implementation->drop_self_circular) return; else - throw CircularDependencyError(entries.begin(), entries.end()); + throw CircularDependencyError(_implementation->merge_list_insert_pos, next(i)); } + + return; } /* are we allowed to install things? */ @@ -263,11 +293,11 @@ DepList::visit(const PackageDepAtom * const p) } /* find the matching package */ - PackageDatabaseEntryCollection::Pointer matches( - _implementation->environment->package_database()->query(p)); - const PackageDatabaseEntry * match(0); VersionMetadata::ConstPointer metadata(0); + PackageDatabaseEntryCollection::Pointer matches(0); + + matches = _implementation->environment->package_database()->query(p); for (PackageDatabaseEntryCollection::ReverseIterator e(matches->rbegin()), e_end(matches->rend()) ; e != e_end ; ++e) { @@ -283,48 +313,43 @@ DepList::visit(const PackageDepAtom * const p) if (! match) throw AllMaskedError(stringify(*p)); - Save<const PackageDatabaseEntry *> old_current_package(&_implementation->current_package, match); + /* make merge entry */ + std::list<DepListEntry>::iterator merge_entry( + _implementation->merge_list.insert(_implementation->merge_list_insert_pos, + DepListEntry(match->get<pde_name>(), match->get<pde_version>(), + SlotName(metadata->get(vmk_slot)), match->get<pde_repository>(), + false, false, false))); + + Save<std::list<DepListEntry>::iterator> old_merge_list_insert_pos( + &_implementation->merge_list_insert_pos, merge_entry); context.change_context("When resolving package dependency '" + stringify(*p) + - "' -> '" + stringify(*match) + "':"); + "' -> '" + stringify(*merge_entry) + "':"); - /* make merge entry */ - DepListEntry merge_entry(match->get<pde_name>(), match->get<pde_version>(), - SlotName(metadata->get(vmk_slot)), match->get<pde_repository>()); + /* new current package */ + Save<const DepListEntry *> old_current_package(&_implementation->current_package, + &*merge_entry); + /* merge depends */ + if (! merge_entry->get<dle_has_predeps>()) { - /* pending */ - ContainerEntry<std::list<DepListEntry> > pending(&_implementation->pending_list, merge_entry); - - /* merge dependencies */ _add_in_role(DepParser::parse(metadata->get(vmk_depend)), "DEPEND"); - - if (_implementation->rdepend_post != dlro_always) - { - try - { - _add_in_role(DepParser::parse(metadata->get(vmk_rdepend)), "RDEPEND"); - } - catch (const CircularDependencyError &) - { - if (_implementation->rdepend_post != dlro_never) - do_rdepend_post = true; - else - throw; - } - } + merge_entry->set<dle_has_predeps>(true); } - /* merge package */ - if (! already_there) - _implementation->merge_list.push_back(merge_entry); - - /* merge post dependencies */ + /* merge rdepends */ + if (! merge_entry->get<dle_has_trypredeps>() && dlro_always != _implementation->rdepend_post) { - Save<bool> save_ignore_cdep(&_implementation->in_pdepend, true); - if (do_rdepend_post) - _add_in_role(DepParser::parse(metadata->get(vmk_rdepend)), "RDEPEND (as PDEPEND)"); - _add_in_role(DepParser::parse(metadata->get(vmk_pdepend)), "PDEPEND"); + try + { + _add_in_role(DepParser::parse(metadata->get(vmk_rdepend)), "RDEPEND"); + merge_entry->set<dle_has_trypredeps>(true); + } + catch (const CircularDependencyError &) + { + if (dlro_never == _implementation->rdepend_post) + throw; + } } } @@ -334,9 +359,13 @@ DepList::visit(const UseDepAtom * const u) if (! _implementation->current_package) throw InternalError(PALUDIS_HERE, "current_package is 0"); - if (_implementation->environment->query_use(u->flag(), - _implementation->current_package) ^ u->inverse()) - std::for_each(u->begin(), u->end(), std::bind1st(std::mem_fun(&DepList::add), this)); + PackageDatabaseEntry e( + _implementation->current_package->get<dle_name>(), + _implementation->current_package->get<dle_version>(), + _implementation->current_package->get<dle_repository>()); + + if (_implementation->environment->query_use(u->flag(), &e) ^ u->inverse()) + std::for_each(u->begin(), u->end(), std::bind1st(std::mem_fun(&DepList::_add), this)); } #ifndef DOXYGEN @@ -352,10 +381,14 @@ struct IsViable : bool operator() (DepAtom::ConstPointer a) { + PackageDatabaseEntry e( + _impl.current_package->get<dle_name>(), + _impl.current_package->get<dle_version>(), + _impl.current_package->get<dle_repository>()); + const UseDepAtom * const u(a->as_use_dep_atom()); if (0 != u) - return _impl.environment->query_use(u->flag(), - _impl.current_package) ^ u->inverse(); + return _impl.environment->query_use(u->flag(), &e) ^ u->inverse(); else return true; } @@ -389,7 +422,7 @@ DepList::visit(const AnyDepAtom * const a) { Save<bool> save_check(&_implementation->check_existing_only, true); Save<bool> save_match(&_implementation->match_found, true); - add(*i); + _add(*i); if ((found = _implementation->match_found)) break; } @@ -409,7 +442,7 @@ DepList::visit(const AnyDepAtom * const a) { try { - add(*i); + _add(*i); return; } catch (const DepListStackTooDeepError &) @@ -439,7 +472,14 @@ DepList::visit(const BlockDepAtom * const d) PackageDatabaseEntryCollection::ConstPointer q(0); std::list<DepListEntry>::const_iterator m; + PackageDatabaseEntry e( + _implementation->current_package->get<dle_name>(), + _implementation->current_package->get<dle_version>(), + _implementation->current_package->get<dle_repository>()); + /* are we already installed? */ + /// \todo installed_database +#if 0 if (! ((q = _implementation->environment->installed_database()->query(d->blocked_atom())))->empty()) { if (! _implementation->current_package) @@ -447,14 +487,14 @@ DepList::visit(const BlockDepAtom * const d) + stringify(*q->begin()) + "'"); VersionMetadata::ConstPointer metadata( - _implementation->environment->installed_database()->fetch_metadata( - *_implementation->current_package)); + _implementation->environment->installed_database()->fetch_metadata(&e)); if (metadata->end_provide() == std::find( metadata->begin_provide(), metadata->end_provide(), d->blocked_atom()->package())) throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by installed package '" + stringify(*q->begin()) + "'"); } +#endif /* will we be installed by this point? */ if (_implementation->merge_list.end() != ((m = std::find_if( @@ -466,13 +506,15 @@ DepList::visit(const BlockDepAtom * const d) throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by pending package '" + stringify(*m)); - VersionMetadata::ConstPointer metadata(_implementation->environment->package_database()->fetch_metadata( - *_implementation->current_package)); +#if 0 + VersionMetadata::ConstPointer metadata( + _implementation->environment->package_database()->fetch_metadata(e)); if (metadata->end_provide() == std::find( metadata->begin_provide(), metadata->end_provide(), d->blocked_atom()->package())) throw BlockError("'" + stringify(*(d->blocked_atom())) + "' blocked by pending package '" + stringify(*m)); +#endif } } diff --git a/paludis/dep_list.hh b/paludis/dep_list.hh index 9186672..4432baf 100644 --- a/paludis/dep_list.hh +++ b/paludis/dep_list.hh @@ -33,6 +33,8 @@ #include <ostream> #include <list> #include <deque> +#include <iterator> +#include <algorithm> namespace paludis { @@ -41,10 +43,14 @@ namespace paludis */ enum DepListEntryKeys { - dle_name, ///< Package name - dle_version, ///< Package version - dle_slot, ///< Package SLOT - dle_repository ///< Repository name + dle_name, ///< Package name + dle_version, ///< Package version + dle_slot, ///< Package SLOT + dle_repository, ///< Repository name + dle_has_predeps, ///< DEPEND (and RDEPEND if not rdepend_post) done? + dle_has_trypredeps, ///< RDEPEND (if rdepend_post) done? + dle_has_postdeps, ///< PDEPEND done? + last_dle ///< Number of entries }; /** @@ -52,11 +58,14 @@ namespace paludis */ struct DepListEntryTag : SmartRecordTag<comparison_mode::FullComparisonTag, comparison_method::SmartRecordCompareByAllTag>, - SmartRecordKeys<DepListEntryKeys, 4>, + SmartRecordKeys<DepListEntryKeys, last_dle>, SmartRecordKey<dle_name, QualifiedPackageName>, SmartRecordKey<dle_version, VersionSpec>, SmartRecordKey<dle_slot, SlotName>, - SmartRecordKey<dle_repository, RepositoryName> + SmartRecordKey<dle_repository, RepositoryName>, + SmartRecordKey<dle_has_predeps, bool>, + SmartRecordKey<dle_has_trypredeps, bool>, + SmartRecordKey<dle_has_postdeps, bool> { }; @@ -141,6 +150,9 @@ namespace paludis */ class CircularDependencyError : public DepListError { + private: + unsigned _cycle_size; + public: /** * Constructor, from a sequence of the items causing the circular @@ -148,8 +160,14 @@ namespace paludis */ template <typename I_> CircularDependencyError(I_ begin, const I_ end) throw () : - DepListError("Circular dependency: " + join(begin, end, " -> ")) + DepListError("Circular dependency: " + join(begin, end, " -> ")), + _cycle_size(std::distance(begin, end)) + { + } + + unsigned cycle_size() const { + return _cycle_size; } }; @@ -184,6 +202,7 @@ namespace paludis protected DepAtomVisitorTypes::ConstVisitor { private: + void _add(DepAtom::ConstPointer); void _add_in_role(DepAtom::ConstPointer, const std::string & role); protected: diff --git a/paludis/dep_list_TEST.cc b/paludis/dep_list_TEST.cc index 6775cc7..061679b 100644 --- a/paludis/dep_list_TEST.cc +++ b/paludis/dep_list_TEST.cc @@ -20,608 +20,268 @@ #include "paludis.hh" #include <test/test_framework.hh> #include <test/test_runner.hh> +#include <deque> +#include <string> using namespace paludis; using namespace test; namespace test_cases { - /** - * \test Test dep list: one package. - * - * \ingroup Test - */ - struct DepListOnePackageTest : TestCase + struct DepListTestCaseBase : TestCase { - DepListOnePackageTest() : TestCase("one package") { } - - void run() + TestEnvironment env; + FakeRepository::Pointer repo; + std::deque<std::string> expected; + std::string merge_target; + + DepListTestCaseBase(const char c) : + TestCase("dep list " + std::string(1, c)), + env(), + repo(new FakeRepository(RepositoryName("repo"))) { - TestEnvironment e; - - /* t/one exists */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"); - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - TEST_CHECK(d.begin() != d.end()); - TEST_CHECK_EQUAL(std::distance(d.begin(), d.end()), 1); - TEST_CHECK_EQUAL(*d.begin(), DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); + env.package_database()->add_repository(repo); } - } test_dep_list_one_package; - - /** - * \test Test dep list: one installed package. - * - * \ingroup Test - */ - struct DepListOneInstalledPackageTest : TestCase - { - DepListOneInstalledPackageTest() : TestCase("one installed package") { } - void run() + bool repeatable() const { - TestEnvironment e; - - /* t/one exists and is already installed. */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"); - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - installed->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("0.9"))-> - set(vmk_slot, "slot1"); - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - TEST_CHECK(d.begin() == d.end()); + return false; } - } test_dep_list_one_installed_package; - - /** - * \test Test dep list: dep. - * - * \ingroup Test - */ - struct DepListDepTest : TestCase - { - DepListDepTest() : TestCase("dep") { } - void run() - { - TestEnvironment e; + virtual void populate_repo() = 0; - /* t/one DEPENDs upon t/two */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(vmk_depend, "t/two"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("two")), - VersionSpec("1.0"), SlotName("slot2"), RepositoryName("repo"))); - TEST_CHECK(++di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); - } - } test_dep_list_dep; - - /** - * \test Test dep list: pdep. - * - * \ingroup Test - */ - struct DepListPDepTest : TestCase - { - DepListPDepTest() : TestCase("pdep") { } + virtual void populate_expected() = 0; void run() { - TestEnvironment e; - - /* t/one PDEPENDs upon t/two */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(vmk_pdepend, "t/two"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); - TEST_CHECK(++di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("two")), - VersionSpec("1.0"), SlotName("slot2"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); + populate_repo(); + populate_expected(); + check_lists(); } - } test_dep_list_pdep; - - /** - * \test Test dep list: common deps. - * - * \ingroup Test - */ - struct DepListCommonDepsTest : TestCase - { - DepListCommonDepsTest() : TestCase("common deps") { } - void run() + virtual void check_lists() { - TestEnvironment e; - - /* t/one DEPENDs upon ( t/two t/three ) ; t/two DEPENDs upon t/three */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(vmk_depend, "t/two t/three"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"). - set(vmk_depend, "t/three"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0"))-> - set(vmk_slot, "slot3"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("three")), - VersionSpec("1.0"), SlotName("slot3"), RepositoryName("repo"))); - TEST_CHECK(++di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("two")), - VersionSpec("1.0"), SlotName("slot2"), RepositoryName("repo"))); - TEST_CHECK(++di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); + TEST_CHECK(true); + DepList d(&env); + d.add(DepParser::parse(merge_target)); + TEST_CHECK(true); + + unsigned n(0); + std::deque<std::string>::const_iterator exp(expected.begin()); + DepList::Iterator got(d.begin()); + while (true) + { + TestMessageSuffix s(stringify(n++), true); + + TEST_CHECK((exp == expected.end()) == (got == d.end())); + if (got == d.end()) + break; + TEST_CHECK_STRINGIFY_EQUAL(*got, *exp); + ++exp; + ++got; + } } - } test_dep_list_common_deps; - - /** - * \test Test dep list: dep failure. - * - * \ingroup Test - */ - struct DepListDepFailureTest : TestCase - { - DepListDepFailureTest() : TestCase("dep failure") { } - - void run_d(VersionMetadataKey dep_kind) PALUDIS_ATTRIBUTE((noinline)); + }; - void run() + template <char c_> + struct DepListTestCase : DepListTestCaseBase + { + DepListTestCase() : + DepListTestCaseBase(c_) { - run_d(vmk_depend); - run_d(vmk_rdepend); - run_d(vmk_pdepend); } - } test_dep_list_dep_failure; + }; - void - DepListDepFailureTest::run_d(VersionMetadataKey dep_kind) - { - TestMessageSuffix suffix(stringify(dep_kind), true); - TestEnvironment e; - - /* t/one DEPENDs upon t/two and t/three. t/three has unresolvable - * deps. */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(dep_kind, "t/two t/three"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0"))-> - set(vmk_slot, "slot3"). - set(dep_kind, "t/bad"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - TEST_CHECK_THROWS(d.add(DepParser::parse("t/one")), Exception); - TEST_CHECK(d.begin() == d.end()); - - /* try again, with some stuff already in the dep list. */ - d.add(DepParser::parse("t/two")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("two")), - VersionSpec("1.0"), SlotName("slot2"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); - - TEST_CHECK_THROWS(d.add(DepParser::parse("t/one")), Exception); - di = d.begin(); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("two")), - VersionSpec("1.0"), SlotName("slot2"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); - } - - - /** - * \test Test dep list: indirect circular deps. - * - * \ingroup Test - */ - struct DepListIndirectCircularDepTest : TestCase + struct DepListTestCaseA : DepListTestCase<'a'> { - DepListIndirectCircularDepTest() : TestCase("indirect circular deps") { } - - void run() + void populate_repo() { - TestEnvironment e; - - /* t/one DEPENDs upon t/two. t/two DEPENDs upon t/three. t/three DEPENDs - * upon t/two */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(vmk_depend, "t/two"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"). - set(vmk_depend, "t/three"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0"))-> - set(vmk_slot, "slot3"). - set(vmk_depend, "t/two"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - TEST_CHECK_THROWS(d.add(DepParser::parse("t/one")), CircularDependencyError); - TEST_CHECK(d.begin() == d.end()); - - installed->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0")); - d.add(DepParser::parse("t/one")); - - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("two")), - VersionSpec("1.0"), SlotName("slot2"), RepositoryName("repo"))); - TEST_CHECK(++di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); + repo->add_version("a", "one", "1"); } - } test_dep_list_indirect_circular_deps; - - /** - * \test Test dep list: self circular deps. - * - * \ingroup Test - */ - struct DepListSelfCircularDepTest : TestCase - { - DepListSelfCircularDepTest() : TestCase("self circular deps") { } - void run() + void populate_expected() { - TestEnvironment e; - - /* t/one DEPENDs upon t/two. t/two DEPENDs upon t/two. */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(vmk_depend, "t/two"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"). - set(vmk_depend, "t/two"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - TEST_CHECK_THROWS(d.add(DepParser::parse("t/one")), CircularDependencyError); - TEST_CHECK(d.begin() == d.end()); - - installed->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0")); - d.add(DepParser::parse("t/one")); - - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); + merge_target = "a/one"; + expected.push_back("a/one-1:0::repo"); } - } test_dep_list_self_circular_deps; - - /** - * \test Test dep list: met or dep. - * - * \ingroup Test - */ - struct DepListMetOrDepTest : TestCase - { - DepListMetOrDepTest() : TestCase("met or dep") { } + } test_dep_list_a; - void run() + struct DepListTestCaseB : DepListTestCase<'b'> + { + void populate_repo() { - TestEnvironment e; - - /* t/one DEPENDs upon || ( t/two t/three ). t/three is already - * installed */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "slot1"). - set(vmk_depend, "|| ( t/two t/three )"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - - installed->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0"))-> - set(vmk_slot, "slot2"); - e.installed_database()->add_repository(installed); + repo->add_version("b", "one", "1")->set(vmk_depend, "b/two"); + repo->add_version("b", "two", "1"); + } - DepList d(&e); - d.add(DepParser::parse("t/one")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("slot1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); + void populate_expected() + { + merge_target = "b/one"; + expected.push_back("b/two-1:0::repo"); + expected.push_back("b/one-1:0::repo"); } - } test_dep_list_met_or_dep; - - /** - * \test Test dep list: complex met or dep. - * - * \ingroup Test - */ - struct DepListComplexMetOrDepTest : TestCase - { - DepListComplexMetOrDepTest() : TestCase("complex met or dep") { } + } test_dep_list_b; - void run_n(int n) PALUDIS_ATTRIBUTE((noinline)); + struct DepListTestCaseC : DepListTestCase<'c'> + { + void populate_repo() + { + repo->add_version("c", "one", "1")->set(vmk_depend, "c/two"); + repo->add_version("c", "two", "1")->set(vmk_depend, "c/three"); + repo->add_version("c", "three", "1"); + } - void run() + void populate_expected() { - for (int n = 1 ; n <= 3 ; ++n) - run_n(n); + merge_target = "c/one"; + expected.push_back("c/three-1:0::repo"); + expected.push_back("c/two-1:0::repo"); + expected.push_back("c/one-1:0::repo"); } - } test_dep_list_complex_met_or_dep; + } test_dep_list_c; - void - DepListComplexMetOrDepTest::run_n(int n) + struct DepListTestCaseD : DepListTestCase<'d'> { - TestEnvironment e; -#if ((! defined(__GNUC__)) || ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))) - TestMessageSuffix(stringify(n), true); -# endif - - /* t/one DEPENDs upon - * || ( - * ( t/two t/three ) - * ( - * t/four - * || ( - * t/five - * ( t/six t/seven ) - * ) - * ) - * ) - */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "1"). - set(vmk_depend, "|| ( ( t/two t/three ) ( t/four || ( t/five ( t/six t/seven ) ) ) )"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - - if (n == 1) + void populate_repo() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0")); - installed->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0")); + repo->add_version("d", "one", "1")->set(vmk_depend, "d/two d/three"); + repo->add_version("d", "two", "1"); + repo->add_version("d", "three", "1"); } - else if (n == 2) + + void populate_expected() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("four"), VersionSpec("1.0")); - installed->add_version(CategoryNamePart("t"), PackageNamePart("five"), VersionSpec("1.0")); + merge_target = "d/one"; + expected.push_back("d/two-1:0::repo"); + expected.push_back("d/three-1:0::repo"); + expected.push_back("d/one-1:0::repo"); } - else if (n == 3) + } test_dep_list_d; + + struct DepListTestCaseE : DepListTestCase<'e'> + { + void populate_repo() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("four"), VersionSpec("1.0")); - installed->add_version(CategoryNamePart("t"), PackageNamePart("six"), VersionSpec("1.0")); - installed->add_version(CategoryNamePart("t"), PackageNamePart("seven"), VersionSpec("1.0")); + repo->add_version("e", "one", "1")->set(vmk_depend, "e/two e/three"); + repo->add_version("e", "two", "1")->set(vmk_depend, "e/three"); + repo->add_version("e", "three", "1"); } - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); - } - - - /** - * \test Test dep list: complex unmet or dep. - * - * \ingroup Test - */ - struct DepListComplexUnmetOrDepTest : TestCase - { - DepListComplexUnmetOrDepTest() : TestCase("complex unmet or dep") { } + void populate_expected() + { + merge_target = "e/one"; + expected.push_back("e/three-1:0::repo"); + expected.push_back("e/two-1:0::repo"); + expected.push_back("e/one-1:0::repo"); + } + } test_dep_list_e; - void run_n(int n) PALUDIS_ATTRIBUTE((noinline)); + struct DepListTestCaseF : DepListTestCase<'f'> + { + void populate_repo() + { + repo->add_version("f", "one", "1")->set(vmk_depend, "f/two f/three"); + repo->add_version("f", "two", "1"); + repo->add_version("f", "three", "1")->set(vmk_depend, "f/two"); + } - void run() + void populate_expected() { - for (int n = 1 ; n <= 4 ; ++n) - run_n(n); + merge_target = "f/one"; + expected.push_back("f/two-1:0::repo"); + expected.push_back("f/three-1:0::repo"); + expected.push_back("f/one-1:0::repo"); } - } test_dep_list_complex_unmet_or_dep; + } test_dep_list_f; - void - DepListComplexUnmetOrDepTest::run_n(int n) + struct DepListTestCaseG : DepListTestCase<'g'> { - TestEnvironment e; - TestMessageSuffix suffix(stringify(n), true); - - /* t/one DEPENDs upon - * || ( - * ( t/two t/three ) - * ( - * t/four - * || ( - * t/five - * ( t/six t/seven ) - * ) - * ) - * ) - */ - FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "1"). - set(vmk_depend, "|| ( ( t/two t/three ) ( t/four || ( t/five ( t/six t/seven ) ) ) )"); - - e.package_database()->add_repository(repo); - - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - - if (n == 1) + void populate_repo() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0")); + repo->add_version("g", "one", "1")->set(vmk_depend, "g/two g/three"); + repo->add_version("g", "two", "1")->set(vmk_depend, "g/four"); + repo->add_version("g", "three", "1")->set(vmk_depend, "g/four"); + repo->add_version("g", "four", "1"); } - else if (n == 2) + + void populate_expected() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0")); + merge_target = "g/one"; + expected.push_back("g/four-1:0::repo"); + expected.push_back("g/two-1:0::repo"); + expected.push_back("g/three-1:0::repo"); + expected.push_back("g/one-1:0::repo"); } - else if (n == 3) + } test_dep_list_g; + + struct DepListTestCaseH : DepListTestCase<'h'> + { + void populate_repo() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("five"), VersionSpec("1.0")); + repo->add_version("h", "one", "1")->set(vmk_depend, "h/two h/three"); + repo->add_version("h", "two", "1")->set(vmk_depend, "h/four h/three"); + repo->add_version("h", "three", "1")->set(vmk_depend, "h/four"); + repo->add_version("h", "four", "1"); } - else if (n == 4) + + void populate_expected() { - installed->add_version(CategoryNamePart("t"), PackageNamePart("four"), VersionSpec("1.0")); - installed->add_version(CategoryNamePart("t"), PackageNamePart("seven"), VersionSpec("1.0")); + merge_target = "h/one"; + expected.push_back("h/four-1:0::repo"); + expected.push_back("h/three-1:0::repo"); + expected.push_back("h/two-1:0::repo"); + expected.push_back("h/one-1:0::repo"); } + } test_dep_list_h; - e.installed_database()->add_repository(installed); + struct DepListTestCaseI : DepListTestCase<'i'> + { + void populate_repo() + { + repo->add_version("i", "one", "1")->set(vmk_depend, "i/two i/three"); + repo->add_version("i", "two", "1")->set(vmk_depend, "i/four"); + repo->add_version("i", "three", "1")->set(vmk_depend, "i/four i/two"); + repo->add_version("i", "four", "1"); + } - DepList d(&e); - TEST_CHECK(d.begin() == d.end()); - TEST_CHECK_THROWS(d.add(DepParser::parse("t/one")), DepListError); - TEST_CHECK(d.begin() == d.end()); - } + void populate_expected() + { + merge_target = "i/one"; + expected.push_back("i/four-1:0::repo"); + expected.push_back("i/two-1:0::repo"); + expected.push_back("i/three-1:0::repo"); + expected.push_back("i/one-1:0::repo"); + } + } test_dep_list_i; - /** - * \test Test dep list: or all use dep. - * - * \ingroup Test - */ - struct DepListOrAllUseDepTest : TestCase + struct DepListTestCaseTransactionalAdd : TestCase { - DepListOrAllUseDepTest() : TestCase("or all use dep") { } + DepListTestCaseTransactionalAdd() : TestCase("dep list transactional add") { } void run() { - TestEnvironment e; - + TestEnvironment env; FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo"))); + env.package_database()->add_repository(repo); - repo->add_version(CategoryNamePart("t"), PackageNamePart("one"), VersionSpec("1.0"))-> - set(vmk_slot, "1"). - set(vmk_depend, "|| ( t/two ( off? ( t/three ) ) )"); - - repo->add_version(CategoryNamePart("t"), PackageNamePart("two"), VersionSpec("1.0"))-> - set(vmk_slot, "1"); + repo->add_version("i", "one", "1")->set(vmk_depend, "i/two i/three"); + repo->add_version("i", "two", "1")->set(vmk_depend, "i/four"); + repo->add_version("i", "three", "1")->set(vmk_depend, "i/four i/two"); + repo->add_version("i", "four", "1"); + repo->add_version("i", "five", "1")->set(vmk_depend, "i/six i/seven"); + repo->add_version("i", "six", "1"); + repo->add_version("i", "seven", "1")->set(vmk_depend, "i/doesnotexist"); - repo->add_version(CategoryNamePart("t"), PackageNamePart("three"), VersionSpec("1.0"))-> - set(vmk_slot, "1"); + DepList d(&env); + d.add(DepParser::parse("i/one")); + TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "), + "i/four-1:0::repo i/two-1:0::repo i/three-1:0::repo i/one-1:0::repo"); - e.package_database()->add_repository(repo); + TEST_CHECK_THROWS(d.add(DepParser::parse("i/five")), DepListError); - FakeRepository::Pointer installed(new FakeRepository(RepositoryName("installed"))); - e.installed_database()->add_repository(installed); - - DepList d(&e); - d.add(DepParser::parse("t/one")); - DepList::Iterator di(d.begin()), di_end(d.end()); - TEST_CHECK(di != di_end); - TEST_CHECK_EQUAL(*di, DepListEntry( - QualifiedPackageName(CategoryNamePart("t"), PackageNamePart("one")), - VersionSpec("1.0"), SlotName("1"), RepositoryName("repo"))); - TEST_CHECK(++di == di_end); + TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "), + "i/four-1:0::repo i/two-1:0::repo i/three-1:0::repo i/one-1:0::repo"); } - } test_dep_list_or_all_use; - + } test_dep_list_transactional_add; } diff --git a/src/install.cc b/src/install.cc index bf41781..ecdc672 100644 --- a/src/install.cc +++ b/src/install.cc @@ -136,27 +136,6 @@ do_install() << e.what() << ")" << endl; cerr << endl; - dep_list.set_drop_self_circular(true); - try - { - dep_list.add(targets); - cerr << "Adding --dl-drop-self-circular will resolve this, but may omit some genuine" - << endl << "dependencies." << endl << endl; - } - catch (...) - { - dep_list.set_drop_circular(true); - try - { - dep_list.add(targets); - cerr << "Adding --dl-drop-circular will resolve this, but may omit some genuine" << endl - << "dependencies." << endl << endl; - } - catch (...) - { - } - } - return_code |= 1; } |