Author: schubi2
Date: Thu Jul 19 16:31:52 2007
New Revision: 6097
URL: http://svn.opensuse.org/viewcvs/zypp?rev=6097&view=rev
Log:
testprogram for dependency viewer
Added:
trunk/libzypp-testsuite/solvertree/
trunk/libzypp-testsuite/solvertree/Makefile.am
trunk/libzypp-testsuite/solvertree/data/
trunk/libzypp-testsuite/solvertree/data/install-simple-test.xml
trunk/libzypp-testsuite/solvertree/data/sl10.1-beta38-packages.xml.gz (with props)
trunk/libzypp-testsuite/solvertree/data/sl10.1-beta38-selections.xml.gz (with props)
trunk/libzypp-testsuite/solvertree/src/
trunk/libzypp-testsuite/solvertree/src/Makefile.am
trunk/libzypp-testsuite/solvertree/src/solvertree.cc
Modified:
trunk/libzypp-testsuite/Makefile.am
trunk/libzypp-testsuite/configure.ac
Modified: trunk/libzypp-testsuite/Makefile.am
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/Makefile.am?rev=6097&r1=6096&r2=6097&view=diff
==============================================================================
--- trunk/libzypp-testsuite/Makefile.am (original)
+++ trunk/libzypp-testsuite/Makefile.am Thu Jul 19 16:31:52 2007
@@ -1,7 +1,7 @@
#
# Makefile.am for libzypp/testsuite
#
-SUBDIRS = src target solver source parser
+SUBDIRS = src target solver source parser solvertree
## ##################################################
Modified: trunk/libzypp-testsuite/configure.ac
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/configure.ac?rev=6097&r1=6096&r2=6097&view=diff
==============================================================================
--- trunk/libzypp-testsuite/configure.ac (original)
+++ trunk/libzypp-testsuite/configure.ac Thu Jul 19 16:31:52 2007
@@ -103,7 +103,9 @@
target/config/Makefile \
target/lib/Makefile \
target/target.test/Makefile \
- target/tests/Makefile
+ target/tests/Makefile \
+ solvertree/Makefile \
+ solvertree/src/Makefile
)
dnl ==================================================
Added: trunk/libzypp-testsuite/solvertree/Makefile.am
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/solvertree/Makefile.am?rev=6097&view=auto
==============================================================================
--- trunk/libzypp-testsuite/solvertree/Makefile.am (added)
+++ trunk/libzypp-testsuite/solvertree/Makefile.am Thu Jul 19 16:31:52 2007
@@ -0,0 +1,13 @@
+#
+# Makefile.am for zypp/solvertree
+#
+
+SUBDIRS = src
+PACKAGE = solvertree
+
+EXTRA_DIST = data
+
+install-data-hook:
+ $(INSTALL) -d $(DESTDIR)$(testsuitedatadir); \
+ $(INSTALL) -d $(DESTDIR)$(testsuitedatadir)/solvertree;
+
Added: trunk/libzypp-testsuite/solvertree/data/install-simple-test.xml
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/solvertree/data/install-simple-test.xml?rev=6097&view=auto
==============================================================================
--- trunk/libzypp-testsuite/solvertree/data/install-simple-test.xml (added)
+++ trunk/libzypp-testsuite/solvertree/data/install-simple-test.xml Thu Jul 19 16:31:52 2007
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ install minmal selection
+-->
+<test>
+<setup>
+ <arch name="i686"/>
+ <channel name="packages" file="sl10.1-beta38-packages.xml.gz"/>
+ <channel name="selections" file="sl10.1-beta38-selections.xml.gz"/>
+ <mediaid/>
+</setup>
+<trial>
+ <install channel="selections" kind="selection" name="default"/>
+ <install channel="packages" package="kernel-default"/>
+<reportproblems/>
+ <showpool prefix="xxxxxx" verbose="true"/>
+</trial>
+</test>
Added: trunk/libzypp-testsuite/solvertree/data/sl10.1-beta38-packages.xml.gz
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/solvertree/data/sl10.1-beta38-packages.xml.gz?rev=6097&view=auto
==============================================================================
Binary file - no diff available.
Added: trunk/libzypp-testsuite/solvertree/data/sl10.1-beta38-selections.xml.gz
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/solvertree/data/sl10.1-beta38-selections.xml.gz?rev=6097&view=auto
==============================================================================
Binary file - no diff available.
Added: trunk/libzypp-testsuite/solvertree/src/Makefile.am
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/solvertree/src/Makefile.am?rev=6097&view=auto
==============================================================================
--- trunk/libzypp-testsuite/solvertree/src/Makefile.am (added)
+++ trunk/libzypp-testsuite/solvertree/src/Makefile.am Thu Jul 19 16:31:52 2007
@@ -0,0 +1,12 @@
+#
+# Makefile.am for zypp/testsuite/solver/src
+#
+
+INCLUDES = -I/usr/include/libxml2 \
+ -I/usr/lib/qt3/include
+ -DZYPP_BASE_LOGGER_LOGGROUP=\"testsuite\"
+
+LDADD = $(libdir)/libzypp.so $(top_srcdir)/src/helix/lib@PACKAGE@_helix.la -L/usr/lib/qt3/lib -lqt-mt -lX11 -lqdialogsolver
+noinst_PROGRAMS = solvertree
+
+solvertree_SOURCES = solvertree.cc
\ No newline at end of file
Added: trunk/libzypp-testsuite/solvertree/src/solvertree.cc
URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp-testsuite/solvertree/src/solvertree.cc?rev=6097&view=auto
==============================================================================
--- trunk/libzypp-testsuite/solvertree/src/solvertree.cc (added)
+++ trunk/libzypp-testsuite/solvertree/src/solvertree.cc Thu Jul 19 16:31:52 2007
@@ -0,0 +1,2404 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/*
+ * zypptestomatic.cc
+ *
+ * Copyright (C) 2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include <sstream>
+#include <iostream>
+#include <map>
+#include <set>
+
+#include <cstdlib>
+#include <cstring>
+#include
+#include
+#include
+#include
+#include
+#include "../../src/helix/XmlNode.h"
+
+#include "zypp/Resolvable.h"
+#include "zypp/ResTraits.h"
+#include "zypp/ResPool.h"
+#include "zypp/PoolItem.h"
+#include "zypp/Capability.h"
+#include "zypp/CapSet.h"
+#include "zypp/CapFactory.h"
+#include "zypp/ResolverProblem.h"
+#include "zypp/ProblemSolution.h"
+
+
+#include "zypp/Source.h"
+#include "zypp/SourceFactory.h"
+#include "zypp/SourceManager.h"
+#include "zypp/source/SourceImpl.h"
+
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+#include "zypp/base/LogControl.h"
+#include "zypp/base/Exception.h"
+
+#include "zypp/base/Algorithm.h"
+#include "zypp/ResPool.h"
+#include "zypp/ResFilters.h"
+#include "zypp/CapFilters.h"
+
+#include "zypp/media/MediaManager.h"
+
+#include "../../src/helix/HelixSourceImpl.h"
+
+#include "zypp/ZYpp.h"
+#include "zypp/ZYppFactory.h"
+
+#include "zypp/pool/GetResolvablesToInsDel.h"
+#include "zypp/solver/detail/Resolver.h"
+#include "zypp/solver/detail/ResolverContext.h"
+#include "zypp/solver/detail/ResolverQueue.h"
+#include "zypp/solver/detail/ResolverInfo.h"
+#include "zypp/ResolverProblem.h"
+#include "zypp/solver/detail/InstallOrder.h"
+#include "zypp/solver/detail/Testcase.h"
+#include "../../solver/src/KeyRingCallbacks.h"
+
+#include "zypp/QZyppSolverDialog.h"
+
+using namespace std;
+using namespace zypp;
+using zypp::solver::detail::XmlNode;
+using zypp::solver::detail::XmlNode_Ptr;
+using zypp::solver::detail::ResolverContext_Ptr;
+using zypp::solver::detail::ResolverQueueList;
+using zypp::solver::detail::ResolverQueue_Ptr;
+using zypp::solver::detail::InstallOrder;
+using zypp::solver::detail::Testcase;
+using zypp::ResolverProblemList;
+
+//-----------------------------------------------------------------------------
+
+static bool show_mediaid = false;
+static string globalPath;
+static ZYpp::LocaleSet locales;
+
+static ZYpp::Ptr God;
+static SourceManager_Ptr manager;
+static bool forceResolve;
+static int maxSolverPasses = 0;
+
+static int sys_res_install = 0;
+
+typedef list<unsigned int> ChecksumList;
+typedef set PoolItemSet;
+
+enum DepKind { PROVIDE, CONFLICT, REQUIRE };
+
+
+#define MARKER ">!> "
+#define RESULT cout << MARKER
+
+
+solver::detail::Resolver_Ptr resolver;
+
+class compare_problems {
+public:
+ int operator() (const boost::intrusive_ptrzypp::ResolverProblem & p1,
+ const boost::intrusive_ptrzypp::ResolverProblem & p2) const
+ { return p1->description() < p2->description(); }
+};
+
+//-----------------------------------------------------------------------------
+
+static std::ostream &
+printRes ( std::ostream & str, ResObject::constPtr r )
+{
+ if (show_mediaid) {
+ Resolvable::constPtr res = r;
+ Package::constPtr pkg = asKind<Package>(res);
+ if (pkg) str << "[" << pkg->sourceMediaNr() << "]";
+ }
+ if (r->kind() != ResTraitszypp::Package::kind)
+ str << r->kind() << ':';
+ str << r->name() << '-' << r->edition();
+ if (r->arch() != "") {
+ str << '.' << r->arch();
+ }
+ Source_Ref s = r->source();
+ if (s) {
+ string alias = s.alias();
+ if (!alias.empty()
+ && alias != "@system")
+ {
+ str << '[' << s.alias() << ']';
+ }
+// str << '[' << s << ']';
+ }
+ return str;
+}
+
+//---------------------------------------------------------------------------
+
+Resolvable::Kind
+string2kind (const std::string & str)
+{
+ Resolvable::Kind kind = ResTraitszypp::Package::kind;
+ if (!str.empty()) {
+ if (str == "package") {
+ // empty
+ }
+ else if (str == "patch") {
+ kind = ResTraitszypp::Patch::kind;
+ }
+ else if (str == "atom") {
+ kind = ResTraitszypp::Atom::kind;
+ }
+ else if (str == "pattern") {
+ kind = ResTraitszypp::Pattern::kind;
+ }
+ else if (str == "selection") {
+ kind = ResTraitszypp::Selection::kind;
+ }
+ else if (str == "script") {
+ kind = ResTraitszypp::Script::kind;
+ }
+ else if (str == "message") {
+ kind = ResTraitszypp::Message::kind;
+ }
+ else if (str == "product") {
+ kind = ResTraitszypp::Product::kind;
+ }
+ else if (str == "language") {
+ kind = ResTraitszypp::Language::kind;
+ }
+ else {
+ cerr << "get_poolItem unknown kind '" << str << "'" << endl;
+ }
+ }
+ return kind;
+}
+
+//---------------------------------------------------------------------------
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+//==============================================================================================================================
+
+//---------------------------------------------------------------------------------------------------------------------
+// helper functions
+
+typedef list<string> StringList;
+
+void addDependencies( const string & kind, const string & name,
+ const DepKind & depKind, const ResPool & pool )
+{
+ CapSet capset;
+ vector<string> names;
+ str::split( name, back_inserter(names), "," );
+ for (unsigned i=0; i < names.size(); i++) {
+ capset.insert (CapFactory().parse (string2kind (kind), names[i]));
+ }
+
+ ResPool::AdditionalCapSet aCapSet;
+ aCapSet[ResStatus::USER] = capset;
+
+ switch (depKind) {
+ case PROVIDE:
+ pool.setAdditionalProvide( aCapSet );
+ break;
+ case CONFLICT:
+ pool.setAdditionalConflict( aCapSet );
+ break;
+ case REQUIRE:
+ pool.setAdditionalRequire( aCapSet );
+ break;
+ }
+}
+
+
+static void
+assemble_install_cb (PoolItem_Ref poolItem, const ResStatus & status, void *data)
+{
+ if (isKind<SystemResObject>( poolItem.resolvable() )) {
+ sys_res_install = 1;
+ return;
+ }
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+ s << str::form ("%-7s ", poolItem.status().staysInstalled() ? "|flag" : "install");
+ printRes (s, poolItem.resolvable());
+
+ slist->push_back (s.str());
+}
+
+
+static void
+assemble_uninstall_cb (PoolItem_Ref poolItem, const ResStatus & status, void *data)
+{
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+//MIL << "assemble_uninstall_cb(" << poolItem << "):" << status << endl;
+ s << str::form ("%-7s ", poolItem.status().isImpossible () ? "|unflag" : "remove");
+ printRes (s, poolItem.resolvable());
+
+ slist->push_back (s.str());
+}
+
+
+static void
+assemble_impossible_cb (PoolItem_Ref poolItem, const ResStatus & status, void *data)
+{
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+//MIL << "assemble_impossible_cb(" << poolItem << "):" << status << endl;
+ s << str::form ("%-7s ", "|unflag");
+ printRes (s, poolItem.resolvable());
+
+ slist->push_back (s.str());
+}
+
+
+static void
+assemble_upgrade_cb (PoolItem_Ref res1, const ResStatus & status, PoolItem_Ref res2, const ResStatus & status2, void *data)
+{
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+
+ s << "upgrade ";
+
+ printRes (s, res2.resolvable());
+ s << " => ";
+ printRes (s, res1.resolvable());
+
+ slist->push_back (s.str());
+}
+
+
+static void
+assemble_incomplete_cb (PoolItem_Ref poolItem, const ResStatus & status,void *data)
+{
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+ s << str::form ("%-11s ", poolItem.status().wasInstalled() ? "incomplete" : "|needed");
+ printRes (s, poolItem.resolvable());
+
+ slist->push_back (s.str());
+}
+
+
+static void
+assemble_satisfy_cb (PoolItem_Ref poolItem, const ResStatus & status, void *data)
+{
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+ s << str::form ("%-10s ", poolItem.status().wasInstalled() ? "complete" : "|satisfied");
+ printRes (s, poolItem.resolvable());
+
+ slist->push_back (s.str());
+}
+
+static void
+print_sep (void)
+{
+ cout << endl << "------------------------------------------------" << endl << endl;
+}
+
+static void
+print_important (const string & str)
+{
+ RESULT << str.c_str() << endl;
+}
+
+static void
+print_items (StringList & items)
+{
+ items.sort();
+ for (StringList::const_iterator iter = items.begin(); iter != items.end(); iter++) {
+ RESULT << (*iter).c_str() << endl;
+ }
+}
+
+
+/** Order on PoolItem_Ref.
+ * \li kind
+ * \li name
+ * \li edition
+ * \li arch
+ * \li source::alias
+ * \li ResObject::constPtr as fallback.
+*/
+struct KNEAOrder : public std::binary_function
+{
+ // NOTE: operator() provides LESS semantics to order the set.
+ // So LESS means 'prior in set'. We want 'better' archs and
+ // 'better' editions at the beginning of the set. So we return
+ // TRUE if (lhs > rhs)!
+ //
+ bool operator()( const PoolItem_Ref lhs, const PoolItem_Ref rhs ) const
+ {
+ int res = lhs->kind().compare( rhs->kind() );
+ if ( res )
+ return res < 0;
+ res = lhs->name().compare( rhs->name() );
+ if ( res )
+ return res < 0;
+ res = lhs->edition().compare( rhs->edition() );
+ if ( res )
+ return res < 0;
+ res = lhs->arch().compare( rhs->arch() );
+ if ( res )
+ return res < 0;
+ res = lhs->source().alias().compare( rhs->source().alias() );
+ if ( res )
+ return res < 0;
+ // no more criteria, still equal:
+ // use the ResObject::constPtr (the poiner value)
+ // (here it's arbitrary whether < or > )
+ return lhs.resolvable() < rhs.resolvable();
+ }
+};
+
+typedef std::set PoolItemOrderSet;
+
+static void
+print_solution (ResolverContext_Ptr context, int *count, ChecksumList & checksum_list, bool instorder, bool mediaorder)
+{
+ if (context->isValid ()) {
+
+ StringList items;
+ items.clear();
+
+ unsigned int checksum = 0;
+ bool is_dup = false;
+
+ RESULT << "Solution #" << *count << ":" << endl;
+ ++*count;
+
+ context->foreachInstall (assemble_install_cb, &items);
+
+ context->foreachUninstall (assemble_uninstall_cb, &items);
+
+ context->foreachImpossible (assemble_impossible_cb, &items);
+
+ context->foreachUpgrade (assemble_upgrade_cb, &items);
+
+ context->foreachIncomplete (assemble_incomplete_cb, &items);
+
+ context->foreachSatisfy (assemble_satisfy_cb, &items);
+
+ items.sort ();
+
+ for (StringList::const_iterator iter = items.begin(); iter != items.end(); iter++) {
+ const char *c = (*iter).c_str();
+ while (*c) {
+ checksum = 17 * checksum + (unsigned int)*c;
+ ++c;
+ }
+ }
+ cout << str::form ("Checksum = %x", checksum) << endl;
+
+ for (ChecksumList::const_iterator iter = checksum_list.begin(); iter != checksum_list.end() && !is_dup; iter++) {
+ if (*iter == checksum) {
+ is_dup = true;
+ }
+ }
+
+ if (! is_dup) {
+ for (StringList::const_iterator iter = items.begin(); iter != items.end(); iter++) {
+ print_important (*iter);
+ }
+ checksum_list.push_back (checksum);
+ } else {
+ RESULT << "This solution is a duplicate." << endl;
+ }
+
+ items.clear();
+
+ } else {
+ RESULT << "Failed Attempt:" << endl;
+ }
+
+ RESULT << "installs=" << context->installCount()-sys_res_install << ", upgrades=" << context->upgradeCount() << ", uninstalls=" << context->uninstallCount();
+ int satisfied = context->satisfyCount();
+ if (satisfied > 0) cout << ", satisfied=" << satisfied;
+ cout << endl;
+ cout << str::form ("download size=%.1fk, install size=%.1fk\n", context->downloadSize() / 1024.0, context->installSize() / 1024.0);
+ cout << str::form ("total priority=%d, min priority=%d, max priority=%d\n", context->totalPriority(), context->minPriority(), context->maxPriority());
+ cout << str::form ("other penalties=%d\n", context->otherPenalties());
+ cout << "- - - - - - - - - -" << endl;
+
+ if (instorder) {
+ cout << endl;
+ RESULT << "Installation Order:" << endl << endl;
+ solver::detail::PoolItemList inslist = context->getMarked(1);
+ solver::detail::PoolItemSet dummy;
+
+ solver::detail::PoolItemSet insset( inslist.begin(), inslist.end() );
+#if 0
+ InstallOrder order( context->pool(), insset, dummy ); // sort according to prereq
+ order.init();
+ const solver::detail::PoolItemList & installorder ( order.getTopSorted() );
+ for (solver::detail::PoolItemList::const_iterator iter = installorder.begin(); iter != installorder.end(); iter++) {
+ RESULT; printRes (cout, (*iter)); cout << endl;
+ }
+#else
+ int counter = 1;
+ InstallOrder order( context->pool(), insset, dummy ); // sort according to prereq
+ order.init();
+ for ( solver::detail::PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
+ {
+ RESULT << endl;
+ RESULT << counter << ". set with " << items.size() << " resolvables" << endl;
+ PoolItemOrderSet orderedset;
+
+ for ( solver::detail::PoolItemList::iterator iter = items.begin(); iter != items.end(); ++iter )
+ {
+ orderedset.insert( *iter );
+ }
+ for (PoolItemOrderSet::const_iterator iter = orderedset.begin(); iter != orderedset.end(); iter++) {
+ RESULT; printRes( cout, *iter); cout << endl;
+ }
+ counter++;
+ order.setInstalled( items );
+ }
+#endif
+
+ cout << "- - - - - - - - - -" << endl;
+ }
+
+ if (mediaorder) {
+ cout << endl;
+ RESULT << "Media Order:" << endl << endl;
+
+ Target::PoolItemList dellist;
+ Target::PoolItemList inslist;
+ Target::PoolItemList srclist;
+ pool::GetResolvablesToInsDel collect( context->pool() );
+ dellist.swap(collect._toDelete);
+ inslist.swap(collect._toInstall);
+ srclist.swap(collect._toSrcinstall);
+
+ int count = 0;
+ for (Target::PoolItemList::const_iterator iter = dellist.begin(); iter != dellist.end(); iter++) {
+ cout << "DEL " << ++count << ".: "; printRes (cout, (*iter)); cout << endl;
+ }
+ count = 0;
+ for (Target::PoolItemList::const_iterator iter = inslist.begin(); iter != inslist.end(); iter++) {
+ cout << "INS " << ++count << ".:"; printRes (cout, (*iter)); cout << endl;
+ }
+ cout << "- - - - - - - - - -" << endl;
+ }
+
+ cout.flush();
+
+ cout << "Context Info:" << endl;
+ context->spewInfo ();
+
+ cout << "Context Context:" << endl;
+ cout << *context << endl;
+
+ return;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+struct FindPackage : public resfilter::ResObjectFilterFunctor
+{
+ PoolItem_Ref poolItem;
+ Source_Ref source;
+ Resolvable::Kind kind;
+ bool edition_set;
+ Edition edition;
+ bool arch_set;
+ Arch arch;
+
+ FindPackage (Source_Ref s, Resolvable::Kind k, const string & v, const string & r, const string & a)
+ : source (s)
+ , kind (k)
+ , edition_set( !v.empty() )
+ , edition( v, r )
+ , arch_set( !a.empty() )
+ , arch( a )
+ {
+ }
+
+ bool operator()( PoolItem_Ref p)
+ {
+ if (arch_set && arch != p->arch()) { // if arch requested, force this arch
+ return true;
+ }
+ if (!p->arch().compatibleWith( God->architecture() )) {
+ return true;
+ }
+
+ if (edition_set) {
+ if (p->edition().compare( edition ) == 0) { // if edition requested, force this edition
+ poolItem = p;
+ return false;
+ }
+ return true;
+ }
+
+ if (!poolItem // none yet
+ || (poolItem->arch().compare( p->arch() ) < 0) // new has better arch
+ || (poolItem->edition().compare( p->edition() ) < 0)) // new has better edition
+ {
+ poolItem = p;
+ }
+ return true;
+ }
+};
+
+static bool set_licence = false;
+
+static PoolItem_Ref
+get_poolItem (const string & source_alias, const string & package_name, const string & kind_name = "", const string & ver = "", const string & rel = "", const string & arch = "")
+{
+ PoolItem_Ref poolItem;
+ Resolvable::Kind kind = string2kind (kind_name);
+ Source_Ref source;
+
+ try {
+ source = manager->findSource (source_alias);
+ }
+ catch (Exception & excpt_r) {
+ ZYPP_CAUGHT (excpt_r);
+ cerr << "Can't find source '" << source_alias << "'" << endl;
+ return poolItem;
+ }
+
+ try {
+ FindPackage info (source, kind, ver, rel, arch);
+
+ invokeOnEach( God->pool().byNameBegin( package_name ),
+ God->pool().byNameEnd( package_name ),
+ functor::chain( resfilter::BySource(source), resfilter::ByKind (kind) ),
+ functor::functorRef (info) );
+
+ poolItem = info.poolItem;
+ if (!poolItem) {
+ // try to find the resolvable over all channel. This is useful for e.g. languages
+ invokeOnEach( God->pool().byNameBegin( package_name ),
+ God->pool().byNameEnd( package_name ),
+ resfilter::ByKind (kind),
+ functor::functorRef (info) );
+ poolItem = info.poolItem;
+ }
+ }
+ catch (Exception & excpt_r) {
+ ZYPP_CAUGHT (excpt_r);
+ cerr << "Can't find kind[" << kind_name << "]:'" << package_name << "': source '" << source_alias << "' not defined" << endl;
+ if (kind_name.empty())
+ cerr << "Please specify kind=\"...\" in the request." << endl;
+ return poolItem;
+ }
+
+ if (!poolItem) {
+ cerr << "Can't find kind: " << kind << ":'" << package_name << "' in source '" << source_alias << "': no such name/kind" << endl;
+ }
+
+ return poolItem;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// whatdependson
+
+
+struct RequiringPoolItem
+{
+ PoolItemSet itemset;
+ PoolItem_Ref provider;
+ Capability cap;
+ bool first;
+
+ RequiringPoolItem (PoolItem_Ref p)
+ : provider (p)
+ { }
+
+ bool operator()( const CapAndItem & cai )
+ {
+ PoolItem_Ref requirer( cai.item );
+ Capability cap( cai.cap );
+ if (itemset.insert (requirer).second) {
+ if (first) {
+ cout << "\t" << provider.resolvable() << " provides " << cap << " required by" << endl;
+ first = false;
+ }
+ cout << "\t\t" << requirer.resolvable() << " for " << cap << endl;
+ }
+ return true;
+ }
+};
+
+
+static PoolItemSet
+whatdependson (PoolItem_Ref poolItem)
+{
+ cout << endl << endl << "What depends on '" << poolItem.resolvable() << "'" << endl;
+
+ RequiringPoolItem info (poolItem);
+
+ // loop over all provides and call foreachRequiringResItem
+
+ CapSet caps = poolItem->dep (Dep::PROVIDES);
+ for (CapSet::const_iterator cap_iter = caps.begin(); cap_iter != caps.end(); ++cap_iter) {
+
+ info.cap = *cap_iter;
+ info.first = true;
+
+ //world->foreachRequiringResItem (info.cap, requires_poolItem_cb, &info);
+
+ Dep dep( Dep::REQUIRES );
+ invokeOnEach( God->pool().byCapabilityIndexBegin( info.cap.index(), dep ),
+ God->pool().byCapabilityIndexEnd( info.cap.index(), dep ),
+ resfilter::ByCapMatch( info.cap ),
+ functor::functorRef(info) );
+
+ }
+
+ return info.itemset;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// whatprovides
+
+
+struct ProvidingPoolItem
+{
+ PoolItemSet itemset;
+
+ bool operator()( const CapAndItem & cai )
+ {
+ itemset.insert( cai.item );
+ return true;
+ }
+};
+
+
+static PoolItemSet
+get_providing_poolItems (const string & prov_name, const string & kind_name = "")
+{
+ PoolItemSet rs;
+ Resolvable::Kind kind = string2kind (kind_name);
+
+ CapFactory factory;
+ Capability cap = factory.parse (kind, prov_name);
+
+ Dep dep( Dep::PROVIDES );
+ ProvidingPoolItem info;
+
+ // world->foreachProvidingResItem (cap, providing_poolItem_cb, &rs);
+
+ invokeOnEach( God->pool().byCapabilityIndexBegin( cap.index(), dep ),
+ God->pool().byCapabilityIndexEnd( cap.index(), dep ),
+ resfilter::ByCapMatch( cap ),
+ functor::functorRef(info) );
+
+ return info.itemset;
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// setup related functions
+
+typedef multimap ItemMap;
+
+struct SortItem : public resfilter::PoolItemFilterFunctor
+{
+ ItemMap sorted;
+ bool _show_all;
+
+ SortItem( bool show_all )
+ : _show_all( show_all )
+ { }
+
+ bool operator()( PoolItem_Ref poolItem )
+ {
+ ostringstream ostr;
+ if (_show_all
+ || (!poolItem.status().isUndetermined()
+ || poolItem.status().transacts()))
+ {
+ printRes (ostr, poolItem);
+ sorted.insert (ItemMap::value_type(ostr.str(), poolItem));
+ }
+ return true;
+ }
+};
+
+
+// collect all installed items in a set
+
+void
+print_pool( solver::detail::Resolver_Ptr resolver, const string & prefix = "", bool show_all = true, string show_licence = "false", bool verbose = false )
+{
+ SortItem info( show_all );
+ cout << "Current pool:" << endl;
+ invokeOnEach( God->pool().begin( ),
+ God->pool().end ( ),
+ functor::functorRef (info) );
+
+ int count = 0;
+ for (ItemMap::const_iterator it = info.sorted.begin(); it != info.sorted.end(); ++it) {
+ cout << prefix << ++count << ": ";
+ if(show_licence == "true"){
+ cout << it->second << " Licence: " << it->second.status().isLicenceConfirmed();
+ }else{
+ cout << it->second;
+ }
+ cout << endl;
+ if (verbose) {
+ zypp::solver::detail::ItemCapKindList selectedBy = resolver->isInstalledBy(it->second);
+ zypp::solver::detail::ItemCapKindList select = resolver->installs(it->second);
+ for (zypp::solver::detail::ItemCapKindList::const_iterator iter = selectedBy.begin(); iter != selectedBy.end(); ++iter) {
+ if (iter == selectedBy.begin()) {
+ cout << prefix << ++count << ": ";
+ cout << " will be selected by:" << endl;
+ }
+ cout << prefix << ++count << ": ";
+ cout << " " << iter->item << " " << iter->initialInstallation << endl;
+ }
+ for (zypp::solver::detail::ItemCapKindList::const_iterator iter = select.begin(); iter != select.end(); ++iter) {
+ if (iter == select.begin()) {
+ cout << prefix << ++count << ": ";
+ cout << " will select:" << endl;
+ }
+ cout << prefix << ++count << ": ";
+ cout << " " << iter->item << " " << iter->initialInstallation << endl;
+ }
+ }
+ }
+ cout << "Pool End." << endl;
+ return;
+}
+
+// set licence-bit on all items in the pool
+void
+set_licence_Pool()
+{
+
+ SortItem info( true );
+ invokeOnEach( God->pool().begin( ),
+ God->pool().end ( ),
+ functor::functorRef (info) );
+
+ for (ItemMap::const_iterator it = info.sorted.begin(); it != info.sorted.end(); ++it) {
+ it->second.status().setLicenceConfirmed();
+ }
+
+ return;
+}
+
+static int
+load_source (const string & alias, const string & filename, const string & type, bool system_packages)
+{
+ Pathname pathname = globalPath + filename;
+ int count = 0;
+
+ Source_Ref src;
+
+ if (type == "url") {
+ try {
+ Url url( filename );
+ cout << "Load from Url '" << url << "' (" << filename << ")" << endl;
+ if (url.getScheme() == "file") {
+ pathname = url.getPathName();
+ url = Url( "file:/" );
+ }
+ else
+ pathname = "";
+
+ Pathname cache_dir( "" );
+ src = Source_Ref( SourceFactory().createFrom( url, pathname, alias, cache_dir ) );
+ }
+ catch ( Exception & excpt_r ) {
+ ZYPP_CAUGHT (excpt_r);
+ cout << "Couldn't load packages from Url '" << filename << "'" << endl;
+ return -1;
+ }
+ }
+ else {
+ try {
+ Url url("file:/");
+
+ media::MediaManager mmgr;
+ media::MediaId mediaid = mmgr.open( url );
+ HelixSourceImpl *impl = new HelixSourceImpl ();
+ cout << "Load from File '" << pathname << "'" << endl;
+ impl->factoryCtor (mediaid, pathname, alias);
+ src = Source_Ref( SourceFactory().createFrom( impl ) );
+ }
+ catch ( Exception & excpt_r ) {
+ ZYPP_CAUGHT (excpt_r);
+ cout << "Couldn't load packages from XML file '" << filename << "'" << endl;
+ return -1;
+ }
+ }
+
+ try {
+ manager->addSource (src);
+ count = src.resolvables().size();
+ cout << "Added source '" << alias << "' with " << count << " resolvables" << endl;
+ God->addResolvables( src.resolvables(), (alias == "@system") );
+// print_pool ();
+
+ cout << "Loaded " << count << " resolvables from " << (filename.empty()?pathname.asString():filename) << "." << endl;
+ }
+ catch ( Exception & excpt_r ) {
+ ZYPP_CAUGHT (excpt_r);
+ cout << "Loaded NO package(s) from " << src << endl;
+ count = -1;
+ }
+
+ if(set_licence)
+ set_licence_Pool();
+ return count;
+}
+
+
+static int
+undump (const std::string & filename)
+{
+ cerr << "undump not really supported" << endl;
+
+ return load_source ("undump", filename, "undump", false);
+}
+
+
+static bool done_setup = false;
+
+static void
+parse_xml_setup (XmlNode_Ptr node)
+{
+ if (!node->equals("setup")) {
+ ZYPP_THROW (Exception ("Node not 'setup' in parse_xml_setup():"+node->name()));
+ }
+
+ if (done_setup) {
+ cerr << "Multiple <setup>..</setup> sections not allowed!" << endl;
+ exit (0);
+ }
+ done_setup = true;
+
+ string architecture = node->getProp( "arch" ); // allow <setup arch="...">
+ if (!architecture.empty()) {
+ MIL << "Setting architecture to '" << architecture << "'" << endl;
+ try {
+ God->setArchitecture( Arch( architecture ) );
+ setenv ("ZYPP_TESTSUITE_FAKE_ARCH", architecture.c_str(), 1);
+ }
+ catch( const Exception & excpt_r ) {
+ ZYPP_CAUGHT( excpt_r );
+ cerr << "Bad architecture '" << architecture << "' in " << endl;
+ return;
+ }
+ }
+
+
+ node = node->children();
+ while (node != NULL) {
+ if (!node->isElement()) {
+ node = node->next();
+ continue;
+ }
+ if (node->equals ("forceResolve")) {
+ forceResolve = true;
+
+ } else if (node->equals ("maxSolverPasses")) {
+ maxSolverPasses = atoi ((node->getProp ("value")).c_str());
+
+ } else if (node->equals ("system")) {
+
+ string file = node->getProp ("file");
+ if (load_source ("@system", file, "helix", true) <= 0) {
+ cerr << "Can't setup 'system'" << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("hardwareInfo")) {
+
+ Pathname pathname = globalPath + node->getProp ("path");
+ setenv ("ZYPP_MODALIAS_SYSFS", pathname.asString().c_str(), 1);
+ RESULT << "setting HardwareInfo to: " << pathname.asString() << endl;
+ } else if (node->equals ("channel")) {
+
+ string name = node->getProp ("name");
+ string file = node->getProp ("file");
+ string type = node->getProp ("type");
+ if (load_source (name, file, type, false) <= 0) {
+ cerr << "Can't setup 'channel'" << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("source")) {
+
+ string url = node->getProp ("url");
+ string alias = node->getProp ("name");
+ if (load_source( alias, url, "url", false ) <= 0) {
+ cerr << "Can't setup 'source'" << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("undump")) {
+
+ string file = node->getProp ("file");
+ undump (file);
+
+ } else if (node->equals ("force-install")) {
+
+ string source_alias = node->getProp ("channel");
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem (source_alias, package_name, kind_name);
+ if (poolItem) {
+ RESULT << "Force-installing " << package_name << " from channel " << source_alias << endl;;
+
+ poolItem.status().setStatus(ResStatus::installed);
+
+#if 0
+ Source_Ref system_source = manager->findSource("@system");
+
+ if (!system_source)
+ cerr << "No system source available!" << endl;
+ PoolItem_Ref r = boost::const_pointer_cast<PoolItem>(poolItem);
+ r->setChannel (system_source);
+#endif
+ } else {
+ cerr << "Unknown package " << source_alias << "::" << package_name << endl;
+ }
+
+ } else if (node->equals ("force-uninstall")) {
+
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem ("@system", package_name, kind_name);
+
+ if (! poolItem) {
+ cerr << "Can't force-uninstall installed package '" << package_name << "'" << endl;
+ } else {
+ RESULT << "Force-uninstalling " << package_name << endl;
+ poolItem.status().setStatus(ResStatus::uninstalled);
+#if 0
+ God->pool().remove (poolItem);
+#endif
+ }
+
+ } else if (node->equals ("lock")) {
+
+ string source_alias = node->getProp ("channel");
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem (source_alias, package_name, kind_name);
+ if (poolItem) {
+ RESULT << "Locking " << package_name << " from channel " << source_alias << endl;
+ poolItem.status().setLock (true, ResStatus::USER);
+ } else {
+ cerr << "Unknown package " << source_alias << "::" << package_name << endl;
+ }
+
+ } else if (node->equals ("mediaid")) {
+ show_mediaid = true;
+ } else if (node->equals ("arch")) {
+ cerr << " deprecated, use instead" << endl;
+ architecture = node->getProp ("name");
+ if (architecture.empty()) {
+ cerr << "Property 'name=' in missing or empty" << endl;
+ }
+ else {
+ MIL << "Setting architecture to '" << architecture << "'" << endl;
+ God->setArchitecture( Arch( architecture ) );
+ setenv ("ZYPP_TESTSUITE_FAKE_ARCH", architecture.c_str(), 1);
+ }
+ } else if (node->equals ("locale")) {
+ string loc = node->getProp ("name");
+ if (loc.empty())
+ cerr << "Bad or missing name in " << endl;
+ else {
+ RESULT << "Requesting locale " << loc << endl;
+ locales.insert( Locale( loc ) );
+ }
+ }else if (node->equals("setlicencebit")){
+ set_licence = true;
+ } else {
+ cerr << "Unrecognized tag '" << node->name() << "' in setup" << endl;
+ }
+
+ node = node->next();
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+// trial related functions
+
+static void
+report_solutions ( solver::detail::Resolver_Ptr resolver, bool instorder, bool mediaorder)
+{
+ int count = 1;
+ ChecksumList checksum_list;
+
+ cout << endl;
+
+ if (!resolver->completeQueues().empty()) {
+ cout << "Completed solutions: " << (long) resolver->completeQueues().size() << endl;
+ }
+
+ if (resolver->prunedQueues().empty()) {
+ cout << "Pruned solutions: " << (long) resolver->prunedQueues().size() << endl;
+ }
+
+ if (resolver->deferredQueues().empty()) {
+ cout << "Deferred solutions: " << (long) resolver->deferredQueues().size() << endl;
+ }
+
+ if (resolver->invalidQueues().empty()) {
+ cout << "Invalid solutions: " << (long) resolver->invalidQueues().size() << endl;
+ }
+
+ if (resolver->bestContext()) {
+ cout << endl << "Best Solution:" << endl;
+ print_solution (resolver->bestContext(), &count, checksum_list, instorder, mediaorder);
+
+ ResolverQueueList complete = resolver->completeQueues();
+ if (complete.size() > 1)
+ cout << endl << "Other Valid Solutions:" << endl;
+
+ if (complete.size() < 20) {
+ for (ResolverQueueList::const_iterator iter = complete.begin(); iter != complete.end(); iter++) {
+ ResolverQueue_Ptr queue = (*iter);
+ if (queue->context() != resolver->bestContext())
+ print_solution (queue->context(), &count, checksum_list, instorder, mediaorder);
+ }
+ }
+ }
+
+ ResolverQueueList invalid = resolver->invalidQueues();
+ if (invalid.size() < 20) {
+ cout << endl;
+
+ for (ResolverQueueList::const_iterator iter = invalid.begin(); iter != invalid.end(); iter++) {
+ ResolverQueue_Ptr queue = (*iter);
+ cout << "Failed Solution: " << endl << *queue->context() << endl;
+ cout << "- - - - - - - - - -" << endl;
+ queue->context()->spewInfo ();
+ fflush (stdout);
+ }
+ } else {
+ cout << "(Not displaying more than 20 invalid solutions)" << endl;
+ }
+ fflush (stdout);
+}
+
+//-----------------------------------------------------------------------------
+// system Upgrade
+
+struct Unique : public resfilter::PoolItemFilterFunctor
+{
+ PoolItemSet itemset;
+
+ bool operator()( PoolItem_Ref poolItem )
+ {
+ itemset.insert (poolItem);
+ return true;
+ }
+};
+
+
+// collect all installed items in a set
+
+PoolItemSet
+uniquelyInstalled (void)
+{
+ Unique info;
+
+ invokeOnEach( God->pool().begin( ),
+ God->pool().end ( ),
+ resfilter::ByInstalled (),
+ functor::functorRef (info) );
+ return info.itemset;
+}
+
+
+// keep upgrades in a map to achieve lexically sorted debug output
+
+typedef pair UpgradePair;
+typedef map UpgradeMap;
+
+struct DoUpgrades : public resfilter::PoolItemFilterFunctor
+{
+ PoolItem_Ref installed;
+ UpgradeMap upgrades;
+// PoolItemSet upgrades;
+ solver::detail::Resolver_Ptr resolver;
+ int count;
+
+ DoUpgrades (solver::detail::Resolver_Ptr r)
+ : resolver (r)
+ , count (0)
+ { }
+
+ bool operator()( PoolItem_Ref poolItem )
+ {
+ if (installed->edition().compare (poolItem->edition()) < 0) {
+
+ UpgradeMap::const_iterator pos = upgrades.find(poolItem->name());
+ if (pos == upgrades.end()) {
+ upgrades[poolItem->name()] = make_pair (installed, poolItem);
+ ++count;
+ return false;
+ }
+ }
+#if 0 // disabled in favor of lexical ordering
+ if (upgrades.insert (poolItem).second) { // only consider first match
+ resolver->addPoolItemToInstall (poolItem);
+ RESULT << "Upgrading ";
+ printRes (cout, installed);
+ cout << " => ";
+ printRes (cout, poolItem);
+ cout << endl;
+ ++count;
+ }
+#endif
+ return true;
+ }
+};
+
+
+int
+foreach_system_upgrade (solver::detail::Resolver_Ptr resolver)
+{
+ PoolItemSet installed = uniquelyInstalled();
+ DoUpgrades info (resolver);
+
+ // world->foreachSystemUpgrade (true, trial_upgrade_cb, (void *)&resolver);
+
+ for (PoolItemSet::iterator iter = installed.begin(); iter != installed.end(); ++iter) {
+ PoolItem_Ref p = *iter;
+ if (!p.status().transacts()) continue;
+ info.installed = p;
+ invokeOnEach( God->pool().byNameBegin( p->name() ), God->pool().byNameEnd( p->name() ),
+ functor::chain( resfilter::ByUninstalled(), resfilter::ByKind( p->kind() ) ),
+#if 0
+ functor::chain( resfilter::ByUninstalled(),
+ functor::chain( resfilter::ByKind( p->kind() ),
+ resfilter::byEdition( p->edition() ) ) ),
+#endif
+ functor::functorRef(info) );
+
+ }
+
+ // now output in alphabetical order
+
+ for (UpgradeMap::const_iterator iter = info.upgrades.begin(); iter != info.upgrades.end(); ++iter) {
+ UpgradePair i_and_u = iter->second;
+ resolver->addPoolItemToInstall (i_and_u.second);
+ RESULT << "Upgrading ";
+ printRes (cout, i_and_u.first);
+ cout << " => ";
+ printRes (cout, i_and_u.second);
+ cout << endl;
+ }
+
+ return info.count;
+}
+
+//-----------------------------------------------------------------------------
+// ResolverContext output
+
+static void
+print_marked_cb (PoolItem_Ref poolItem, const ResStatus & status, void *data)
+{
+ if (data == NULL) {
+ RESULT; printRes (cout, poolItem.resolvable()); cout << " " << status << endl;
+ } else {
+ StringList *slist = (StringList *)data;
+ ostringstream s;
+ printRes (s, poolItem.resolvable());
+ s << " " << status;
+ slist->push_back (s.str());
+ }
+
+ return;
+}
+
+
+static void
+freshen_marked_cb (PoolItem_Ref poolItem, const ResStatus & status, void *data)
+{
+ solver::detail::Resolver_Ptr resolver = *((solver::detail::Resolver_Ptr *)data);
+ if (status.isNeeded()) {
+ poolItem.status().setToBeInstalled(ResStatus::USER);
+// resolver->addPoolItemToInstall (poolItem);
+ }
+
+ return;
+}
+
+
+static void
+parse_xml_trial (XmlNode_Ptr node, const ResPool & pool)
+{
+ static bool first_trial = true;
+
+ bool verify = false;
+ bool instorder = false;
+ bool mediaorder = false;
+ bool distupgrade = false;
+
+ if (!node->equals ("trial")) {
+ ZYPP_THROW (Exception ("Node not 'trial' in parse_xml_trial()"));
+ }
+
+ DBG << "parse_xml_trial()" << endl;
+
+ // reset pool on subsequent trials.
+
+ if (first_trial) {
+ first_trial = false;
+ }
+ else {
+ for (ResPool::const_iterator it = pool.begin(); it != pool.end(); ++it) {
+ if (it->status().transacts()) it->status().resetTransact( ResStatus::USER );
+ }
+ }
+
+ if (! done_setup) {
+ cerr << "Any trials must be preceeded by the setup!" << endl;
+ exit (0);
+ }
+
+ print_sep ();
+
+ resolver = new solver::detail::Resolver( pool );
+ resolver->setArchitecture( God->architecture() );
+ resolver->setTesting ( true ); // continue despite missing target
+ resolver->setForceResolve( forceResolve );
+ resolver->setMaxSolverPasses( maxSolverPasses );
+
+ if (!locales.empty()) {
+ God->setRequestedLocales( locales );
+ }
+
+ node = node->children();
+ while (node) {
+ if (!node->isElement()) {
+ node = node->next();
+ continue;
+ }
+
+ if (node->equals("note")) {
+
+ string note = node->getContent ();
+ cout << "NOTE: " << note << endl;
+
+ } else if (node->equals ("verify")) {
+
+ verify = true;
+
+ } else if (node->equals ("current")) {
+
+ string source_alias = node->getProp ("channel");
+ Source_Ref source = manager->findSource (source_alias);
+
+ if (source) {
+//FIXME resolver->setCurrentChannel (source);
+ } else {
+ cerr << "Unknown source '" << source_alias << "' (current)" << endl;
+ }
+
+ } else if (node->equals ("subscribe")) {
+
+ string source_alias = node->getProp ("channel");
+ Source_Ref source = manager->findSource (source_alias);
+
+ if (source) {
+//FIXME source->setSubscription (true);
+ } else {
+ cerr << "Unknown source '" << source_alias << "' (subscribe)" << endl;
+ }
+
+ } else if (node->equals ("install")) {
+
+ string source_alias = node->getProp ("channel");
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+ string soft = node->getProp ("soft");
+ string version = node->getProp ("ver");
+ string release = node->getProp ("rel");
+ string architecture = node->getProp ("arch");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem( source_alias, name, kind_name, version, release, architecture );
+ if (poolItem) {
+ RESULT << "Installing "
+ << ((poolItem->kind() != ResTraitszypp::Package::kind) ? (poolItem->kind().asString() + ":") : "")
+ << name
+ << (version.empty()?"":(string("-")+poolItem->edition().version()))
+ << (release.empty()?"":(string("-")+poolItem->edition().release()))
+ << (architecture.empty()?"":(string(".")+poolItem->arch().asString()))
+ << " from channel " << source_alias << endl;;
+ poolItem.status().setToBeInstalled(ResStatus::USER);
+ if (!soft.empty())
+ poolItem.status().setSoftInstall(true);
+// resolver->addPoolItemToInstall (poolItem);
+ } else {
+ cerr << "Unknown item " << source_alias << "::" << name << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("uninstall")) {
+
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+ string soft = node->getProp ("soft");
+ string version = node->getProp ("ver");
+ string release = node->getProp ("rel");
+ string architecture = node->getProp ("arch");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem ("@system", name, kind_name, version, release, architecture );
+ if (poolItem) {
+ RESULT << "Uninstalling " << name
+ << (version.empty()?"":(string("-")+poolItem->edition().version()))
+ << (release.empty()?"":(string("-")+poolItem->edition().release()))
+ << (architecture.empty()?"":(string(".")+poolItem->arch().asString()))
+ << endl;
+ poolItem.status().setToBeUninstalled(ResStatus::USER);
+ if (!soft.empty())
+ poolItem.status().setSoftUninstall(true);
+#if 0 // replaced by 'transact'
+ if ( kind_name== "selection"
+ || kind_name == "pattern" ) {
+ // -> do a 'single step' resolving either installing or removing
+ // required and recommended PoolItems; this will be used by the YaST UI
+ resolver->transactResObject ( poolItem, false);
+ }
+#endif
+// resolver->addPoolItemToRemove (poolItem);
+ } else {
+ cerr << "Unknown system item " << name << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("upgrade")) {
+
+ RESULT << "Checking for upgrades..." << endl;
+
+ int count = foreach_system_upgrade (resolver);
+
+ if (count == 0)
+ RESULT << "System is up-to-date, no upgrades required" << endl;
+ else
+ RESULT << "Upgrading " << count << " package" << (count > 1 ? "s" : "") << endl;
+
+ } else if (node->equals ("distupgrade")) {
+
+ distupgrade = true;
+
+ RESULT << "Doing distribution upgrade ..." << endl;
+ UpgradeStatistics stats;
+
+ string delete_unmaintained = node->getProp ("delete_unmaintained");
+ if (delete_unmaintained == "false") {
+ stats.delete_unmaintained = false;
+ } else {
+ stats.delete_unmaintained = true;
+ }
+
+ resolver->doUpgrade(stats);
+
+ print_pool( resolver, MARKER );
+
+ } else if (node->equals ("establish")) {
+
+ string freshen = node->getProp ("freshen");
+
+ RESULT << "Establishing state ..." << endl;
+
+ if (!resolver->establishPool()) {
+ RESULT << "Established NO context !" << endl;
+ }
+ else {
+ RESULT << "Established context" << endl;
+ StringList items;
+
+ resolver->context()->foreachMarked (print_marked_cb, &items);
+ print_items (items);
+// print_pool( MARKER, "false" );
+ if (!freshen.empty()) {
+ RESULT << "Freshening ..." << endl;
+ resolver->context()->foreachMarked (freshen_marked_cb, &resolver);
+ }
+ }
+
+ } else if (node->equals ("freshen")) {
+
+ RESULT << "Freshening pool ..." << endl;
+
+ if (!resolver->freshenPool()) {
+ RESULT << "Freshened NO context !" << endl;
+ }
+ else {
+ RESULT << "Freshened context" << endl;
+ StringList items;
+
+ resolver->context()->foreachMarked (print_marked_cb, &items);
+ print_items (items);
+ }
+
+ } else if (node->equals ("instorder")) {
+
+ RESULT << "Calculating installation order ..." << endl;
+
+ instorder = true;
+
+ } else if (node->equals ("maxSolverPasses")) {
+ maxSolverPasses = atoi ((node->getProp ("value")).c_str());
+
+ } else if (node->equals ("mediaorder")) {
+
+ RESULT << "Calculating media installation order ..." << endl;
+
+ mediaorder = true;
+
+ } else if (node->equals ("solvedeps")) {
+#if 0
+ XmlNode_Ptr iter = node->children();
+
+ while (iter != NULL) {
+ Dependency_Ptr dep = new Dependency (iter);
+
+ /* We just skip over anything that doesn't look like a dependency. */
+
+ if (dep) {
+ string conflict_str = iter->getProp ("conflict");
+
+ RESULT << "Solvedeps " << (conflict_str.empty() ? "" : "conflict ") << dep->asString().c_str() << endl;
+
+ resolver->addExtraDependency (dep);
+
+ }
+ iter = iter->next();
+ }
+#else
+#warning solvedeps disabled
+#endif
+
+ } else if (node->equals ("whatprovides")) {
+
+ string kind_name = node->getProp ("kind");
+ string prov_name = node->getProp ("provides");
+
+ PoolItemSet poolItems;
+
+ cout << "poolItems providing '" << prov_name << "'" << endl;
+
+ poolItems = get_providing_poolItems (prov_name, kind_name);
+
+ if (poolItems.empty()) {
+ cerr << "None found" << endl;
+ } else {
+ for (PoolItemSet::const_iterator iter = poolItems.begin(); iter != poolItems.end(); ++iter) {
+ cout << (*iter) << endl;
+ }
+ }
+
+ } else if (node->equals ("whatdependson")) {
+
+ string source_alias = node->getProp ("channel");
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+ string prov_name = node->getProp ("provides");
+
+ PoolItemSet poolItems;
+
+ assert (!source_alias.empty());
+ assert (!package_name.empty());
+
+ if (!prov_name.empty()) {
+ if (!package_name.empty()) {
+ cerr << " can't have both package and provides." << endl;
+ exit (1);
+ }
+ poolItems = get_providing_poolItems (prov_name, kind_name);
+ }
+ else {
+ PoolItem_Ref poolItem = get_poolItem (source_alias, package_name, kind_name);
+ if (poolItem) poolItems.insert (poolItem);
+ }
+ if (poolItems.empty()) {
+ cerr << "Can't find matching package" << endl;
+ } else {
+ for (PoolItemSet::const_iterator iter = poolItems.begin(); iter != poolItems.end(); ++iter) {
+ PoolItemSet dependants = whatdependson (*iter);
+ for (PoolItemSet::const_iterator dep_iter = dependants.begin(); dep_iter != dependants.end(); ++dep_iter) {
+ cout << (*dep_iter) << endl;
+ }
+ }
+ }
+ } else if (node->equals ("addProvide")) {
+ addDependencies (node->getProp ("kind") , node->getProp ("name"), PROVIDE, pool);
+ } else if (node->equals ("addConflict")) {
+ addDependencies (node->getProp ("kind") , node->getProp ("name"), CONFLICT, pool);
+ } else if (node->equals ("addRequire")) {
+ addDependencies (node->getProp ("kind") , node->getProp ("name"), REQUIRE, pool);
+ } else if (node->equals ("reportproblems")) {
+ if (resolver->resolvePool() == true
+ && node->getProp ("ignoreValidSolution").empty()) {
+ RESULT << "No problems so far" << endl;
+ }
+ else {
+ ResolverProblemList problems = resolver->problems (true);
+ problems.sort(compare_problems());
+ RESULT << problems.size() << " problems found:" << endl;
+ for (ResolverProblemList::iterator iter = problems.begin(); iter != problems.end(); ++iter) {
+ ResolverProblem problem = **iter;
+ RESULT << "Problem:" << endl;
+ RESULT << problem.description() << endl;
+ RESULT << problem.details() << endl;
+
+ ProblemSolutionList solutions = problem.solutions();
+ for (ProblemSolutionList::const_iterator iter = solutions.begin();
+ iter != solutions.end(); ++iter) {
+ ProblemSolution solution = **iter;
+ RESULT << " Solution:" << endl;
+ RESULT << " " << solution.description() << endl;
+ RESULT << " " << solution.details() << endl;
+ }
+ }
+ }
+ } else if (node->equals ("takesolution")) {
+ string problemNrStr = node->getProp ("problem");
+ string solutionNrStr = node->getProp ("solution");
+ assert (!problemNrStr.empty());
+ assert (!solutionNrStr.empty());
+ int problemNr = atoi (problemNrStr.c_str());
+ int solutionNr = atoi (solutionNrStr.c_str());
+ RESULT << "Taking solution: " << solutionNr << endl;
+ RESULT << "For problem: " << problemNr << endl;
+ ResolverProblemList problems = resolver->problems ();
+
+ int problemCounter = -1;
+ int solutionCounter = -1;
+ // find problem
+ for (ResolverProblemList::iterator probIter = problems.begin();
+ probIter != problems.end(); ++probIter) {
+ problemCounter++;
+ if (problemCounter == problemNr) {
+ ResolverProblem problem = **probIter;
+ ProblemSolutionList solutionList = problem.solutions();
+ //find solution
+ for (ProblemSolutionList::iterator solIter = solutionList.begin();
+ solIter != solutionList.end(); ++solIter) {
+ solutionCounter++;
+ if (solutionCounter == solutionNr) {
+ ProblemSolution_Ptr solution = *solIter;
+ cout << "Taking solution: " << endl << *solution << endl;
+ cout << "For problem: " << endl << problem << endl;
+ ProblemSolutionList doList;
+ doList.push_back (solution);
+ resolver->applySolutions (doList);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (problemCounter != problemNr) {
+ RESULT << "Wrong problem number (0-" << problemCounter << ")" << endl;
+ } else if (solutionCounter != solutionNr) {
+ RESULT << "Wrong solution number (0-" << solutionCounter << ")" <resolvePool() == true) {
+ RESULT << "No problems so far" << endl;
+ }
+ else {
+ ResolverProblemList problems = resolver->problems ();
+ RESULT << problems.size() << " problems found:" << endl;
+ for (ResolverProblemList::iterator iter = problems.begin(); iter != problems.end(); ++iter) {
+ cout << **iter << endl;
+ }
+ }
+ }
+ } else if (node->equals ("showpool")) {
+ string prefix = node->getProp ("prefix");
+ string all = node->getProp ("all");
+ string get_licence = node->getProp ("getlicence");
+ string verbose = node->getProp ("verbose");
+ print_pool( resolver, prefix, !all.empty(), get_licence, !verbose.empty() );
+ } else if (node->equals ("lock")) {
+ string source_alias = node->getProp ("channel");
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem (source_alias, package_name, kind_name);
+ if (poolItem) {
+ RESULT << "Locking " << package_name << " from channel " << source_alias << endl;
+ poolItem.status().setLock (true, ResStatus::USER);
+ } else {
+ cerr << "Unknown package " << source_alias << "::" << package_name << endl;
+ }
+ } else if (node->equals ("availablelocales")) {
+ RESULT << "Available locales: ";
+ ZYpp::LocaleSet locales = God->getAvailableLocales();
+ for (ZYpp::LocaleSet::const_iterator it = locales.begin(); it != locales.end(); ++it) {
+ if (it != locales.begin()) std::cout << ", ";
+ std::cout << it->code();
+ }
+ std::cout << endl;
+
+ } else if (node->equals ("transact")) {
+
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ string source_alias = node->getProp ("channel");
+ if (source_alias.empty())
+ source_alias = "@system";
+
+ if (!name.empty()
+ && !kind_name.empty())
+ {
+ cerr << "transact either takes 'name' or 'kind', but not both" << endl;
+ return;
+ }
+
+ if (name.empty()
+ && kind_name.empty())
+ {
+ cerr << "transact need either 'name' or 'kind' parameter" << endl;
+ return;
+ }
+
+ if (name.empty()) { // assume kind
+ RESULT << "Calling transactResKind( " << kind_name << " )" << endl;;
+ resolver->transactResKind( string2kind( kind_name ) );
+ }
+ else {
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem( source_alias, name, kind_name );
+
+ if (poolItem) {
+ if (source_alias == "@system") {
+ RESULT << "Removing " << name << " from channel " << source_alias << endl;;
+ poolItem.status().setToBeUninstalled( ResStatus::USER );
+ }
+ else {
+ RESULT << "Installing " << name << " from channel " << source_alias << endl;;
+ poolItem.status().setToBeInstalled( ResStatus::USER );
+ }
+ resolver->transactResObject( poolItem, false );
+ }
+ else {
+ cerr << "Unknown item " << source_alias << "::" << name << endl;
+ }
+
+ }
+
+ } else if (node->equals ("keep")) {
+ string kind_name = node->getProp ("kind");
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+
+ string source_alias = node->getProp ("channel");
+ if (source_alias.empty())
+ source_alias = "@system";
+
+ if (name.empty())
+ {
+ cerr << "transact need 'name' parameter" << endl;
+ return;
+ }
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem( source_alias, name, kind_name );
+
+ if (poolItem) {
+ // first: set anything
+ if (source_alias == "@system") {
+ poolItem.status().setToBeUninstalled( ResStatus::USER );
+ }
+ else {
+ poolItem.status().setToBeInstalled( ResStatus::USER );
+ }
+ // second: keep old state
+ poolItem.status().setTransact( false, ResStatus::USER );
+ }
+ else {
+ cerr << "Unknown item " << source_alias << "::" << name << endl;
+ }
+ } else if (node->equals ("createTestcase")) {
+ string path = node->getProp ("path");
+ if (path.empty())
+ path = ".";
+ Testcase testcase (path);
+ testcase.createTestcase (*resolver);
+
+ } else {
+ cerr << "Unknown tag '" << node->name() << "' in trial" << endl;
+ }
+
+ node = node->next();
+ }
+
+ if (getenv ("RC_DEPS_TIME")) {
+ int timeout = atoi (getenv ("RC_DEPS_TIME"));
+
+ resolver->setTimeout (timeout);
+ }
+
+ if (verify)
+ resolver->verifySystem ();
+#if 0
+ else if (distupgrade)
+ resolver->resolvePool();
+ else
+ resolver->resolveDependencies (established);
+#else
+ else
+ resolver->resolvePool();
+
+#endif
+
+ report_solutions (resolver, instorder, mediaorder);
+}
+
+static void
+parse_xml_transact (XmlNode_Ptr node, const ResPool & pool)
+{
+ static bool first_transact = true;
+
+ bool verify = false;
+ bool instorder = false;
+ bool mediaorder = false;
+ bool distupgrade = false;
+
+ if (!node->equals ("transact")) {
+ ZYPP_THROW (Exception ("Node not 'transact' in parse_xml_transact()"));
+ }
+
+ DBG << "parse_xml_transact()" << endl;
+
+ // reset pool on subsequent transacts.
+
+ if (first_transact) {
+ first_transact = false;
+ }
+ else {
+ for (ResPool::const_iterator it = pool.begin(); it != pool.end(); ++it) {
+ if (it->status().transacts()) it->status().resetTransact( ResStatus::USER );
+ }
+ }
+
+ if (! done_setup) {
+ cerr << "Any transacts must be preceeded by the setup!" << endl;
+ exit (0);
+ }
+
+ print_sep ();
+
+ resolver = new solver::detail::Resolver( pool );
+ resolver->setArchitecture( God->architecture() );
+ resolver->setTesting ( true ); // continue despite missing target
+ resolver->setForceResolve( forceResolve );
+
+ if (!locales.empty()) {
+ God->setRequestedLocales( locales );
+ }
+
+ node = node->children();
+ while (node) {
+ if (!node->isElement()) {
+ node = node->next();
+ continue;
+ }
+
+ if (node->equals("note")) {
+
+ string note = node->getContent ();
+ cout << "NOTE: " << note << endl;
+
+ } else if (node->equals ("verify")) {
+
+ verify = true;
+
+ } else if (node->equals ("current")) {
+
+ string source_alias = node->getProp ("channel");
+ Source_Ref source = manager->findSource (source_alias);
+
+ if (source) {
+//FIXME resolver->setCurrentChannel (source);
+ } else {
+ cerr << "Unknown source '" << source_alias << "' (current)" << endl;
+ }
+
+ } else if (node->equals ("subscribe")) {
+
+ string source_alias = node->getProp ("channel");
+ Source_Ref source = manager->findSource (source_alias);
+
+ if (source) {
+//FIXME source->setSubscription (true);
+ } else {
+ cerr << "Unknown source '" << source_alias << "' (subscribe)" << endl;
+ }
+
+ } else if (node->equals ("install")) {
+
+ string source_alias = node->getProp ("channel");
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+ string soft = node->getProp ("soft");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem (source_alias, name, kind_name);
+ if (poolItem) {
+ RESULT << "Installing " << ((poolItem->kind() != ResTraitszypp::Package::kind) ? (poolItem->kind().asString() + ":") : "") << name << " from channel " << source_alias << endl;;
+ poolItem.status().setToBeInstalled(ResStatus::USER);
+ if (!soft.empty())
+ poolItem.status().setSoftInstall(true);
+// resolver->addPoolItemToInstall (poolItem);
+ } else {
+ cerr << "Unknown item " << source_alias << "::" << name << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("uninstall")) {
+
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+ string soft = node->getProp ("soft");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem ("@system", name, kind_name);
+ if (poolItem) {
+ RESULT << "Uninstalling " << name << endl;
+ poolItem.status().setToBeUninstalled(ResStatus::USER);
+ if (!soft.empty())
+ poolItem.status().setSoftUninstall(true);
+#if 0 // replaced by 'transact'
+ if ( kind_name== "selection"
+ || kind_name == "pattern" ) {
+ // -> do a 'single step' resolving either installing or removing
+ // required and recommended PoolItems; this will be used by the YaST UI
+ resolver->transactResObject ( poolItem, false);
+ }
+#endif
+// resolver->addPoolItemToRemove (poolItem);
+ } else {
+ cerr << "Unknown system item " << name << endl;
+ exit( 1 );
+ }
+
+ } else if (node->equals ("upgrade")) {
+
+ RESULT << "Checking for upgrades..." << endl;
+
+ int count = foreach_system_upgrade (resolver);
+
+ if (count == 0)
+ RESULT << "System is up-to-date, no upgrades required" << endl;
+ else
+ RESULT << "Upgrading " << count << " package" << (count > 1 ? "s" : "") << endl;
+
+ } else if (node->equals ("distupgrade")) {
+
+ distupgrade = true;
+
+ RESULT << "Doing distribution upgrade ..." << endl;
+ UpgradeStatistics stats;
+
+ string delete_unmaintained = node->getProp ("delete_unmaintained");
+ if (delete_unmaintained == "false") {
+ stats.delete_unmaintained = false;
+ } else {
+ stats.delete_unmaintained = true;
+ }
+
+ resolver->doUpgrade(stats);
+
+ print_pool( resolver, MARKER );
+
+ } else if (node->equals ("establish")) {
+
+ string freshen = node->getProp ("freshen");
+
+ RESULT << "Establishing state ..." << endl;
+
+ if (!resolver->establishPool()) {
+ RESULT << "Established NO context !" << endl;
+ }
+ else {
+ RESULT << "Established context" << endl;
+ StringList items;
+
+ resolver->context()->foreachMarked (print_marked_cb, &items);
+ print_items (items);
+// print_pool( MARKER, "false" );
+ if (!freshen.empty()) {
+ RESULT << "Freshening ..." << endl;
+ resolver->context()->foreachMarked (freshen_marked_cb, &resolver);
+ }
+ }
+
+ } else if (node->equals ("freshen")) {
+
+ RESULT << "Freshening pool ..." << endl;
+
+ if (!resolver->freshenPool()) {
+ RESULT << "Freshened NO context !" << endl;
+ }
+ else {
+ RESULT << "Freshened context" << endl;
+ StringList items;
+
+ resolver->context()->foreachMarked (print_marked_cb, &items);
+ print_items (items);
+ }
+
+ } else if (node->equals ("instorder")) {
+
+ RESULT << "Calculating installation order ..." << endl;
+
+ instorder = true;
+
+ } else if (node->equals ("mediaorder")) {
+
+ RESULT << "Calculating media installation order ..." << endl;
+
+ mediaorder = true;
+
+ } else if (node->equals ("solvedeps")) {
+#if 0
+ XmlNode_Ptr iter = node->children();
+
+ while (iter != NULL) {
+ Dependency_Ptr dep = new Dependency (iter);
+
+ /* We just skip over anything that doesn't look like a dependency. */
+
+ if (dep) {
+ string conflict_str = iter->getProp ("conflict");
+
+ RESULT << "Solvedeps " << (conflict_str.empty() ? "" : "conflict ") << dep->asString().c_str() << endl;
+
+ resolver->addExtraDependency (dep);
+
+ }
+ iter = iter->next();
+ }
+#else
+#warning solvedeps disabled
+#endif
+
+ } else if (node->equals ("whatprovides")) {
+
+ string kind_name = node->getProp ("kind");
+ string prov_name = node->getProp ("provides");
+
+ PoolItemSet poolItems;
+
+ cout << "poolItems providing '" << prov_name << "'" << endl;
+
+ poolItems = get_providing_poolItems (prov_name, kind_name);
+
+ if (poolItems.empty()) {
+ cerr << "None found" << endl;
+ } else {
+ for (PoolItemSet::const_iterator iter = poolItems.begin(); iter != poolItems.end(); ++iter) {
+ cout << (*iter) << endl;
+ }
+ }
+
+ } else if (node->equals ("whatdependson")) {
+
+ string source_alias = node->getProp ("channel");
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+ string prov_name = node->getProp ("provides");
+
+ PoolItemSet poolItems;
+
+ assert (!source_alias.empty());
+ assert (!package_name.empty());
+
+ if (!prov_name.empty()) {
+ if (!package_name.empty()) {
+ cerr << " can't have both package and provides." << endl;
+ exit (1);
+ }
+ poolItems = get_providing_poolItems (prov_name, kind_name);
+ }
+ else {
+ PoolItem_Ref poolItem = get_poolItem (source_alias, package_name, kind_name);
+ if (poolItem) poolItems.insert (poolItem);
+ }
+ if (poolItems.empty()) {
+ cerr << "Can't find matching package" << endl;
+ } else {
+ for (PoolItemSet::const_iterator iter = poolItems.begin(); iter != poolItems.end(); ++iter) {
+ PoolItemSet dependants = whatdependson (*iter);
+ for (PoolItemSet::const_iterator dep_iter = dependants.begin(); dep_iter != dependants.end(); ++dep_iter) {
+ cout << (*dep_iter) << endl;
+ }
+ }
+ }
+
+ } else if (node->equals ("reportproblems")) {
+ if (resolver->resolvePool() == true) {
+ RESULT << "No problems so far" << endl;
+ }
+ else {
+ ResolverProblemList problems = resolver->problems ();
+ problems.sort(compare_problems());
+ RESULT << problems.size() << " problems found:" << endl;
+ for (ResolverProblemList::iterator iter = problems.begin(); iter != problems.end(); ++iter) {
+ ResolverProblem problem = **iter;
+ RESULT << "Problem:" << endl;
+ RESULT << problem.description() << endl;
+ RESULT << problem.details() << endl;
+
+ ProblemSolutionList solutions = problem.solutions();
+ for (ProblemSolutionList::const_iterator iter = solutions.begin();
+ iter != solutions.end(); ++iter) {
+ ProblemSolution solution = **iter;
+ RESULT << " Solution:" << endl;
+ RESULT << " " << solution.description() << endl;
+ RESULT << " " << solution.details() << endl;
+ }
+ }
+ }
+ } else if (node->equals ("takesolution")) {
+ string problemNrStr = node->getProp ("problem");
+ string solutionNrStr = node->getProp ("solution");
+ assert (!problemNrStr.empty());
+ assert (!solutionNrStr.empty());
+ int problemNr = atoi (problemNrStr.c_str());
+ int solutionNr = atoi (solutionNrStr.c_str());
+ RESULT << "Taking solution: " << solutionNr << endl;
+ RESULT << "For problem: " << problemNr << endl;
+ ResolverProblemList problems = resolver->problems ();
+
+ int problemCounter = -1;
+ int solutionCounter = -1;
+ // find problem
+ for (ResolverProblemList::iterator probIter = problems.begin();
+ probIter != problems.end(); ++probIter) {
+ problemCounter++;
+ if (problemCounter == problemNr) {
+ ResolverProblem problem = **probIter;
+ ProblemSolutionList solutionList = problem.solutions();
+ //find solution
+ for (ProblemSolutionList::iterator solIter = solutionList.begin();
+ solIter != solutionList.end(); ++solIter) {
+ solutionCounter++;
+ if (solutionCounter == solutionNr) {
+ ProblemSolution_Ptr solution = *solIter;
+ cout << "Taking solution: " << endl << *solution << endl;
+ cout << "For problem: " << endl << problem << endl;
+ ProblemSolutionList doList;
+ doList.push_back (solution);
+ resolver->applySolutions (doList);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (problemCounter != problemNr) {
+ RESULT << "Wrong problem number (0-" << problemCounter << ")" << endl;
+ } else if (solutionCounter != solutionNr) {
+ RESULT << "Wrong solution number (0-" << solutionCounter << ")" <resolvePool() == true) {
+ RESULT << "No problems so far" << endl;
+ }
+ else {
+ ResolverProblemList problems = resolver->problems ();
+ RESULT << problems.size() << " problems found:" << endl;
+ for (ResolverProblemList::iterator iter = problems.begin(); iter != problems.end(); ++iter) {
+ cout << **iter << endl;
+ }
+ }
+ }
+ } else if (node->equals ("showpool")) {
+ string prefix = node->getProp ("prefix");
+ string all = node->getProp ("all");
+ string get_licence = node->getProp ("getlicence");
+ string verbose = node->getProp ("verbose");
+ print_pool( resolver, prefix, !all.empty(), get_licence, !verbose.empty() );
+ } else if (node->equals ("lock")) {
+ string source_alias = node->getProp ("channel");
+ string package_name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem (source_alias, package_name, kind_name);
+ if (poolItem) {
+ RESULT << "Locking " << package_name << " from channel " << source_alias << endl;
+ poolItem.status().setLock (true, ResStatus::USER);
+ } else {
+ cerr << "Unknown package " << source_alias << "::" << package_name << endl;
+ }
+ } else if (node->equals ("availablelocales")) {
+ RESULT << "Available locales: ";
+ ZYpp::LocaleSet locales = God->getAvailableLocales();
+ for (ZYpp::LocaleSet::const_iterator it = locales.begin(); it != locales.end(); ++it) {
+ if (it != locales.begin()) std::cout << ", ";
+ std::cout << it->code();
+ }
+ std::cout << endl;
+
+ } else if (node->equals ("transact")) {
+
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+ string kind_name = node->getProp ("kind");
+
+ string source_alias = node->getProp ("channel");
+ if (source_alias.empty())
+ source_alias = "@system";
+
+ if (!name.empty()
+ && !kind_name.empty())
+ {
+ cerr << "transact either takes 'name' or 'kind', but not both" << endl;
+ return;
+ }
+
+ if (name.empty()
+ && kind_name.empty())
+ {
+ cerr << "transact need either 'name' or 'kind' parameter" << endl;
+ return;
+ }
+
+ if (name.empty()) { // assume kind
+ resolver->transactResKind( string2kind( kind_name ) );
+ }
+ else {
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem( source_alias, name, kind_name );
+
+ if (poolItem) {
+ if (source_alias == "@system") {
+ RESULT << "Removing " << name << " from channel " << source_alias << endl;;
+ poolItem.status().setToBeUninstalled( ResStatus::USER );
+ }
+ else {
+ RESULT << "Installing " << name << " from channel " << source_alias << endl;;
+ poolItem.status().setToBeInstalled( ResStatus::USER );
+ }
+ resolver->transactResObject( poolItem, false );
+ }
+ else {
+ cerr << "Unknown item " << source_alias << "::" << name << endl;
+ }
+ }
+ } else if (node->equals ("keep")) {
+
+ string name = node->getProp ("name");
+ if (name.empty())
+ name = node->getProp ("package");
+
+ string source_alias = node->getProp ("channel");
+ if (source_alias.empty())
+ source_alias = "@system";
+
+ if (name.empty())
+ {
+ cerr << "transact need 'name' parameter" << endl;
+ return;
+ }
+
+ PoolItem_Ref poolItem;
+
+ poolItem = get_poolItem( source_alias, name, "" );
+
+ if (poolItem) {
+ // first: set anything
+ if (source_alias == "@system") {
+ poolItem.status().setToBeUninstalled( ResStatus::USER );
+ }
+ else {
+ poolItem.status().setToBeInstalled( ResStatus::USER );
+ }
+ // second: keep old state
+ poolItem.status().setTransact( false, ResStatus::USER );
+ resolver->transactResObject( poolItem, false );
+ }
+ else {
+ cerr << "Unknown item " << source_alias << "::" << name << endl;
+ }
+
+ } else {
+ cerr << "Unknown tag '" << node->name() << "' in transact" << endl;
+ }
+
+ node = node->next();
+ }
+
+print_pool( resolver, MARKER );
+ report_solutions (resolver, instorder, mediaorder);
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+
+static void
+parse_xml_test (XmlNode_Ptr node, const ResPool & pool)
+{
+ if (!node->equals("test")) {
+ ZYPP_THROW (Exception("Node not 'test' in parse_xml_test():"+node->name()));
+ }
+
+ node = node->children();
+
+ while (node) {
+ if (node->type() == XML_ELEMENT_NODE) {
+ if (node->equals( "setup" )) {
+ parse_xml_setup( node );
+ } else if (node->equals( "trial" )) {
+ parse_xml_trial( node, pool );
+ } else if (node->equals( "transact" )) {
+ parse_xml_transact( node, pool );
+ } else {
+ cerr << "Unknown tag '" << node->name() << "' in test" << endl;
+ }
+ }
+
+ node = node->next();
+ }
+}
+
+
+static void
+process_xml_test_file (const string & filename, const ResPool & pool)
+{
+ xmlDocPtr xml_doc;
+ XmlNode_Ptr root;
+
+ xml_doc = xmlParseFile (filename.c_str());
+ if (xml_doc == NULL) {
+ cerr << "Can't parse test file '" << filename << "'" << endl;
+ exit (0);
+ }
+
+ root = new XmlNode (xmlDocGetRootElement (xml_doc));
+
+ DBG << "Parsing file '" << filename << "'" << endl;
+
+ parse_xml_test (root, pool);
+
+ xmlFreeDoc (xml_doc);
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+
+int
+main (int argc, char *argv[])
+{
+// setenv("ZYPP_NOLOG","1",1); // no logging
+
+ if (argc != 2) {
+ cerr << "Usage: deptestomatic testfile.xml" << endl;
+ exit (0);
+ }
+ zypp::base::LogControl::instance().logfile( "-" );
+
+ forceResolve = false;
+ manager = SourceManager::sourceManager();
+
+ try {
+ God = zypp::getZYpp();
+ }
+ catch (const Exception & excpt_r ) {
+ ZYPP_CAUGHT( excpt_r );
+ cerr << "Can't aquire ZYpp lock" << endl;
+ return 1;
+ }
+
+ KeyRingCallbacks keyring_callbacks;
+ DigestCallbacks digest_callbacks;
+
+ globalPath = argv[1];
+ globalPath = globalPath.substr (0, globalPath.find_last_of ("/") +1);
+
+ DBG << "init_libzypp() done" << endl;
+
+ process_xml_test_file (string (argv[1]), God->pool());
+
+ QApplication app(argc, argv);
+
+ QZyppSolverDialog *dialog = new QZyppSolverDialog(resolver);
+ app.setMainWidget( dialog );
+ dialog->setCaption("Solvertree");
+ dialog->setMinimumSize ( 700, 700 );
+ dialog->show();
+
+ return app.exec();
+
+ return 0;
+}
+
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org