- fixed problems related to incorrect selection of, or check for update
authorJan Kupec <jkupec@suse.cz>
Sun, 5 Oct 2008 10:35:12 +0000 (10:35 +0000)
committerJan Kupec <jkupec@suse.cz>
Sun, 5 Oct 2008 10:35:12 +0000 (10:35 +0000)
  candidate (bnc #422141)

src/install.cc
src/update.cc
src/update.h

index 5a6a79d..5f23950 100755 (executable)
@@ -8,13 +8,17 @@
 #include "utils/misc.h"
 
 #include "install.h"
-
+#include "update.h"
+#include <iostream>
 using namespace std;
 using namespace zypp;
 using namespace boost;
 
 extern ZYpp::Ptr God;
 
+/** Use ui::Selectable::theObj() or candidateObj() */
+#define USE_THE_ONE 0
+
 // TODO edition, arch ?
 static void mark_for_install(Zypper & zypper,
                       const ResObject::Kind &kind,
@@ -47,32 +51,36 @@ static void mark_for_install(Zypper & zypper,
 
   ui::Selectable::Ptr s = *q.selectableBegin();
 
+#if USE_THE_ONE
+  PoolItem candidate = s->candidateObj();
+#else
+  PoolItem candidate = findUpdateItem(God->pool(), s->installedObj());
+  if (!candidate)
+    candidate = s->installedObj();
+#endif
+
   if (s->installedObj() &&
-      s->installedObj().resolvable()->edition() == s->candidateObj().resolvable()->edition() &&
-      s->installedObj().resolvable()->arch() == s->candidateObj().resolvable()->arch() &&
+      s->installedObj().resolvable()->edition() == candidate.resolvable()->edition() &&
+      s->installedObj().resolvable()->arch() == candidate.resolvable()->arch() &&
       ( ! copts.count("force") ) )
   {
     // if it is broken install anyway, even if it is installed
-    if ( s->candidateObj().isBroken() )
-    {
-      s->candidateObj().status().setTransact( true, zypp::ResStatus::USER );
-    }
+    if (candidate.isBroken())
+      candidate.status().setTransact(true, zypp::ResStatus::USER);
     else
-    {
       zypper.out().info(boost::str(format(
         // translators: e.g. skipping package 'zypper' (the newest version already installed)  
         _("skipping %s '%s' (the newest version already installed)"))
         % kind_to_string_localized(kind,1) % name));
-    }
   }
-  else {
-
+  else
+  {
     //! \todo don't use setToBeInstalled for this purpose but higher level solver API
-    bool result = s->candidateObj().status().setToBeInstalled( zypp::ResStatus::USER );
-    if (!result)
+    if (!candidate.status().setToBeInstalled(zypp::ResStatus::USER))
     {
+      cout << "no" << endl;
       // this is because the resolvable is installed and we are forcing.
-      s->candidateObj().status().setTransact( true, zypp::ResStatus::USER );
+      candidate.status().setTransact(true, zypp::ResStatus::USER);
       if (!copts.count("force"))
       {
         zypper.out().error(boost::str(
@@ -235,58 +243,6 @@ install_remove_preprocess_args(const Zypper::ArgList & args,
   DBG << endl;
 }
 
-#define USE_THE_ONE 0
-
-#if not USE_THE_ONE
-
-// ----------------------------------------------------------------------------
-
-class LookForUpdate : public zypp::resfilter::PoolItemFilterFunctor
-{
-public:
-  PoolItem best;
-
-  bool operator()( PoolItem provider )
-  {
-    if (!provider.status().isLocked() // is not locked (taboo)
-        && (!best                     // first match
-            // or a better edition than so-far-found
-            || best->edition().compare( provider->edition() ) < 0))
-    {
-      best = provider;
-    }
-    return true;
-  }
-};
-
-// ----------------------------------------------------------------------------
-
-// Find best (according to edition) uninstalled item
-// with same kind/name/arch as item.
-// Similar to zypp::solver::detail::Helper::findUpdateItem
-// but allows changing the vendor
-static
-PoolItem
-findUpdateItem( const ResPool & pool, PoolItem item )
-{
-  LookForUpdate info;
-
-  invokeOnEach( pool.byIdentBegin(item->kind(), item->name()),
-                pool.byIdentEnd(item->kind(), item->name()),
-                // get uninstalled, equal kind and arch, better edition
-                functor::chain (
-                  functor::chain (
-                    resfilter::ByUninstalled (),
-                    resfilter::byArch<CompareByEQ<Arch> >( item->arch() ) ),
-                  resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),
-                functor::functorRef<bool,PoolItem>(info));
-
-  XXX << "findArchUpdateItem(" << item << ") => " << info.best;
-  return info.best;
-}
-
-#endif
-
 // ----------------------------------------------------------------------------
 
 static void
index ff69dcf..14f98f2 100755 (executable)
@@ -202,51 +202,47 @@ static void list_patch_updates(Zypper & zypper)
 
 // ----------------------------------------------------------------------------
 
-// collect items, select best edition
-//   this is used to find best available or installed.
-// The name of the class is a bit misleading though ...
-
-class LookForArchUpdate : public zypp::resfilter::PoolItemFilterFunctor
+/*
+ * Collect items, select the best edition.
+ * This is used to find the best available or installed pool item from a set. 
+ */
+class SaveBetterEdition : public zypp::resfilter::PoolItemFilterFunctor
 {
 public:
   PoolItem best;
 
-  bool operator()( PoolItem provider )
+  bool operator()(PoolItem provider)
+  {
+    if (!provider.status().isLocked() // is not locked (taboo)
+        && (!best                     // first match
+            // or a better edition than so-far-found
+            || best->edition().compare(provider->edition()) < 0))
     {
-      if (!provider.status().isLocked() // is not locked (taboo)
-          && (!best                     // first match
-              // or a better edition than candidate
-              || best->edition().compare( provider->edition() ) < 0))
-      {
-        best = provider;        // store
-      }
-      return true;              // keep going
+      best = provider;
     }
+    return true;
+  }
 };
 
 // ----------------------------------------------------------------------------
 
-// Find best (according to edition) uninstalled item
-// with same kind/name/arch as item.
-// Similar to zypp::solver::detail::Helper::findUpdateItem
-// but that allows changing the arch (#222140).
-static
+// does not allow changing the arch (#222140).
 PoolItem
-findArchUpdateItem( const ResPool & pool, PoolItem item )
+findUpdateItem( const ResPool & pool, PoolItem item )
 {
-  LookForArchUpdate info;
+  SaveBetterEdition info;
 
-  invokeOnEach( pool.byIdentBegin( item->kind(), item->name() ),
-                pool.byIdentEnd( item->kind(), item->name() ),
+  invokeOnEach( pool.byIdentBegin(item->kind(), item->name()),
+                pool.byIdentEnd(item->kind(), item->name()),
                 // get uninstalled, equal kind and arch, better edition
-                functor::chain (
-                  functor::chain (
-                    resfilter::ByUninstalled (),
-                    resfilter::byArch<CompareByEQ<Arch> >( item->arch() ) ),
-                  resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),
-                functor::functorRef<bool,PoolItem> (info) );
-
-  _XDEBUG("findArchUpdateItem(" << item << ") => " << info.best);
+                functor::chain(
+                  functor::chain(
+                    resfilter::ByUninstalled(),
+                    resfilter::byArch<CompareByEQ<Arch> >(item->arch())),
+                  resfilter::byEdition<CompareByGT<Edition> >(item->edition())),
+                functor::functorRef<bool,PoolItem>(info));
+
+  XXX << "findUpdateItem(" << item << ") => " << info.best;
   return info.best;
 }
 
@@ -283,8 +279,8 @@ find_updates( const ResKind & kind, Candidates & candidates )
   {
     if (it->status().isUninstalled())
       continue;
-    // (actually similar to ProvideProcess?)
-    PoolItem candidate = findArchUpdateItem( pool, *it );
+
+    PoolItem candidate = findUpdateItem( pool, *it );
     if (!candidate.resolvable())
       continue;
 
@@ -451,23 +447,24 @@ mark_item_install (const PoolItem & pi)
 // best-effort update
 // ----------------------------------------------------------------------------
 
-// find installed item matching passed one
-//   use LookForArchUpdate as callback handler in order to cope with
-//   multiple installed resolvables of the same name.
-//   LookForArchUpdate will return the one with the highest edition.
-
+/*
+ * Find installed item matching passed one.
+ * Use SaveBetterEdition as callback handler in order to cope with
+ * multiple installed resolvables of the same name.
+ * SaveBetterEdition will return the one with the highest edition.
+ */
 static PoolItem
 findInstalledItem( PoolItem item )
 {
   const zypp::ResPool& pool = God->pool();
-  LookForArchUpdate info;
+  SaveBetterEdition info;
 
   invokeOnEach( pool.byIdentBegin( item->kind(), item->name() ),
                 pool.byIdentEnd( item->kind(), item->name() ),
                 resfilter::ByInstalled (),
                 functor::functorRef<bool,PoolItem> (info) );
 
-  _XDEBUG("findInstalledItem(" << item << ") => " << info.best);
+  XXX << "findInstalledItem(" << item << ") => " << info.best;
   return info.best;
 }
 
@@ -684,7 +681,19 @@ void mark_updates(Zypper & zypper, const ResKindSet & kinds, bool skip_interacti
           for_(solvit, q.selectableBegin(), q.selectableEnd())
           {
             ui::Selectable::Ptr s = *solvit;
-            PoolItem theone = s->theObj();
+#if USE_THE_ONE
+            PoolItem theone = s.theObj();
+#else
+            PoolItem theone;
+            
+            if (s->installedEmpty())
+              theone = *s->availableBegin();
+            else
+              theone = findUpdateItem(God->pool(), *s->installedBegin());
+            if (!theone)
+              theone = *s->installedBegin();
+#endif
+
             if (equalNVRA(*s->installedObj().resolvable(), *theone.resolvable()))
             {
               DBG << "the One (" << theone << ") is installed, skipping." << endl;
index 3d2fb22..0537e76 100755 (executable)
@@ -1,3 +1,5 @@
+#include "zypp/PoolItem.h"
+
 #include "Zypper.h"
 
 #include "utils/misc.h"
@@ -34,3 +36,12 @@ void mark_updates(Zypper & zypper,
                   const ResKindSet & kinds,
                   bool skip_interactive,
                   bool best_effort);
+
+/**
+ * Find best (according to edition) uninstalled item
+ * with same kind/name/arch as \a item.
+ * 
+ * Similar to zypp::solver::detail::Helper::findUpdateItem()
+ * but allows changing the vendor and does not allow chaning arch.
+ */
+zypp::PoolItem findUpdateItem(const zypp::ResPool & pool, zypp::PoolItem item);