From 01a54687a704b162ab55a2eeb04a273636be6558 Mon Sep 17 00:00:00 2001 From: Duncan Mac-Vicar P Date: Wed, 6 Jun 2007 11:31:56 +0000 Subject: [PATCH] - move .repo file parsing to its own component, and - disable other.xml in YUM by default, otherwise test fails, because the downloader doesnt download other.xml by default --- zypp/parser/yum/RepoParserOpts.h | 2 +- zypp2/CMakeLists.txt | 9 ++ zypp2/RepoInfo.cc | 17 ++-- zypp2/RepoManager.cc | 182 +++++++++++++++++++++++---------------- zypp2/RepoManager.h | 28 +++++- zypp2/parser/RepoFileReader.cc | 100 +++++++++++++++++++++ zypp2/parser/RepoFileReader.h | 93 ++++++++++++++++++++ zypp2/repo/RepoException.h | 18 ++++ 8 files changed, 363 insertions(+), 86 deletions(-) create mode 100644 zypp2/parser/RepoFileReader.cc create mode 100644 zypp2/parser/RepoFileReader.h diff --git a/zypp/parser/yum/RepoParserOpts.h b/zypp/parser/yum/RepoParserOpts.h index 98c0d6b..aab0263 100644 --- a/zypp/parser/yum/RepoParserOpts.h +++ b/zypp/parser/yum/RepoParserOpts.h @@ -15,7 +15,7 @@ namespace zypp struct RepoParserOpts { /** Skip parsing of other.xml.gz */ - DefaultIntegral skipOther; + DefaultIntegral skipOther; /** Skip parsing of filelists.xml.gz */ DefaultIntegral skipFilelists; diff --git a/zypp2/CMakeLists.txt b/zypp2/CMakeLists.txt index f7f0bd3..89f3819 100644 --- a/zypp2/CMakeLists.txt +++ b/zypp2/CMakeLists.txt @@ -121,6 +121,13 @@ SET( zypp2_parser_susetags_HEADERS parser/susetags/RepoParser.h ) +SET( zypp2_parser_SRCS + parser/RepoFileReader.cc +) + +SET( zypp2_parser_HEADERS + parser/RepoFileReader.h +) #INSTALL( FILES # ${zypp2_repository_sqlite-repository_HEADERS} @@ -135,6 +142,7 @@ ${zypp2_cache_SRCS} ${zypp2_repository_cached_SRCS} ${zypp2_repository_data_SRCS} ${zypp2_cache_sqlite3x_SRCS} +${zypp2_parser_SRCS} ${zypp2_parser_yum_SRCS} ${zypp2_parser_susetags_SRCS} ) @@ -144,6 +152,7 @@ ${zypp2_repository_HEADERS} ${zypp2_HEADERS} ${zypp2_cache_HEADERS} ${zypp2_cache_sqlite3x_HEADERS} +${zypp2_parser_HEADERS} ${zypp2_parser_yum_HEADERS} ${zypp2_parser_susetags_HEADERS} ) diff --git a/zypp2/RepoInfo.cc b/zypp2/RepoInfo.cc index d4ab123..7136f0f 100644 --- a/zypp2/RepoInfo.cc +++ b/zypp2/RepoInfo.cc @@ -34,6 +34,11 @@ namespace zypp autorefresh(indeterminate), type(repo::RepoType::NONE_e) {} + + ~Impl() + { + MIL << std::endl; + } public: boost::tribool enabled; boost::tribool autorefresh; @@ -44,12 +49,6 @@ namespace zypp std::string name; public: - /** Offer default Impl. */ - static shared_ptr nullimpl() - { - static shared_ptr _nullimpl( new Impl ); - return _nullimpl; - } private: friend Impl * rwcowClone( const Impl * rhs ); @@ -77,7 +76,7 @@ namespace zypp // METHOD TYPE : Ctor // RepoInfo::RepoInfo() - : _pimpl( Impl::nullimpl() ) + : _pimpl( new Impl() ) {} /////////////////////////////////////////////////////////////////// @@ -86,7 +85,9 @@ namespace zypp // METHOD TYPE : Dtor // RepoInfo::~RepoInfo() - {} + { + //MIL << std::endl; + } diff --git a/zypp2/RepoManager.cc b/zypp2/RepoManager.cc index cd57497..f797e37 100644 --- a/zypp2/RepoManager.cc +++ b/zypp2/RepoManager.cc @@ -15,9 +15,9 @@ #include #include "zypp/base/InputStream.h" #include "zypp/base/Logger.h" +#include "zypp/base/Function.h" #include "zypp/PathInfo.h" #include "zypp/TmpPath.h" -#include "zypp/parser/IniDict.h" #include "zypp2/repo/RepoException.h" #include "zypp2/RepoManager.h" @@ -26,6 +26,7 @@ #include "zypp2/repo/cached/RepoImpl.h" #include "zypp/MediaSetAccess.h" +#include "zypp2/parser/RepoFileReader.h" #include "zypp/source/yum/YUMDownloader.h" #include "zypp/parser/yum/RepoParser.h" @@ -36,7 +37,6 @@ using namespace std; using namespace zypp; using namespace zypp::repo; using namespace zypp::filesystem; -using parser::IniDict; using zypp::source::yum::YUMDownloader; using zypp::source::susetags::SUSETagsDownloader; @@ -45,6 +45,12 @@ using zypp::source::susetags::SUSETagsDownloader; namespace zypp { ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : RepoManagerOptions + // + /////////////////////////////////////////////////////////////////// + RepoManagerOptions::RepoManagerOptions() { ZConfig globalConfig; @@ -52,48 +58,34 @@ namespace zypp repoRawCachePath = globalConfig.defaultRepoRawCachePath(); knownReposPath = globalConfig.defaultKnownReposPath(); } - + /** - * \short List of RepoInfo's from a file. - * \param file pathname of the file to read. - */ - static std::list repositories_in_file( const Pathname &file ) + * \short Simple callback to collect the results + */ + struct RepoCollector { - InputStream is(file); - IniDict dict(is); - std::list repos; + RepoCollector() + { + MIL << endl; + } - for ( IniDict::section_const_iterator its = dict.sectionsBegin(); - its != dict.sectionsEnd(); - ++its ) + ~RepoCollector() { - MIL << (*its) << endl; - - RepoInfo info; - info.setAlias(*its); - - for ( IniDict::entry_const_iterator it = dict.entriesBegin(*its); - it != dict.entriesEnd(*its); - ++it ) - { - - //MIL << (*it).first << endl; - if (it->first == "name" ) - info.setName(it-> second); - else if ( it->first == "enabled" ) - info.setEnabled( it->second == "1" ); - else if ( it->first == "baseurl" ) - info.addBaseUrl( Url(it->second) ); - else if ( it->first == "type" ) - info.setType(repo::RepoType(it->second)); - } - - // add it to the list. - repos.push_back(info); + MIL << endl; } - return repos; - } + bool collect( const RepoInfo &repo ) + { + //MIL << "here in collector: " << repo.alias() << endl; + repos.push_back(repo); + //MIL << "added: " << repo.alias() << endl; + return true; + } + + RepoInfoList repos; + }; + + //////////////////////////////////////////////////////////////////////////// /** * \short List of RepoInfo's from a directory @@ -105,6 +97,8 @@ namespace zypp */ static std::list repositories_in_path( const Pathname &dir ) { + MIL << " " << dir << endl; + RepoCollector collector; std::list repos; list entries; if ( filesystem::readdir( entries, Pathname(dir), false ) != 0 ) @@ -113,18 +107,50 @@ namespace zypp for ( list::const_iterator it = entries.begin(); it != entries.end(); ++it ) { Pathname file = *it; - std::list repos_here = repositories_in_file(file); - std::copy( repos_here.begin(), repos_here.end(), std::back_inserter(repos)); + parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) ); + + //std::copy( collector.repos.begin(), collector.repos.end(), std::back_inserter(repos)); + //MIL << "ok" << endl; } - return repos; + return collector.repos; } - std::list RepoManager::knownRepositories() + //////////////////////////////////////////////////////////////////////////// + + static void assert_alias( const RepoInfo &info ) { - return repositories_in_path("/etc/zypp/repos.d"); + if (info.alias().empty()) + ZYPP_THROW(RepoNoAliasException()); + } + + //////////////////////////////////////////////////////////////////////////// + + static void assert_urls( const RepoInfo &info ) + { + if (info.urls().empty()) + ZYPP_THROW(RepoNoUrlException()); + } + + //////////////////////////////////////////////////////////////////////////// + + /** + * \short Calculates the raw cache path for a repository + */ + static Pathname rawcache_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info ) + { + assert_alias(info); + return opt.repoRawCachePath + info.alias(); } - /** RepoManager implementation. */ + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : RepoManager::Impl + // + /////////////////////////////////////////////////////////////////// + + /** + * \short RepoManager implementation. + */ struct RepoManager::Impl { Impl( const RepoManagerOptions &opt ) @@ -168,41 +194,26 @@ namespace zypp // /////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : RepoManager::RepoManager - // METHOD TYPE : Ctor - // RepoManager::RepoManager( const RepoManagerOptions &opt ) : _pimpl( new Impl(opt) ) {} - /////////////////////////////////////////////////////////////////// - // - // METHOD NAME : RepoManager::~RepoManager - // METHOD TYPE : Dtor - // + //////////////////////////////////////////////////////////////////////////// + RepoManager::~RepoManager() {} - - static void assert_alias( const RepoInfo &info ) - { - if (info.alias().empty()) - ZYPP_THROW(RepoNoAliasException()); - } - static void assert_urls( const RepoInfo &info ) - { - if (info.urls().empty()) - ZYPP_THROW(RepoNoUrlException()); - } + //////////////////////////////////////////////////////////////////////////// - static Pathname rawcache_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info ) + std::list RepoManager::knownRepositories() const { - assert_alias(info); - return opt.repoRawCachePath + info.alias(); + MIL << endl; + return repositories_in_path("/etc/zypp/repos.d"); + MIL << endl; } - + + //////////////////////////////////////////////////////////////////////////// + void RepoManager::refreshMetadata( const RepoInfo &info ) { assert_alias(info); @@ -260,11 +271,15 @@ namespace zypp } } + //////////////////////////////////////////////////////////////////////////// + void RepoManager::cleanMetadata( const RepoInfo &info ) { filesystem::recursive_rmdir(rawcache_path_for_repoinfo(_pimpl->options, info)); } + //////////////////////////////////////////////////////////////////////////// + void RepoManager::buildCache( const RepoInfo &info ) { assert_alias(info); @@ -319,6 +334,8 @@ namespace zypp store.commit(); } + //////////////////////////////////////////////////////////////////////////// + repo::RepoType RepoManager::probe( const Url &url ) { MediaSetAccess access(url); @@ -330,6 +347,8 @@ namespace zypp return repo::RepoType("UNKNOWN"); } + //////////////////////////////////////////////////////////////////////////// + void RepoManager::cleanCache( const RepoInfo &info ) { cache::CacheStore store(_pimpl->options.repoCachePath); @@ -339,6 +358,14 @@ namespace zypp store.commit(); } + //////////////////////////////////////////////////////////////////////////// + + bool RepoManager::isCached( const RepoInfo &info ) const + { + cache::CacheStore store(_pimpl->options.repoCachePath); + return store.isCached(info.alias()); + } + Repository RepoManager::createFromCache( const RepoInfo &info ) { cache::CacheStore store(_pimpl->options.repoCachePath); @@ -349,17 +376,22 @@ namespace zypp MIL << "Repository " << info.alias() << " is cached" << endl; data::RecordId id = store.lookupRepository(info.alias()); - repo::cached::RepoImpl::Ptr repoimpl = new repo::cached::RepoImpl( info, _pimpl->options.repoCachePath, id ); + repo::cached::RepoImpl::Ptr repoimpl = + new repo::cached::RepoImpl( info, _pimpl->options.repoCachePath, id ); // read the resolvables from cache repoimpl->createResolvables(); return Repository(repoimpl); } - /****************************************************************** - ** - ** FUNCTION NAME : operator<< - ** FUNCTION TYPE : std::ostream & - */ + //////////////////////////////////////////////////////////////////////////// + + void RepoManager::addRepository( const RepoInfo &info ) + { + + } + + //////////////////////////////////////////////////////////////////////////// + std::ostream & operator<<( std::ostream & str, const RepoManager & obj ) { return str << *obj._pimpl; diff --git a/zypp2/RepoManager.h b/zypp2/RepoManager.h index 2497741..3a5eef7 100644 --- a/zypp2/RepoManager.h +++ b/zypp2/RepoManager.h @@ -67,7 +67,7 @@ namespace zypp * Which defaults to ZYpp global settings. * */ - std::list knownRepositories(); + std::list knownRepositories() const; /** * \short Refresh local cache @@ -122,13 +122,19 @@ namespace zypp void cleanCache( const RepoInfo &info ); /** + * \short Wether a repository exists in cache + * + * \param RepoInfo to be checked. + */ + bool isCached( const RepoInfo &info ) const; + + /** * \short Create a repository object from the cache data * * \throw RepoNotCachedException When the source is not cached. */ Repository createFromCache( const RepoInfo &info ); - /** * \short Probe repo metadata type. * @@ -136,6 +142,24 @@ namespace zypp */ repo::RepoType probe( const Url &url ); + + /** + * \short Adds a repository to the list of known repositories. + * + * + * + * \throws RepoAlreadyExistsException If the repo clash some + * unique attribute like alias + */ + void addRepository( const RepoInfo &info ); + + /** + * Adds a .repo file directly, which can contain + * one or more repositories. + */ + //void addRepositories( const Url &url ); + + public: private: diff --git a/zypp2/parser/RepoFileReader.cc b/zypp2/parser/RepoFileReader.cc new file mode 100644 index 0000000..d899d43 --- /dev/null +++ b/zypp2/parser/RepoFileReader.cc @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/repo/RepoFileReader.cc + * +*/ +#include +#include "zypp/base/Logger.h" +#include "zypp/base/InputStream.h" +#include "zypp/base/UserRequestException.h" + +#include "zypp/parser/IniDict.h" +#include "zypp2/parser/RepoFileReader.h" + +using std::endl; +using zypp::parser::IniDict; + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + namespace parser + { ///////////////////////////////////////////////////////////////// + + /** + * \short List of RepoInfo's from a file. + * \param file pathname of the file to read. + */ + static void repositories_in_file( const Pathname &file, + const RepoFileReader::ProcessRepo &callback, + const ProgressData::ReceiverFnc &progress ) + { + InputStream is(file); + parser::IniDict dict(is); + for ( parser::IniDict::section_const_iterator its = dict.sectionsBegin(); + its != dict.sectionsEnd(); + ++its ) + { + MIL << (*its) << endl; + + RepoInfo info; + info.setAlias(*its); + + for ( IniDict::entry_const_iterator it = dict.entriesBegin(*its); + it != dict.entriesEnd(*its); + ++it ) + { + + //MIL << (*it).first << endl; + if (it->first == "name" ) + info.setName(it-> second); + else if ( it->first == "enabled" ) + info.setEnabled( it->second == "1" ); + else if ( it->first == "baseurl" ) + info.addBaseUrl( Url(it->second) ); + else if ( it->first == "type" ) + info.setType(repo::RepoType(it->second)); + } + + // add it to the list. + callback(info); + //if (!progress.tick()) + // ZYPP_THROW(AbortRequestException()); + } + } + + /////////////////////////////////////////////////////////////////// + // + // CLASS NAME : RepoFileReader + // + /////////////////////////////////////////////////////////////////// + + RepoFileReader::RepoFileReader( const Pathname & repo_file, + const ProcessRepo & callback, + const ProgressData::ReceiverFnc &progress ) + : _callback(callback) + { + repositories_in_file(repo_file, _callback, progress); + //MIL << "Done" << endl; + } + + RepoFileReader::~RepoFileReader() + {} + + std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj ) + { + return str; + } + + ///////////////////////////////////////////////////////////////// + } // namespace parser + /////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// diff --git a/zypp2/parser/RepoFileReader.h b/zypp2/parser/RepoFileReader.h new file mode 100644 index 0000000..a3680f7 --- /dev/null +++ b/zypp2/parser/RepoFileReader.h @@ -0,0 +1,93 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp2/repo/RepoFileReader.h + * +*/ +#ifndef ZYPP_REPO_REPOFILEREADER_H +#define ZYPP_REPO_REPOFILEREADER_H + +#include + +#include "zypp/base/PtrTypes.h" +#include "zypp2/RepoInfo.h" +#include "zypp/ProgressData.h" + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + namespace parser + { ///////////////////////////////////////////////////////////////// + + /** + * \short Read repository data from a .repo file + * + * After each repo is read, a \ref RepoInfo is prepared and \ref _callback + * is called with the object passed in. + * + * The \ref _callback is provided on construction. + * + * \code + * RepoFileReader reader(repo_file, + * bind( &SomeClass::callbackfunc, &SomeClassInstance, _1, _2 ) ); + * \endcode + */ + class RepoFileReader + { + friend std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj ); + public: + + /** + * Callback definition. + * First parameter is a \ref RepoInfo object with the resource + * second parameter is the resource type. + * + * Return false from the callback to get a \ref AbortRequestException + * to be thrown and the processing to be cancelled. + */ + typedef function< bool( const RepoInfo & )> ProcessRepo; + + /** Implementation */ + class Impl; + + public: + /** + * \short Constructor. Creates the reader and start reading. + * + * \param repo_file A valid .repo file + * \param callback Callback that will be called for each repository. + * \param progress Optional progress function. \see ProgressData + * + * \throws AbortRequestException If the callback returns false + * \throws Exception If a error occurs at reading / parsing + * + */ + RepoFileReader( const Pathname & repo_file, + const ProcessRepo & callback, + const ProgressData::ReceiverFnc &progress = ProgressData::ReceiverFnc() ); + + /** + * Dtor + */ + ~RepoFileReader(); + private: + ProcessRepo _callback; + }; + /////////////////////////////////////////////////////////////////// + + /** \relates RepoFileReader Stream output */ + std::ostream & operator<<( std::ostream & str, const RepoFileReader & obj ); + + ///////////////////////////////////////////////////////////////// + } // namespace parser + /////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_REPO_REPOFILEREADER_H diff --git a/zypp2/repo/RepoException.h b/zypp2/repo/RepoException.h index 3a3bd74..c188217 100644 --- a/zypp2/repo/RepoException.h +++ b/zypp2/repo/RepoException.h @@ -75,6 +75,24 @@ namespace zypp /** * thrown when it was impossible to + * match a repository + */ + class RepoNotFoundException : public RepoException + { + + }; + + /** + * Repository already exists and some unique + * attribute can't be duplicated. + */ + class RepoAlreadyExistsException : public RepoException + { + + }; + + /** + * thrown when it was impossible to * determine an alias for this repo. */ class RepoUnknownTypeException : public RepoException -- 2.7.4