- fixed update -t {patch,patter,product} (bnc #388201)
authorJan Kupec <jkupec@suse.cz>
Sun, 11 May 2008 21:11:04 +0000 (21:11 +0000)
committerJan Kupec <jkupec@suse.cz>
Sun, 11 May 2008 21:11:04 +0000 (21:11 +0000)
- fixed patch-check

doc/TODO
src/zypper-misc.cc
src/zypper.cc

index 0a414f5..4612212 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,12 +1,19 @@
-0.10.x
-- improve command line arguments handling (be more user-friendly,
-  do the obvious stuff automatically, e.g. use -C automatically after typing
-  zypper in subversion=1.5.0)
-- xml output for all (or most of the) commands
-- xml input (feed a xml with operation specification to zypper)
+1.0.x
+- bugfixing
+
+before 1.0.0
 - implement all rug commands (where it makes sense)
-- system consistency verification command
-- drop xu command (as soon as 'zypper -x lu -t patch -t package is ready')
+- zypper [help] rug
+- add help texts for prompts
+- code reorganization
+  - remove zypper- prefix from sources
+  - split misc.cc into common/commit(solver dialog, summary, commit)/update/install-srcinstall-remove code
+  - clean up/split utils.cc
+- drop xu command
+- show recommended and suggested in the summary
+
+0.11.x
+- bugfixing
 
 
 NOT SCHEDULED
@@ -14,14 +21,14 @@ NOT SCHEDULED
 
 General
 
+- xml input (feed a xml with operation specification to zypper)
 - detect whether the terminal we are writing to supports used control sequences
   and fall back to OutNoTerminal (make it a child of OutNormal) if not. Usefull
   also in cases where the output is redirected to a file or pipe.
+  DONE in OutNormal, TODO via OutNoTerminal?
 - enumerate prompt answers for all prompts
-- provide ? for help on prompts (except for Yes/No)
 ? script progress: does the output contain newline?
 - installation and deletion notifications
-- confirm license: more user friendly (see confirm_licenses() comment)
 - testsuite
 ? move -vv output to zypper.log, leave only normal and verbose output levels?
 
@@ -30,18 +37,12 @@ Patches
 - respect license-to-confirm (test on kernel patch)
  (svn up ncurses)
 ? reboot-needed: ?
-? cron updater:
-- wrapper script for restart-packager
-- zypper patch-search (for rug compatibility)
+- cron updater: wrapper script for restart-packager
 
 Packages
 
-- install
-       --force-install option
 - just download, not install. compare to YOU: do not delete after installing
 
-
-
 Cool Stuff
 
 (document it, brag around)
index 7dc58f6..4662c76 100644 (file)
@@ -1549,6 +1549,24 @@ static void make_solver_test_case(Zypper & zypper)
   }
 }
 
+// ----------------------------------------------------------------------------
+//
+// Updates
+//
+// The following scenarios are handled distinctly:
+// * -t patch (default), no arguments
+// * -t package, no arguments
+//   - uses Resolver::doUpdate()
+// * -t {other}, no arguments
+// * -t patch foo
+// * -t package foo
+//   - addRequires(>installed-version) if available
+// * -t {other} foo
+//   - addRequires(>installed-version) if available
+//
+// update summary must correspond to list-updates and patch-check
+// ----------------------------------------------------------------------------
+
 void patch_check ()
 {
   Out & out = Zypper::instance()->out();
@@ -1557,14 +1575,14 @@ void patch_check ()
   gData.patches_count = gData.security_patches_count = 0;
 
   ResPool::byKind_iterator
-    it = God->pool().byKindBegin<Patch>(),
-    e = God->pool().byKindEnd<Patch>();
+    it = God->pool().byKindBegin(ResKind::patch),
+    e = God->pool().byKindEnd(ResKind::patch);
   for (; it != e; ++it )
   {
     ResObject::constPtr res = it->resolvable();
     Patch::constPtr patch = asKind<Patch>(res);
 
-    if ( it->isBroken() )
+    if (it->isRelevant() && !it->isSatisfied())
     {
       gData.patches_count++;
       if (patch->category() == "security")
@@ -1577,7 +1595,7 @@ void patch_check ()
   s << format(_PL("%d patch needed", "%d patches needed", gData.patches_count))
       % gData.patches_count
     << " ("
-    // translators: %d is the number of needed patches
+    // translators: %d is the number of security patches
     << format(_PL("%d security patch", "%d security patches", gData.security_patches_count))
       % gData.security_patches_count
     << ")";
@@ -1586,47 +1604,29 @@ void patch_check ()
 
 // ----------------------------------------------------------------------------
 
+// returns true if restartSuggested() patches are availble
 bool xml_list_patches ()
 {
-  // returns true if restartSuggested() patches are availble
+  const zypp::ResPool& pool = God->pool();
 
+  unsigned int patchcount=0;
   bool pkg_mgr_available = false;
 
-
-  const zypp::ResPool& pool = God->pool();
   ResPool::byKind_iterator
-    it = pool.byKindBegin<Patch> (),
-    e  = pool.byKindEnd<Patch> ();
-
-
-  for (; it != e; ++it )
+    it = pool.byKindBegin(ResKind::patch),
+    e  = pool.byKindEnd(ResKind::patch);
+  for (; it != e; ++it, ++patchcount)
   {
-    ResObject::constPtr res = it->resolvable();
-    if ( it->isRelevant() )
+    if (it->isRelevant() && !it->isSatisfied())
     {
+      ResObject::constPtr res = it->resolvable();
       Patch::constPtr patch = asKind<Patch>(res);
 
       if (patch->restartSuggested())
-       pkg_mgr_available = true;
-    }
-  }
-
-
-  unsigned int patchcount=0;
-
-  it = pool.byKindBegin<Patch> ();
+        pkg_mgr_available = true;
 
-  for (; it != e; ++it )
-  {
-    ResObject::constPtr res = it->resolvable();
-
-    patchcount++;
-
-    if ( it->isBroken())
-    {
-      Patch::constPtr patch = asKind<Patch>(res);
-      if ((pkg_mgr_available && patch->restartSuggested())  ||
-       !pkg_mgr_available )
+      // if updates stack patches are available, show only those
+      if ((pkg_mgr_available && patch->restartSuggested()) || pkg_mgr_available)
       {
         cout << " <update ";
         cout << "name=\"" << res->name () << "\" ";
@@ -1653,15 +1653,11 @@ bool xml_list_patches ()
   }
 
   if (patchcount == 0)
-  {
     cout << "<appletinfo status=\"no-update-repositories\"/>" << endl;
-  }
 
   return pkg_mgr_available;
-
 }
 
-
 // ----------------------------------------------------------------------------
 
 static void list_patch_updates(Zypper & zypper)
@@ -1679,8 +1675,8 @@ static void list_patch_updates(Zypper & zypper)
 
   const zypp::ResPool& pool = God->pool();
   ResPool::byKind_iterator
-    it = pool.byKindBegin<Patch> (),
-    e  = pool.byKindEnd<Patch> ();
+    it = pool.byKindBegin(ResKind::patch),
+    e  = pool.byKindEnd(ResKind::patch);
   for (; it != e; ++it )
   {
     ResObject::constPtr res = it->resolvable();
@@ -1787,7 +1783,7 @@ find_updates( const ResKind & kind, Candidates & candidates )
   ResPool::byKind_iterator
     it = pool.byKindBegin (kind),
     e  = pool.byKindEnd (kind);
-  DBG << "Finding update candidates of kind " << kind << endl;
+  DBG << "Looking for update candidates of kind " << kind << endl;
   for (; it != e; ++it)
   {
     if (it->status().isUninstalled())
@@ -1803,6 +1799,8 @@ find_updates( const ResKind & kind, Candidates & candidates )
   }
 }
 
+// ----------------------------------------------------------------------------
+
 /**
  * Find all available updates of given kinds.
  */
@@ -1816,6 +1814,8 @@ find_updates( const ResKindSet & kinds, Candidates & candidates )
     WAR << "called with empty kinds set" << endl;
 }
 
+// ----------------------------------------------------------------------------
+
 string i18n_kind_updates(const ResKind & kind)
 {
   if (kind == ResTraits<Package>::kind)
@@ -1844,7 +1844,9 @@ void list_updates(Zypper & zypper, const ResKindSet & kinds, bool best_effort)
   unsigned kind_size = kinds.size();
   ResKindSet localkinds = kinds;
   ResKindSet::iterator it;
-  it = localkinds.find(ResTraits<Patch>::kind);
+
+  // patch updates
+  it = localkinds.find(ResKind::patch);
   if(it != localkinds.end())
   {
     if (zypper.out().type() == Out::TYPE_XML)
@@ -1858,6 +1860,8 @@ void list_updates(Zypper & zypper, const ResKindSet & kinds, bool best_effort)
     localkinds.erase(it);
   }
 
+  // other kinds
+  //! \todo list package updates according to Resolver::doUpdate()
   if (zypper.out().type() == Out::TYPE_XML)
   {
     if (not_affects_pkgmgr)
@@ -1936,8 +1940,9 @@ void list_updates(Zypper & zypper, const ResKindSet & kinds, bool best_effort)
   }
 }
 
+// ----------------------------------------------------------------------------
+
 // may be useful as a functor
-/*
 static bool
 mark_item_install (const PoolItem & pi)
 {
@@ -1946,16 +1951,16 @@ mark_item_install (const PoolItem & pi)
     ERR << "Marking " << pi << "for installation failed" << endl;
   return result;
 }
-*/
+
 // ----------------------------------------------------------------------------
 // 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.
-/*
+
 static PoolItem
 findInstalledItem( PoolItem item )
 {
@@ -1970,14 +1975,15 @@ findInstalledItem( PoolItem item )
   _XDEBUG("findInstalledItem(" << item << ") => " << info.best);
   return info.best;
 }
-*/
+
+// ----------------------------------------------------------------------------
 
 // require update of installed item
 //   The PoolItem passed to require_item_update() is the installed resolvable
 //   to which an update candidate is guaranteed to exist.
 //
 // may be useful as a functor
-/*
+
 static bool require_item_update (const PoolItem& pi) {
   Resolver_Ptr resolver = zypp::getZYpp()->resolver();
 
@@ -1996,7 +2002,7 @@ static bool require_item_update (const PoolItem& pi) {
 
   return true;
 }
-*/
+
 // ----------------------------------------------------------------------------
 
 void xml_list_updates(const ResKindSet & kinds)
@@ -2027,13 +2033,16 @@ void xml_list_updates(const ResKindSet & kinds)
   }
 }
 
-/*
+// ----------------------------------------------------------------------------
+
 static bool
 mark_patch_update(const PoolItem & pi, bool skip_interactive, bool ignore_affects_pm)
 {
   Patch::constPtr patch = asKind<Patch>(pi.resolvable());
-  if (pi.isRelevant() && ! pi.isSatisfied())
+  if (pi.isRelevant() && !pi.isSatisfied())
   {
+    DBG << "patch " << patch->name() << " " << ignore_affects_pm << ", "
+      << patch->restartSuggested() << endl;
     if (ignore_affects_pm || patch->restartSuggested())
     {
       // #221476
@@ -2057,9 +2066,9 @@ mark_patch_update(const PoolItem & pi, bool skip_interactive, bool ignore_affect
 
   return false;
 }
-*/
+
 // ----------------------------------------------------------------------------
-/*
+
 static void
 mark_patch_updates( Zypper & zypper, bool skip_interactive )
 {
@@ -2072,10 +2081,13 @@ mark_patch_updates( Zypper & zypper, bool skip_interactive )
   {
     if (zypper.arguments().empty() || zypper.globalOpts().is_rug_compatible)
     {
+      DBG << "marking all needed patches" << endl;
+
       for_(it, God->pool().byKindBegin(ResKind::patch), 
                God->pool().byKindEnd  (ResKind::patch))
       {
-        any_marked = mark_patch_update(*it, skip_interactive, ignore_affects_pm);
+        if (mark_patch_update(*it, skip_interactive, ignore_affects_pm))
+          any_marked = true;
       }
     }
     else if (!zypper.arguments().empty())
@@ -2113,7 +2125,7 @@ mark_patch_updates( Zypper & zypper, bool skip_interactive )
     }
   }
 }
-*/
+
 // ----------------------------------------------------------------------------
 
 void mark_updates(Zypper & zypper, const ResKindSet & kinds, bool skip_interactive, bool best_effort )
@@ -2122,21 +2134,29 @@ void mark_updates(Zypper & zypper, const ResKindSet & kinds, bool skip_interacti
 
   if (zypper.arguments().empty() || zypper.globalOpts().is_rug_compatible)
   {
-    // this will do a complete pppp update as far as possible
-    God->resolver()->doUpdate();
-    // no need to call Resolver::resolvePool() afterwards
-    zypper.runtimeData().solve_before_commit = false;
-
-    //! \todo update specified types only. Or should we drop this option? 
-
-    /*
-    Candidates candidates;
-    find_updates (localkinds, candidates);
-    if (best_effort)
-      invokeOnEach (candidates.begin(), candidates.end(), require_item_update);
-    else
-      invokeOnEach (candidates.begin(), candidates.end(), mark_item_install);
-    */
+    for_(kindit, localkinds.begin(), localkinds.end())
+    {
+      if (*kindit == ResKind::package)
+      {
+        // this will do a complete pacakge update as far as possible
+        God->resolver()->doUpdate();
+        // no need to call Resolver::resolvePool() afterwards
+        zypper.runtimeData().solve_before_commit = false;
+      }
+      else if (*kindit == ResKind::patch)
+      {
+        mark_patch_updates(zypper, skip_interactive);
+      }
+      else
+      {
+        Candidates candidates;
+        find_updates (localkinds, candidates);
+        if (best_effort)
+          invokeOnEach (candidates.begin(), candidates.end(), require_item_update);
+        else
+          invokeOnEach (candidates.begin(), candidates.end(), mark_item_install);
+      } 
+    }
   }
   // treat arguments as package names (+allow wildcards)
   else if (!zypper.arguments().empty())
@@ -2188,6 +2208,8 @@ void mark_updates(Zypper & zypper, const ResKindSet & kinds, bool skip_interacti
 }
 
 // ----------------------------------------------------------------------------
+// commit
+// ----------------------------------------------------------------------------
 
 /**
  * @return ZYPPER_EXIT_OK - successful commit,
index 5c7b9f9..6c106f0 100644 (file)
@@ -2687,7 +2687,6 @@ void Zypper::doCommand()
     }
 
     init_target(*this);
-
     init_repos(*this);
     if (exitCode() != ZYPPER_EXIT_OK)
       return;
@@ -2698,8 +2697,10 @@ void Zypper::doCommand()
 
     // now load resolvables:
     load_resolvables(*this);
+    // needed to compute status of PPP
+    resolve(*this);
 
-    patch_check ();
+    patch_check();
 
     if (gData.security_patches_count > 0)
     {
@@ -3169,7 +3170,7 @@ void Zypper::doCommand()
 
     Locks::instance().save();
 
-    out().info(str::form("removed locks: %lu",start-Locks::instance().size()));
+    out().info(str::form("removed locks: %lu", start - Locks::instance().size()));
     
     break;
   }