From 15fe461691de0318ab56166ef6cfb00128ef7948 Mon Sep 17 00:00:00 2001 From: Jan Kupec Date: Sun, 11 May 2008 21:11:04 +0000 Subject: [PATCH] - fixed update -t {patch,patter,product} (bnc #388201) - fixed patch-check --- doc/TODO | 35 ++++++------ src/zypper-misc.cc | 160 ++++++++++++++++++++++++++++++----------------------- src/zypper.cc | 7 ++- 3 files changed, 113 insertions(+), 89 deletions(-) diff --git a/doc/TODO b/doc/TODO index 0a414f5..4612212 100644 --- 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) diff --git a/src/zypper-misc.cc b/src/zypper-misc.cc index 7dc58f6..4662c76 100644 --- a/src/zypper-misc.cc +++ b/src/zypper-misc.cc @@ -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(), - e = God->pool().byKindEnd(); + 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(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 (), - e = pool.byKindEnd (); - - - 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(res); if (patch->restartSuggested()) - pkg_mgr_available = true; - } - } - - - unsigned int patchcount=0; - - it = pool.byKindBegin (); + pkg_mgr_available = true; - for (; it != e; ++it ) - { - ResObject::constPtr res = it->resolvable(); - - patchcount++; - - if ( it->isBroken()) - { - Patch::constPtr patch = asKind(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 << " name () << "\" "; @@ -1653,15 +1653,11 @@ bool xml_list_patches () } if (patchcount == 0) - { cout << "" << 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 (), - e = pool.byKindEnd (); + 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::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::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(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, diff --git a/src/zypper.cc b/src/zypper.cc index 5c7b9f9..6c106f0 100644 --- a/src/zypper.cc +++ b/src/zypper.cc @@ -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; } -- 2.7.4