- move .repo file parsing to its own component, and
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Wed, 6 Jun 2007 11:31:56 +0000 (11:31 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Wed, 6 Jun 2007 11:31:56 +0000 (11:31 +0000)
- disable other.xml in YUM by default, otherwise
  test fails, because the downloader doesnt
  download other.xml by default

zypp/parser/yum/RepoParserOpts.h
zypp2/CMakeLists.txt
zypp2/RepoInfo.cc
zypp2/RepoManager.cc
zypp2/RepoManager.h
zypp2/parser/RepoFileReader.cc [new file with mode: 0644]
zypp2/parser/RepoFileReader.h [new file with mode: 0644]
zypp2/repo/RepoException.h

index 98c0d6b..aab0263 100644 (file)
@@ -15,7 +15,7 @@ namespace zypp
   struct RepoParserOpts
   {
     /** Skip parsing of other.xml.gz */
-    DefaultIntegral<bool,false> skipOther;
+    DefaultIntegral<bool,true> skipOther;
 
     /** Skip parsing of filelists.xml.gz */
     DefaultIntegral<bool,false> skipFilelists;
index f7f0bd3..89f3819 100644 (file)
@@ -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}
 )
index d4ab123..7136f0f 100644 (file)
@@ -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<Impl> nullimpl()
-    {
-      static shared_ptr<Impl> _nullimpl( new Impl );
-      return _nullimpl;
-    }
 
   private:
     friend Impl * rwcowClone<Impl>( 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;
+  }
 
   
   
index cd57497..f797e37 100644 (file)
@@ -15,9 +15,9 @@
 #include <algorithm>
 #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<RepoInfo> repositories_in_file( const Pathname &file )
+    * \short Simple callback to collect the results
+    */
+  struct RepoCollector
   {
-    InputStream is(file);
-    IniDict dict(is);
-    std::list<RepoInfo> 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<RepoInfo> repositories_in_path( const Pathname &dir )
   {
+    MIL << " " << dir << endl;
+    RepoCollector collector;
     std::list<RepoInfo> repos;
     list<Pathname> entries;
     if ( filesystem::readdir( entries, Pathname(dir), false ) != 0 )
@@ -113,18 +107,50 @@ namespace zypp
     for ( list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
     {
       Pathname file = *it;
-      std::list<RepoInfo> 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<RepoInfo> 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<RepoInfo> 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;
index 2497741..3a5eef7 100644 (file)
@@ -67,7 +67,7 @@ namespace zypp
     * Which defaults to ZYpp global settings.
     *
     */
-   std::list<RepoInfo> knownRepositories();
+   std::list<RepoInfo> 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 (file)
index 0000000..d899d43
--- /dev/null
@@ -0,0 +1,100 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp/repo/RepoFileReader.cc
+ *
+*/
+#include <iostream>
+#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 (file)
index 0000000..a3680f7
--- /dev/null
@@ -0,0 +1,93 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file      zypp2/repo/RepoFileReader.h
+ *
+*/
+#ifndef ZYPP_REPO_REPOFILEREADER_H
+#define ZYPP_REPO_REPOFILEREADER_H
+
+#include <iosfwd>
+
+#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
index 3a3bd74..c188217 100644 (file)
@@ -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