commit libzypp for openSUSE:Factory
Hello community, here is the log from the commit of package libzypp for openSUSE:Factory checked in at 2014-06-01 18:56:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libzypp (Old) and /work/SRC/openSUSE:Factory/.libzypp.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "libzypp" Changes: -------- --- /work/SRC/openSUSE:Factory/libzypp/libzypp.changes 2014-05-10 07:48:28.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libzypp.new/libzypp.changes 2014-06-01 18:56:05.000000000 +0200 @@ -1,0 +2,17 @@ +Tue May 27 16:31:21 CEST 2014 - ma@suse.de + +- Let ServiceRefresh en-/disable repos with respect to previous state + and user modifications. +- RepoindexFileReader: support variable substitution +- Parse optional autorefresh attribute from repoindex.xml +- version 14.21.0 (20) + +------------------------------------------------------------------- +Wed May 14 13:52:38 CEST 2014 - ma@suse.de + +- Add DownloadResolvableReport::infoInCache +- Adjust transfer timeout settings (bnc#877405) +- Fix computation of update candidate (bnc#834858) +- version 14.20.0 (20) + +------------------------------------------------------------------- Old: ---- libzypp-14.19.0.tar.bz2 New: ---- libzypp-14.21.0.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libzypp.spec ++++++ --- /var/tmp/diff_new_pack.gNO1b9/_old 2014-06-01 18:56:06.000000000 +0200 +++ /var/tmp/diff_new_pack.gNO1b9/_new 2014-06-01 18:56:06.000000000 +0200 @@ -23,7 +23,7 @@ Summary: Package, Patch, Pattern, and Product Management License: GPL-2.0+ Group: System/Packages -Version: 14.19.0 +Version: 14.21.0 Release: 0 Source: %{name}-%{version}.tar.bz2 Source1: %{name}-rpmlintrc ++++++ libzypp-14.19.0.tar.bz2 -> libzypp-14.21.0.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/VERSION.cmake new/libzypp-14.21.0/VERSION.cmake --- old/libzypp-14.19.0/VERSION.cmake 2014-05-08 18:56:44.000000000 +0200 +++ new/libzypp-14.21.0/VERSION.cmake 2014-05-27 16:33:18.000000000 +0200 @@ -59,10 +59,10 @@ # See './mkChangelog -h' for help. # SET(LIBZYPP_MAJOR "14") -SET(LIBZYPP_COMPATMINOR "19") -SET(LIBZYPP_MINOR "19") +SET(LIBZYPP_COMPATMINOR "20") +SET(LIBZYPP_MINOR "21") SET(LIBZYPP_PATCH "0") # -# LAST RELEASED: 14.19.0 (19) +# LAST RELEASED: 14.21.0 (20) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/package/libzypp.changes new/libzypp-14.21.0/package/libzypp.changes --- old/libzypp-14.19.0/package/libzypp.changes 2014-05-08 18:56:44.000000000 +0200 +++ new/libzypp-14.21.0/package/libzypp.changes 2014-05-27 16:33:18.000000000 +0200 @@ -1,4 +1,21 @@ ------------------------------------------------------------------- +Tue May 27 16:31:21 CEST 2014 - ma@suse.de + +- Let ServiceRefresh en-/disable repos with respect to previous state + and user modifications. +- RepoindexFileReader: support variable substitution +- Parse optional autorefresh attribute from repoindex.xml +- version 14.21.0 (20) + +------------------------------------------------------------------- +Wed May 14 13:52:38 CEST 2014 - ma@suse.de + +- Add DownloadResolvableReport::infoInCache +- Adjust transfer timeout settings (bnc#877405) +- Fix computation of update candidate (bnc#834858) +- version 14.20.0 (20) + +------------------------------------------------------------------- Thu May 8 18:54:25 CEST 2014 - ma@suse.de - KeyRingReport: New infoVerify callback showing the trusted key diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/tests/parser/RepoindexFileReader_test.cc new/libzypp-14.21.0/tests/parser/RepoindexFileReader_test.cc --- old/libzypp-14.19.0/tests/parser/RepoindexFileReader_test.cc 2013-03-20 09:29:30.000000000 +0100 +++ new/libzypp-14.21.0/tests/parser/RepoindexFileReader_test.cc 2014-05-27 16:33:19.000000000 +0200 @@ -10,13 +10,13 @@ using std::string; using namespace zypp; -static string service = "<repoindex>" +static string service = "<repoindex arch=\"i386\" distver=\"11\">" "<repo alias=\"company-foo\" name=\"Company's Foo\"" - " path=\"products/foo\" distro_target=\"sle-11-i386\" priority=\"20\"/>" + " path=\"products/foo\" distro_target=\"sle-%{distver}-%{arch}\" priority=\"20\"/>" "<repo alias=\"company-bar\" name=\"Company's Bar\"" - " path=\"products/bar\" distro_target=\"sle-11-i386\" enabled=\"true\"/>" + " path=\"products/bar\" distro_target=\"sle-%{distver}-%{arch}\" enabled=\"tRUe\" autorefresh=\"FaLsE\"/>" "<repo alias=\"company-foo-upd\" name=\"Company's Foo Updates\"" - " path=\"products/foo/updates\" distro_target=\"sle-11-i386\" priority=\"1\"/>" + " path=\"products/foo/updates\" distro_target=\"sle-%{distver}-%{arch}\" priority=\"1\"/>" "</repoindex>"; struct RepoCollector : private base::NonCopyable @@ -61,6 +61,8 @@ BOOST_CHECK_EQUAL(99, repo.priority()); // "Repository is explicitly enabled" BOOST_CHECK(repo.enabled()); + // "Repository autorefresh is explicitly disabled" + BOOST_CHECK(!repo.autorefresh()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/RepoManager.cc new/libzypp-14.21.0/zypp/RepoManager.cc --- old/libzypp-14.19.0/zypp/RepoManager.cc 2014-04-03 19:24:12.000000000 +0200 +++ new/libzypp-14.21.0/zypp/RepoManager.cc 2014-05-27 16:33:19.000000000 +0200 @@ -1294,7 +1294,7 @@ if ( subdir->basename() == r->escaped_alias() ) { found = true; break; } - if ( ! found ) + if ( ! found && ( Date::now()-PathInfo(*subdir).mtime() > Date::day ) ) filesystem::recursive_rmdir( *subdir ); progress.set( progress.val() + sdircurrent * 100 / sdircount ); @@ -1717,7 +1717,7 @@ void RepoManager::Impl::removeService( const std::string & alias ) { - MIL << "Going to delete repo " << alias << endl; + MIL << "Going to delete service " << alias << endl; const ServiceInfo & service = getService( alias ); @@ -1838,12 +1838,24 @@ uglyHack.second = e; } + //////////////////////////////////////////////////////////////////////////// + // On the fly remember the new repo states as defined the reopoindex.xml. + // Move into ServiceInfo later. + ServiceInfo::RepoStates newRepoStates; + // set service alias and base url for all collected repositories for_( it, collector.repos.begin(), collector.repos.end() ) { + // First of all: Prepend service alias: + it->setAlias( str::form( "%s:%s", service.alias().c_str(), it->alias().c_str() ) ); + // set refrence to the parent service + it->setService( service.alias() ); + + // remember the new parsed repo state + newRepoStates[it->alias()] = *it; + // if the repo url was not set by the repoindex parser, set service's url Url url; - if ( it->baseUrlsEmpty() ) url = service.url(); else @@ -1862,13 +1874,8 @@ it->setPath(""); } - // Prepend service alias: - it->setAlias( str::form( "%s:%s", service.alias().c_str(), it->alias().c_str() ) ); - // save the url it->setBaseUrl( url ); - // set refrence to the parent service - it->setService( service.alias() ); } //////////////////////////////////////////////////////////////////////////// @@ -1877,22 +1884,29 @@ RepoInfoList oldRepos; getRepositoriesInService( service.alias(), std::back_inserter( oldRepos ) ); + //////////////////////////////////////////////////////////////////////////// // find old repositories to remove... - for_( it, oldRepos.begin(), oldRepos.end() ) + for_( oldRepo, oldRepos.begin(), oldRepos.end() ) { - if ( ! foundAliasIn( it->alias(), collector.repos ) ) + if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) ) { - if ( it->enabled() && ! service.repoToDisableFind( it->alias() ) ) - { - DBG << "Service removes enabled repo " << it->alias() << endl; - service.addRepoToEnable( it->alias() ); - serviceModified = true; - } - else - { - DBG << "Service removes disabled repo " << it->alias() << endl; - } - removeRepository( *it ); + if ( oldRepo->enabled() ) + { + // Currently enabled. If this was a user modification remember the state. + const auto & last = service.repoStates().find( oldRepo->alias() ); + if ( last != service.repoStates().end() && ! last->second.enabled ) + { + DBG << "Service removes user enabled repo " << oldRepo->alias() << endl; + service.addRepoToEnable( oldRepo->alias() ); + serviceModified = true; + } + else + DBG << "Service removes enabled repo " << oldRepo->alias() << endl; + } + else + DBG << "Service removes disabled repo " << oldRepo->alias() << endl; + + removeRepository( *oldRepo ); } } @@ -1900,76 +1914,101 @@ // create missing repositories and modify exising ones if needed... for_( it, collector.repos.begin(), collector.repos.end() ) { - // Service explicitly requests the repo being enabled? - // Service explicitly requests the repo being disabled? + // User explicitly requested the repo being enabled? + // User explicitly requested the repo being disabled? // And hopefully not both ;) If so, enable wins. - bool beEnabled = service.repoToEnableFind( it->alias() ); - bool beDisabled = service.repoToDisableFind( it->alias() ); - // Make sure the service repo is created with the - // appropriate enable - if ( beEnabled ) it->setEnabled(true); - if ( beDisabled ) it->setEnabled(false); + TriBool toBeEnabled( indeterminate ); // indeterminate - follow the service request + DBG << "Service request to " << (it->enabled()?"enable":"disable") << " service repo " << it->alias() << endl; - if ( beEnabled ) + if ( service.repoToEnableFind( it->alias() ) ) { + DBG << "User request to enable service repo " << it->alias() << endl; + toBeEnabled = true; // Remove from enable request list. // NOTE: repoToDisable is handled differently. // It gets cleared on each refresh. service.delRepoToEnable( it->alias() ); serviceModified = true; } + else if ( service.repoToDisableFind( it->alias() ) ) + { + DBG << "User request to disable service repo " << it->alias() << endl; + toBeEnabled = false; + } + RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) ); if ( oldRepo == oldRepos.end() ) { // Not found in oldRepos ==> a new repo to add - // At that point check whether a repo with the same alias - // exists outside this service. Maybe forcefully re-alias - // the existing repo? + // Make sure the service repo is created with the appropriate enablement + if ( ! indeterminate(toBeEnabled) ) + it->setEnabled( toBeEnabled ); + DBG << "Service adds repo " << it->alias() << " " << (it->enabled()?"enabled":"disabled") << endl; addRepository( *it ); - - // save repo credentials - // ma@: task for modifyRepository? } else { // ==> an exising repo to check bool oldRepoModified = false; + if ( indeterminate(toBeEnabled) ) + { + // No user request: check for an old user modificaton otherwise follow service request. + // NOTE: Assert toBeEnabled is boolean afterwards! + if ( oldRepo->enabled() == it->enabled() ) + toBeEnabled = it->enabled(); // service requests no change to the system + else + { + const auto & last = service.repoStates().find( oldRepo->alias() ); + if ( last == service.repoStates().end() || last->second.enabled != it->enabled() ) + toBeEnabled = it->enabled(); // service request has changed since last refresh -> follow + else + { + toBeEnabled = oldRepo->enabled(); // service request unchaned since last refresh -> keep user modification + DBG << "User modified service repo " << it->alias() << " may stay " << (toBeEnabled?"enabled":"disabled") << endl; + } + } + } + // changed enable? - if ( beEnabled ) - { - if ( ! oldRepo->enabled() ) - { - DBG << "Service repo " << it->alias() << " gets enabled" << endl; - oldRepo->setEnabled( true ); - oldRepoModified = true; - } - else - { - DBG << "Service repo " << it->alias() << " stays enabled" << endl; - } - } - else if ( beDisabled ) - { - if ( oldRepo->enabled() ) - { - DBG << "Service repo " << it->alias() << " gets disabled" << endl; - oldRepo->setEnabled( false ); - oldRepoModified = true; - } - else - { - DBG << "Service repo " << it->alias() << " stays disabled" << endl; - } - } - else - { - DBG << "Service repo " << it->alias() << " stays " << (oldRepo->enabled()?"enabled":"disabled") << endl; - } + if ( toBeEnabled == oldRepo->enabled() ) + { + DBG << "Service repo " << it->alias() << " stays " << (oldRepo->enabled()?"enabled":"disabled") << endl; + } + else if ( toBeEnabled ) + { + DBG << "Service repo " << it->alias() << " gets enabled" << endl; + oldRepo->setEnabled( true ); + oldRepoModified = true; + } + else + { + DBG << "Service repo " << it->alias() << " gets disabled" << endl; + oldRepo->setEnabled( false ); + oldRepoModified = true; + } + + // all other attributes follow the service request: + + // changed autorefresh + if ( oldRepo->autorefresh() != it->autorefresh() ) + { + DBG << "Service repo " << it->alias() << " gets new AUTOREFRESH " << it->autorefresh() << endl; + oldRepo->setAutorefresh( it->autorefresh() ); + oldRepoModified = true; + } + + // changed priority? + if ( oldRepo->priority() != it->priority() ) + { + DBG << "Service repo " << it->alias() << " gets new PRIORITY " << it->priority() << endl; + oldRepo->setPriority( it->priority() ); + oldRepoModified = true; + } // changed url? // service repo can contain only one URL now, so no need to iterate. @@ -1995,6 +2034,13 @@ serviceModified = true; } + // Remember original service request for next refresh + if ( service.repoStates() != newRepoStates ) + { + service.setRepoStates( std::move(newRepoStates) ); + serviceModified = true; + } + //////////////////////////////////////////////////////////////////////////// // save service if modified: if ( serviceModified ) @@ -2021,7 +2067,7 @@ if ( service.type() == ServiceType::PLUGIN ) { - MIL << "Not modifying plugin service '" << oldAlias << "'" << endl; + WAR << "Not modifying plugin service '" << oldAlias << "'" << endl; return; } @@ -2052,23 +2098,29 @@ _services.insert(service); // changed properties affecting also repositories - if( oldAlias != service.alias() // changed alias - || oldService.enabled() != service.enabled() // changed enabled status - ) + if ( oldAlias != service.alias() // changed alias + || oldService.enabled() != service.enabled() ) // changed enabled status { std::vector<RepoInfo> toModify; getRepositoriesInService(oldAlias, std::back_inserter(toModify)); for_( it, toModify.begin(), toModify.end() ) { - if (oldService.enabled() && !service.enabled()) - it->setEnabled(false); - else if (!oldService.enabled() && service.enabled()) - { - //! \todo do nothing? the repos will be enabled on service refresh - //! \todo how to know the service needs a (auto) refresh???? - } - else + if ( oldService.enabled() != service.enabled() ) + { + if ( service.enabled() ) + { + // reset to last refreshs state + const auto & last = service.repoStates().find( it->alias() ); + if ( last != service.repoStates().end() ) + it->setEnabled( last->second.enabled ); + } + else + it->setEnabled( false ); + } + + if ( oldAlias != service.alias() ) it->setService(service.alias()); + modifyRepository(it->alias(), *it); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/ServiceInfo.cc new/libzypp-14.21.0/zypp/ServiceInfo.cc --- old/libzypp-14.19.0/zypp/ServiceInfo.cc 2014-01-24 11:28:53.000000000 +0100 +++ new/libzypp-14.21.0/zypp/ServiceInfo.cc 2014-05-27 16:33:19.000000000 +0200 @@ -41,6 +41,8 @@ repo::ServiceType type; ReposToEnable reposToEnable; ReposToDisable reposToDisable; + RepoStates repoStates; + public: Impl() @@ -164,6 +166,19 @@ void ServiceInfo::clearReposToDisable() { _pimpl->reposToDisable.clear(); } + const ServiceInfo::RepoStates & ServiceInfo::repoStates() const + { return _pimpl->repoStates; } + + void ServiceInfo::setRepoStates( RepoStates newStates_r ) + { swap( _pimpl->repoStates, newStates_r ); } + + std::ostream & operator<<( std::ostream & str, const ServiceInfo::RepoState & obj ) + { + return str + << "enabled=" << obj.enabled << " " + << "autorefresh=" << obj.autorefresh << " " + << "priority=" << obj.priority; + } std::ostream & ServiceInfo::dumpAsIniOn( std::ostream & str ) const { @@ -171,6 +186,24 @@ << "url = " << url() << endl << "type = " << type() << endl; + if ( ! repoStates().empty() ) + { + unsigned cnt = 0U; + for ( const auto & el : repoStates() ) + { + std::string tag( "repo_" ); + tag += str::numstring( ++cnt ); + const RepoState & state( el.second ); + + str << tag << "=" << el.first << endl + << tag << "_enabled=" << state.enabled << endl + << tag << "_autorefresh=" << state.autorefresh << endl; + if ( state.priority != RepoInfo::defaultPriority() ) + str + << tag << "_priority=" << state.priority << endl; + } + } + if ( ! reposToEnableEmpty() ) str << "repostoenable = " << str::joinEscaped( reposToEnableBegin(), reposToEnableEnd() ) << endl; if ( ! reposToDisableEmpty() ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/ServiceInfo.h new/libzypp-14.21.0/zypp/ServiceInfo.h --- old/libzypp-14.19.0/zypp/ServiceInfo.h 2014-01-24 11:28:53.000000000 +0100 +++ new/libzypp-14.21.0/zypp/ServiceInfo.h 2014-05-27 16:33:19.000000000 +0200 @@ -18,7 +18,7 @@ #include "zypp/Url.h" #include "zypp/repo/ServiceType.h" -#include "zypp/repo/RepoInfoBase.h" +#include "zypp/RepoInfo.h" /////////////////////////////////////////////////////////////////// @@ -137,6 +137,40 @@ void clearReposToDisable(); //@} + /** \name The original repo state as defined by the repoindex.xml upon last refresh. + * + * This state is remembered to detect any user modifications applied to the repos. + * It may not be available for all repos or in plugin services. In this case all + * changes requested by a service refresh are applied unconditionally. + */ + //@{ + struct RepoState + { + bool enabled; + bool autorefresh; + unsigned priority; + + RepoState() + : enabled( false ), autorefresh( true ), priority( RepoInfo::defaultPriority() ) + {} + RepoState( const RepoInfo & repo_r ) + : enabled( repo_r.enabled() ), autorefresh( repo_r.autorefresh() ), priority( repo_r.priority() ) + {} + bool operator==( const RepoState & rhs ) const + { return( enabled==rhs.enabled && autorefresh==rhs.autorefresh && priority==rhs.priority ); } + bool operator!=( const RepoState & rhs ) const + { return ! operator==( rhs ); } + friend std::ostream & operator<<( std::ostream & str, const RepoState & obj ); + }; + typedef std::map<std::string,RepoState> RepoStates; + + /** Access the remembered repository states. */ + const RepoStates & repoStates() const; + + /** Remember a new set of repository states. */ + void setRepoStates( RepoStates newStates_r ); + //@} + public: /** * Writes ServiceInfo to stream in ".service" format diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/ZYppCallbacks.h new/libzypp-14.21.0/zypp/ZYppCallbacks.h --- old/libzypp-14.19.0/zypp/ZYppCallbacks.h 2014-04-10 19:20:45.000000000 +0200 +++ new/libzypp-14.21.0/zypp/ZYppCallbacks.h 2014-05-14 13:57:00.000000000 +0200 @@ -111,6 +111,12 @@ INVALID // the downloaded file is invalid }; + /** Hint that package is available in the local cache (no download needed). + * This will be the only trigger for an already cached package. + */ + virtual void infoInCache( Resolvable::constPtr res_r, const Pathname & localfile_r ) + {} + virtual void start( Resolvable::constPtr /*resolvable_ptr*/ , const Url &/*url*/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/base/String.h new/libzypp-14.21.0/zypp/base/String.h --- old/libzypp-14.19.0/zypp/base/String.h 2014-04-10 19:20:45.000000000 +0200 +++ new/libzypp-14.21.0/zypp/base/String.h 2014-05-09 11:04:45.000000000 +0200 @@ -410,6 +410,28 @@ */ std::string & replaceAllFun( std::string & str_r, const std::string & from_r, function<std::string()> to_r ); + /** Enhance readability: insert gaps at regular distance + * \code + * // no gaps + * Key Fingerprint: 22C07BA534178CD02EFE22AAB88B2FD43DBDC284 + * // gapify 8 + * Key Fingerprint: 22C07BA5 34178CD0 2EFE22AA B88B2FD4 3DBDC284 + * // gapify 4 + * Key Fingerprint: 22C0 7BA5 3417 8CD0 2EFE 22AA B88B 2FD4 3DBD C284 + * // gapify 4, '-' + * Key Fingerprint: 22C0-7BA5-3417-8CD0-2EFE-22AA-B88B-2FD4-3DBD-C284 + * \endcode + */ + inline std::string gapify( std::string inp_r, std::string::size_type gap_r = 1, char gapchar = ' ' ) + { + if ( gap_r && inp_r.size() > gap_r ) + { + inp_r.reserve( inp_r.size() + (inp_r.size()-1)/gap_r ); + for ( std::string::size_type pos = gap_r; pos < inp_r.size(); pos += gap_r+1 ) + inp_r.insert( pos, 1, gapchar ); + } + return inp_r; + } /////////////////////////////////////////////////////////////////// /** \name Split. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/media/MediaCurl.cc new/libzypp-14.21.0/zypp/media/MediaCurl.cc --- old/libzypp-14.19.0/zypp/media/MediaCurl.cc 2014-01-13 12:04:52.000000000 +0100 +++ new/libzypp-14.21.0/zypp/media/MediaCurl.cc 2014-05-14 13:57:00.000000000 +0200 @@ -598,6 +598,13 @@ * Connect timeout */ SET_OPTION(CURLOPT_CONNECTTIMEOUT, _settings.connectTimeout()); + // If a transfer timeout is set, also set CURLOPT_TIMEOUT to an upper limit + // just in case curl does not trigger its progress callback frequently + // enough. + if ( _settings.timeout() ) + { + SET_OPTION(CURLOPT_TIMEOUT, 3600L); + } // follow any Location: header that the server sends as part of // an HTTP header (#113275) @@ -715,7 +722,7 @@ { SET_OPTION(CURLOPT_LOW_SPEED_LIMIT, _settings.minDownloadSpeed()); // default to 10 seconds at low speed - SET_OPTION(CURLOPT_LOW_SPEED_TIME, 10L); + SET_OPTION(CURLOPT_LOW_SPEED_TIME, 60L); } #if CURLVERSION_AT_LEAST(7,15,5) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/parser/RepoindexFileReader.cc new/libzypp-14.21.0/zypp/parser/RepoindexFileReader.cc --- old/libzypp-14.19.0/zypp/parser/RepoindexFileReader.cc 2013-03-20 09:29:30.000000000 +0100 +++ new/libzypp-14.21.0/zypp/parser/RepoindexFileReader.cc 2014-05-27 16:33:19.000000000 +0200 @@ -10,6 +10,7 @@ * Implementation of repoindex.xml file reader. */ #include <iostream> +#include <unordered_map> #include "zypp/base/String.h" #include "zypp/base/Logger.h" @@ -29,14 +30,68 @@ #undef ZYPP_BASE_LOGGER_LOGGROUP #define ZYPP_BASE_LOGGER_LOGGROUP "parser" -using namespace std; -using namespace zypp::xml; +using std::endl; namespace zypp { namespace parser { + using xml::Reader; + using xml::XmlString; + /////////////////////////////////////////////////////////////////// + namespace + { + class VarReplacer : private base::NonCopyable + { + public: + /** */ + void setVar( const std::string & key_r, const std::string & val_r ) + { + MIL << "*** Inject " << key_r << " = " << val_r; + _vars[key_r] = replace( val_r ); + MIL << " (" << _vars[key_r] << ")" << endl; + } + + std::string replace( const std::string & val_r ) const + { + std::string::size_type vbeg = val_r.find( "%{", 0 ); + if ( vbeg == std::string::npos ) + return val_r; + + str::Str ret; + std::string::size_type cbeg = 0; + for( ; vbeg != std::string::npos; vbeg = val_r.find( "%{", vbeg ) ) + { + std::string::size_type nbeg = vbeg+2; + std::string::size_type nend = val_r.find( "}", nbeg ); + if ( nend == std::string::npos ) + { + WAR << "Incomplete variable in '" << val_r << "'" << endl; + break; + } + const auto & iter = _vars.find( val_r.substr( nbeg, nend-nbeg ) ); + if ( iter != _vars.end() ) + { + if ( cbeg < vbeg ) + ret << val_r.substr( cbeg, vbeg-cbeg ); + ret << iter->second; + cbeg = nend+1; + } + else + WAR << "Undefined variable %{" << val_r.substr( nbeg, nend-nbeg ) << "} in '" << val_r << "'" << endl; + vbeg = nend+1; + } + if ( cbeg < val_r.size() ) + ret << val_r.substr( cbeg ); + + return ret; + } + private: + std::unordered_map<std::string,std::string> _vars; + }; + } // namespace + /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // @@ -57,11 +112,23 @@ */ bool consumeNode( Reader & reader_r ); + private: + bool getAttrValue( const std::string & key_r, Reader & reader_r, std::string & value_r ) + { + const XmlString & s( reader_r->getAttribute( key_r ) ); + if ( s.get() ) + { + value_r = _replacer.replace( s.asString() ); + return !value_r.empty(); + } + value_r.clear(); + return false; + } private: /** Function for processing collected data. Passed-in through constructor. */ ProcessResource _callback; - string _target_distro; + VarReplacer _replacer; }; /////////////////////////////////////////////////////////////////////// @@ -94,76 +161,78 @@ // xpath: /repoindex if ( reader_r->name() == "repoindex" ) { + while ( reader_r.nextNodeAttribute() ) + _replacer.setVar( reader_r->localName().asString(), reader_r->value().asString() ); return true; } // xpath: /repoindex/data (+) if ( reader_r->name() == "repo" ) { - XmlString s; - RepoInfo info; - - // enabled or disabled is controlled by the - // reposToEnable/Disable list, unless the - // enabled attribute is set - info.setEnabled(false); - // Set some defaults that are not contained in the repo information info.setAutorefresh( true ); + info.setEnabled(false); - // url and/or path - string url_s; - s = reader_r->getAttribute("url"); - if (s.get()) - url_s = s.asString(); - string path_s; - s = reader_r->getAttribute("path"); - if (s.get()) - path_s = s.asString(); - - if (url_s.empty() && path_s.empty()) - throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path")); - //! \todo FIXME this hardcodes the "/repo/" fragment - should not be if we want it to be usable by others! - else if (url_s.empty()) - info.setPath(Pathname(string("/repo/") + path_s)); - else if (path_s.empty()) - info.setBaseUrl(Url(url_s)); - else - info.setBaseUrl(Url(url_s + "/repo/" + path_s)); - - // required alias - s = reader_r->getAttribute("alias"); - if (!s.get()) - throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias")); - info.setAlias(s.asString()); - - // optional type - s = reader_r->getAttribute("type"); - if (s.get()) - info.setType(repo::RepoType(s.asString())); + std::string attrValue; + + // required alias + // mandatory, so we can allow it in var replacement without reset + if ( getAttrValue( "alias", reader_r, attrValue ) ) + { + info.setAlias( attrValue ); + _replacer.setVar( "alias", attrValue ); + } + else + throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias")); + + // required url + // SLES HACK: or path, but beware of the hardcoded '/repo' prefix! + { + std::string urlstr; + std::string pathstr; + getAttrValue( "url", reader_r, urlstr ); + getAttrValue( "path", reader_r, pathstr ); + if ( urlstr.empty() ) + { + if ( pathstr.empty() ) + throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path")); + else + info.setPath( Pathname("/repo") / pathstr ); + } + else + { + if ( pathstr.empty() ) + info.setBaseUrl( Url(urlstr) ); + else + { + Url url( urlstr ); + url.setPathName( Pathname(url.getPathName()) / "repo" / pathstr ); + info.setBaseUrl( url ); + } + } + } // optional name - s = reader_r->getAttribute("name"); - if (s.get()) - info.setName(s.asString()); + if ( getAttrValue( "name", reader_r, attrValue ) ) + info.setName( attrValue ); // optional targetDistro - s = reader_r->getAttribute("distro_target"); - if (s.get()) - info.setTargetDistribution(s.asString()); + if ( getAttrValue( "distro_target", reader_r, attrValue ) ) + info.setTargetDistribution( attrValue ); // optional priority - s = reader_r->getAttribute("priority"); - if (s.get()) { - info.setPriority(str::strtonum<unsigned>(s.asString())); - } + if ( getAttrValue( "priority", reader_r, attrValue ) ) + info.setPriority( str::strtonum<unsigned>( attrValue ) ); + // optional enabled - s = reader_r->getAttribute("enabled"); - if (s.get()) { - info.setEnabled(str::strToTrue(s.asString())); - } + if ( getAttrValue( "enabled", reader_r, attrValue ) ) + info.setEnabled( str::strToBool( attrValue, info.enabled() ) ); + + // optional autorefresh + if ( getAttrValue( "autorefresh", reader_r, attrValue ) ) + info.setAutorefresh( str::strToBool( attrValue, info.autorefresh() ) ); DBG << info << endl; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/parser/ServiceFileReader.cc new/libzypp-14.21.0/zypp/parser/ServiceFileReader.cc --- old/libzypp-14.19.0/zypp/parser/ServiceFileReader.cc 2013-03-20 09:29:30.000000000 +0100 +++ new/libzypp-14.21.0/zypp/parser/ServiceFileReader.cc 2014-05-27 16:33:19.000000000 +0200 @@ -12,6 +12,7 @@ #include <iostream> #include "zypp/base/Logger.h" #include "zypp/base/String.h" +#include "zypp/base/Regex.h" #include "zypp/base/InputStream.h" #include "zypp/base/UserRequestException.h" @@ -54,6 +55,7 @@ MIL << (*its) << endl; ServiceInfo service(*its); + std::map<std::string,std::pair<std::string,ServiceInfo::RepoState>> repoStates; // <repo_NUM,< alias,RepoState >> for ( IniDict::entry_const_iterator it = dict.entriesBegin(*its); it != dict.entriesEnd(*its); @@ -88,10 +90,52 @@ service.addRepoToDisable( *ait ); } } + else if ( str::startsWith( it->first, "repo_" ) ) + { + static str::regex rxexpr( "([0-9]+)(_(.*))?" ); + str::smatch what; + if ( str::regex_match( it->first.c_str()+5/*repo_*/, what, rxexpr ) ) + { + std::string tag( what[1] ); + if ( what.size() > 3 ) + { + // attribute + if ( what[3] == "enabled" ) + repoStates[tag].second.enabled = str::strToBool( it->second, repoStates[tag].second.enabled ); + else if ( what[3] == "autorefresh" ) + repoStates[tag].second.autorefresh = str::strToBool( it->second, repoStates[tag].second.autorefresh ); + else if ( what[3] == "priority" ) + str::strtonum( it->second, repoStates[tag].second.priority ); + else + ERR << "Unknown attribute " << it->first << " ignored" << endl; + } + else + { + // alias + repoStates[tag].first = it->second; + } + } + else + ERR << "Unknown attribute " << it->first << " ignored" << endl; + } else ERR << "Unknown attribute " << it->first << " ignored" << endl; } + if ( ! repoStates.empty() ) + { + ServiceInfo::RepoStates data; + for ( const auto & el : repoStates ) + { + if ( el.second.first.empty() ) + ERR << "Missing alias for repo_" << el.first << "; ignore entry" << endl; + else + data[el.second.first] = el.second.second; + } + if ( ! data.empty() ) + service.setRepoStates( std::move(data) ); + } + MIL << "Linking ServiceInfo with file " << file << endl; service.setFilepath(file); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/parser/xml/Node.h new/libzypp-14.21.0/zypp/parser/xml/Node.h --- old/libzypp-14.19.0/zypp/parser/xml/Node.h 2013-05-02 11:11:26.000000000 +0200 +++ new/libzypp-14.21.0/zypp/parser/xml/Node.h 2014-05-27 16:33:19.000000000 +0200 @@ -71,6 +71,9 @@ XmlString getAttribute( const char * name_r ) const { return XmlString( xmlTextReaderGetAttribute( _reader, reinterpret_cast<const xmlChar *>(name_r) ), XmlString::FREE ); } + /** \overload */ + XmlString getAttribute( const std::string & name_r ) const + { return getAttribute( name_r.c_str() ); } /** Provides a copy of the attribute value with the specified * index relative to the containing element. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/repo/PackageProvider.cc new/libzypp-14.21.0/zypp/repo/PackageProvider.cc --- old/libzypp-14.19.0/zypp/repo/PackageProvider.cc 2014-01-24 08:44:53.000000000 +0100 +++ new/libzypp-14.21.0/zypp/repo/PackageProvider.cc 2014-05-14 13:57:00.000000000 +0200 @@ -208,25 +208,25 @@ ManagedFile PackageProvider::Impl::providePackage() const { + ScopedGuard guardReport( newReport() ); + // check for cache hit: ManagedFile ret( providePackageFromCache() ); if ( ! ret->empty() ) { MIL << "provided Package from cache " << _package << " at " << ret << endl; + report()->infoInCache( _package, ret ); return ret; // <-- cache hit } // HERE: cache misss, do download: - Url url; RepoInfo info = _package->repoInfo(); // FIXME we only support the first url for now. if ( info.baseUrlsEmpty() ) ZYPP_THROW(Exception("No url in repository.")); - else - url = * info.baseUrlsBegin(); MIL << "provide Package " << _package << endl; - ScopedGuard guardReport( newReport() ); + Url url = * info.baseUrlsBegin(); do { _retry = false; report()->start( _package, url ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/solver/detail/Testcase.cc new/libzypp-14.21.0/zypp/solver/detail/Testcase.cc --- old/libzypp-14.19.0/zypp/solver/detail/Testcase.cc 2014-02-13 10:36:18.000000000 +0100 +++ new/libzypp-14.21.0/zypp/solver/detail/Testcase.cc 2014-05-21 16:24:51.000000000 +0200 @@ -120,6 +120,10 @@ str << "<dep name='packageand(" << IdString(detail.lhs().id()) << ":" << IdString(detail.rhs().id()) << ")' />" << endl; + } else if (detail.capRel() == CapDetail::CAP_NAMESPACE + && detail.lhs().id() == NAMESPACE_OTHERPROVIDERS) { + str << "<dep name='otherproviders(" + << IdString(detail.rhs().id()) << ")' />" << endl; } else { // modalias ? IdString packageName; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/target/CommitPackageCache.cc new/libzypp-14.21.0/zypp/target/CommitPackageCache.cc --- old/libzypp-14.19.0/zypp/target/CommitPackageCache.cc 2014-04-15 17:04:45.000000000 +0200 +++ new/libzypp-14.21.0/zypp/target/CommitPackageCache.cc 2014-05-27 16:33:19.000000000 +0200 @@ -127,13 +127,17 @@ {} void CommitPackageCache::setCommitList( std::vector<sat::Solvable> commitList_r ) - { - _pimpl->setCommitList( commitList_r ); - } + { _pimpl->setCommitList( commitList_r ); } ManagedFile CommitPackageCache::get( const PoolItem & citem_r ) { return _pimpl->get( citem_r ); } + bool CommitPackageCache::preloaded() const + { return _pimpl->preloaded(); } + + void CommitPackageCache::preloaded( bool newval_r ) + { _pimpl->preloaded( newval_r ); } + /****************************************************************** ** ** FUNCTION NAME : operator<< diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/target/CommitPackageCache.h new/libzypp-14.21.0/zypp/target/CommitPackageCache.h --- old/libzypp-14.19.0/zypp/target/CommitPackageCache.h 2014-04-15 17:04:45.000000000 +0200 +++ new/libzypp-14.21.0/zypp/target/CommitPackageCache.h 2014-05-27 16:33:19.000000000 +0200 @@ -84,6 +84,14 @@ ManagedFile get( sat::Solvable citem_r ) { return get( PoolItem(citem_r) ); } + /** Whether preloaded hint is set. + * If preloaded the cache tries to avoid trigering the infoInCache CB, + * based on the assumption this was already done when preloading the cache. + */ + bool preloaded() const; + /** Set preloaded hint. */ + void preloaded( bool newval_r ); + public: /** Implementation. */ class Impl; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/target/CommitPackageCacheImpl.h new/libzypp-14.21.0/zypp/target/CommitPackageCacheImpl.h --- old/libzypp-14.19.0/zypp/target/CommitPackageCacheImpl.h 2014-01-24 08:44:53.000000000 +0100 +++ new/libzypp-14.21.0/zypp/target/CommitPackageCacheImpl.h 2014-05-27 16:33:19.000000000 +0200 @@ -64,6 +64,12 @@ const std::vector<sat::Solvable> & commitList() const { return _commitList; } + bool preloaded() const + { return _preloaded; } + + void preloaded( bool newval_r ) + { _preloaded = newval_r; } + protected: /** Let the Source provide the package. */ virtual ManagedFile sourceProvidePackage( const PoolItem & pi ) const @@ -96,6 +102,7 @@ private: std::vector<sat::Solvable> _commitList; PackageProvider _packageProvider; + DefaultIntegral<bool,false> _preloaded; }; /////////////////////////////////////////////////////////////////// diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/target/CommitPackageCacheReadAhead.cc new/libzypp-14.21.0/zypp/target/CommitPackageCacheReadAhead.cc --- old/libzypp-14.19.0/zypp/target/CommitPackageCacheReadAhead.cc 2014-01-24 08:44:53.000000000 +0100 +++ new/libzypp-14.21.0/zypp/target/CommitPackageCacheReadAhead.cc 2014-05-27 16:33:19.000000000 +0200 @@ -140,27 +140,39 @@ // ManagedFile CommitPackageCacheReadAhead::get( const PoolItem & citem_r ) { - // Non CD/DVD media provide their packages without cache. - if ( ! onInteractiveMedia( citem_r ) ) + ManagedFile ret; + if ( preloaded() ) { - return sourceProvidePackage( citem_r ); + // Check whether it's cached. + ManagedFile ret( sourceProvideCachedPackage( citem_r ) ); + if ( ! ret->empty() ) + return ret; } + // else: we head for sourceProvidePackage(), even if the package + // was cached. The actual difference is that sourceProvidePackage + // will trigger the infoInCache CB that informs the application. + // Once the cache is preloaded we try to avoid this CB. - // Check whether it's cached. - ManagedFile ret( sourceProvideCachedPackage( citem_r ) ); - if ( ! ret->empty() ) - return ret; - IMediaKey current( citem_r ); - if ( current != _lastInteractive ) + // Preload cache if a CD/DVD change is pending to avoid + // switching back and forth... + if ( onInteractiveMedia( citem_r ) ) { - if ( _lastInteractive != IMediaKey() ) + ret = sourceProvideCachedPackage( citem_r ); + if ( ! ret->empty() ) + return ret; + + IMediaKey current( citem_r ); + if ( current != _lastInteractive ) { - cacheLastInteractive( citem_r ); - } + if ( _lastInteractive != IMediaKey() ) + { + cacheLastInteractive( citem_r ); + } - DBG << "Interactive change [" << ++_dbgChanges << "] from " << _lastInteractive << " to " << current << endl; - _lastInteractive = current; + DBG << "Interactive change [" << ++_dbgChanges << "] from " << _lastInteractive << " to " << current << endl; + _lastInteractive = current; + } } // Provide and return the file from media. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/target/TargetImpl.cc new/libzypp-14.21.0/zypp/target/TargetImpl.cc --- old/libzypp-14.19.0/zypp/target/TargetImpl.cc 2014-04-28 15:36:46.000000000 +0200 +++ new/libzypp-14.21.0/zypp/target/TargetImpl.cc 2014-05-27 16:33:19.000000000 +0200 @@ -1449,6 +1449,7 @@ } } } + packageCache.preloaded( true ); // try to avoid duplicate infoInCache CBs in commit } if ( miss ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-14.19.0/zypp/ui/SelectableImpl.h new/libzypp-14.21.0/zypp/ui/SelectableImpl.h --- old/libzypp-14.19.0/zypp/ui/SelectableImpl.h 2013-07-11 10:50:17.000000000 +0200 +++ new/libzypp-14.21.0/zypp/ui/SelectableImpl.h 2014-05-14 13:57:00.000000000 +0200 @@ -153,10 +153,6 @@ // Here: installed and defaultCand are non NULL and it's not a // multiversion install. - // update candidate must come from the highest priority repo - if ( defaultCand->repoInfo().priority() != (*availableBegin())->repoInfo().priority() ) - return PoolItem(); - PoolItem installed( installedObj() ); // check vendor change if ( ! ( ResPool::instance().resolver().allowVendorChange() -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de