- repo deletion, test does not passes, still fixing
authorDuncan Mac-Vicar P <dmacvicar@suse.de>
Tue, 19 Jun 2007 13:23:33 +0000 (13:23 +0000)
committerDuncan Mac-Vicar P <dmacvicar@suse.de>
Tue, 19 Jun 2007 13:23:33 +0000 (13:23 +0000)
tests/zypp/RepoManager_test.cc
tests/zypp/data/RepoManager/proprietary.repo [new file with mode: 0644]
tests/zypp/data/RepoManager/repos.d/proprietary.repo [new file with mode: 0644]
zypp/RepoManager.cc
zypp/RepoManager.h
zypp/repo/RepoException.h

index dcf5c52..a47f3d4 100644 (file)
@@ -34,16 +34,51 @@ void repomanager_test( const string &dir )
   
   TmpDir tmpCachePath;
   TmpDir tmpRawCachePath;
+  TmpDir tmpKnownReposPath;
+  
+  BOOST_CHECK_EQUAL( filesystem::copy_dir_content( Pathname(dir) + "/repos.d", tmpKnownReposPath.path() ), 0 );
   
   opts.repoCachePath = tmpCachePath.path();
   opts.repoRawCachePath = tmpRawCachePath.path();
-  opts.knownReposPath = Pathname(dir) + "/repos.d";
+  opts.knownReposPath = tmpKnownReposPath.path();
   
   RepoManager manager(opts);
   
   list<RepoInfo> repos = manager.knownRepositories();
+  BOOST_CHECK_EQUAL(repos.size(), (unsigned) 4);
+  
+  // now add a .repo file with 2 repositories in it
+  Url url;
+  url.setPathName((Pathname(dir) + "/proprietary.repo").asString());
+  url.setScheme("file");
+
+  manager.addRepositories(url);
+  
+  // check it was not overwriten the proprietary.repo file
+  BOOST_CHECK( PathInfo(Pathname(dir) + "/repos.d/proprietary_1.repo").isExist() );
+  
+  // now there should be 6 repos
+  repos = manager.knownRepositories();
+  BOOST_CHECK_EQUAL(repos.size(), (unsigned) 6);
+  
+  // delete the office repo inside the propietary_1.repo
+  RepoInfo office;
+  office.setAlias("office");
+  manager.removeRepository(office);
+  // now there should be 5 repos
+  repos = manager.knownRepositories();
+  BOOST_CHECK_EQUAL(repos.size(), (unsigned) 5);
+  // the file still contained one repo, so it should still exists
+  BOOST_CHECK( PathInfo(Pathname(dir) + "/repos.d/proprietary_1.repo").isExist() );
   
-  BOOST_CHECK_EQUAL(repos.size(), (unsigned) 3);
+  // now delete the macromedia one
+  RepoInfo macromedia;
+  macromedia.setAlias("macromedia");
+  manager.removeRepository(macromedia);
+  repos = manager.knownRepositories();
+  BOOST_CHECK_EQUAL(repos.size(), (unsigned) 4);
+  // the file should not exist anymore
+  BOOST_CHECK( ! PathInfo(Pathname(dir) + "/repos.d/proprietary_1.repo").isExist() );
   
   RepoInfo repo(repos.front());
   manager.refreshMetadata(repo);
diff --git a/tests/zypp/data/RepoManager/proprietary.repo b/tests/zypp/data/RepoManager/proprietary.repo
new file mode 100644 (file)
index 0000000..0392ffe
--- /dev/null
@@ -0,0 +1,14 @@
+[macromedia]
+name=Macromedia for i386 Linux
+baseurl=http://macromedia.rediris.es/rpm/
+enabled=1
+gpgcheck=1
+gpgkey=http://macromedia.mplug.org/FEDORA-GPG-KEY
+
+[office]
+name=Microsoft Office for Linux
+baseurl=http://www.microsoft.com/linux/office
+enabled=1
+gpgcheck=1
+gpgkey=http://www.microsoft.com/~sballmer/gpgkey.txt
+
diff --git a/tests/zypp/data/RepoManager/repos.d/proprietary.repo b/tests/zypp/data/RepoManager/repos.d/proprietary.repo
new file mode 100644 (file)
index 0000000..e78c242
--- /dev/null
@@ -0,0 +1,5 @@
+
+[adobe]
+name=acrobat reader
+baseurl=http://www.adobe.com/reader/linux
+
index e30dfb7..51be082 100644 (file)
@@ -248,7 +248,7 @@ namespace zypp
   std::list<RepoInfo> RepoManager::knownRepositories() const
   {
     MIL << endl;
-    return repositories_in_dir("/etc/zypp/repos.d");
+    return repositories_in_dir(_pimpl->options.knownReposPath);
     MIL << endl;
   }
 
@@ -300,95 +300,105 @@ namespace zypp
     // try urls one by one
     for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); it != info.baseUrlsEnd(); ++it )
     {
-      Url url(*it);
-      filesystem::TmpDir tmpdir;
-      
-      repo::RepoType repokind = info.type();
-      
-      // if the type is unknown, try probing.
-      switch ( repokind.toEnum() )
-      {
-        case RepoType::NONE_e:
-          // unknown, probe it
-          repokind = probe(*it);
-        break;
-        default:
-        break;
-      }
-      
-      Pathname rawpath = rawcache_path_for_repoinfo( _pimpl->options, info );
-      oldstatus = rawMetadataStatus(info);
-      
-      switch ( repokind.toEnum() )
+      try
       {
-        case RepoType::RPMMD_e :
+        Url url(*it);
+        filesystem::TmpDir tmpdir;
+        
+        repo::RepoType repokind = info.type();
+        
+        // if the type is unknown, try probing.
+        switch ( repokind.toEnum() )
         {
-          yum::Downloader downloader( url, "/" );
-          
-          RepoStatus newstatus = downloader.status();
-          bool refresh = false;
-          if ( oldstatus.checksum() == newstatus.checksum() )
+          case RepoType::NONE_e:
+            // unknown, probe it
+            repokind = probe(*it);
+          break;
+          default:
+          break;
+        }
+        
+        Pathname rawpath = rawcache_path_for_repoinfo( _pimpl->options, info );
+        oldstatus = rawMetadataStatus(info);
+        
+        switch ( repokind.toEnum() )
+        {
+          case RepoType::RPMMD_e :
           {
-            MIL << "repo has not changed" << endl;
-            if ( policy == RefreshForced )
+            yum::Downloader downloader( url, "/" );
+            
+            RepoStatus newstatus = downloader.status();
+            bool refresh = false;
+            if ( oldstatus.checksum() == newstatus.checksum() )
+            {
+              MIL << "repo has not changed" << endl;
+              if ( policy == RefreshForced )
+              {
+                MIL << "refresh set to forced" << endl;
+                refresh = true;
+              }
+            }
+            else
             {
-              MIL << "refresh set to forced" << endl;
               refresh = true;
             }
+  
+            if ( refresh )
+              downloader.download(tmpdir.path());
+            else
+              return;
+            // no error
           }
-          else
-          {
-            refresh = true;
-          }
-
-          if ( refresh )
-            downloader.download(tmpdir.path());
-          else
-            return;
-           // no error
-        }
-        break;
-        case RepoType::YAST2_e :
-        {
-          susetags::Downloader downloader( url, "/" );
-          
-          RepoStatus newstatus = downloader.status();
-          bool refresh = false;
-          if ( oldstatus.checksum() == newstatus.checksum() )
+          break;
+          case RepoType::YAST2_e :
           {
-            MIL << "repo has not changed" << endl;
-            if ( policy == RefreshForced )
+            susetags::Downloader downloader( url, "/" );
+            
+            RepoStatus newstatus = downloader.status();
+            bool refresh = false;
+            if ( oldstatus.checksum() == newstatus.checksum() )
+            {
+              MIL << "repo has not changed" << endl;
+              if ( policy == RefreshForced )
+              {
+                MIL << "refresh set to forced" << endl;
+                refresh = true;
+              }
+            }
+            else
             {
-              MIL << "refresh set to forced" << endl;
               refresh = true;
             }
+  
+            if ( refresh )
+              downloader.download(tmpdir.path());
+            else
+              return;
+            // no error
           }
-          else
-          {
-            refresh = true;
-          }
-          if ( refresh )
-            downloader.download(tmpdir.path());
-          else
-            return;
-          // no error
+          break;
+          default:
+            ZYPP_THROW(RepoUnknownTypeException());
         }
-        break;
-        default:
-          ZYPP_THROW(RepoUnknownTypeException());
+        
+        // ok we have the metadata, now exchange
+        // the contents
+        TmpDir oldmetadata;
+        filesystem::assert_dir(rawpath);
+        filesystem::rename( rawpath, oldmetadata.path() );
+        // move the just downloaded there
+        filesystem::rename( tmpdir.path(), rawpath );
+        // we are done.
+        return;
       }
-      
-      // ok we have the metadata, now exchange
-      // the contents
-      TmpDir oldmetadata;
-      filesystem::assert_dir(rawpath);
-      filesystem::rename( rawpath, oldmetadata.path() );
-      // move the just downloaded there
-      filesystem::rename( tmpdir.path(), rawpath );
-      
-      // we are done.
-    }
+      catch ( const Exception &e )
+      {
+        ZYPP_CAUGHT(e);
+        ERR << "Trying another url..." << endl;
+      }
+    } // for every url
+    ERR << "No more urls..." << endl;
+    ZYPP_THROW(RepoException("Cant refresh metadata"));
   }
   
   ////////////////////////////////////////////////////////////////////////////
@@ -601,11 +611,14 @@ namespace zypp
     {
       // look if the alias is in the known repos.
       for ( std::list<RepoInfo>::const_iterator kit = knownrepos.begin();
-          kit != repos.end();
+          kit != knownrepos.end();
           ++kit )
       {
         if ( (*it).alias() == (*kit).alias() )
+        {
+          ERR << "To be added repo " << (*it).alias() << " conflicts with existing repo " << (*kit).alias() << endl;
           ZYPP_THROW(RepoAlreadyExistsException((*it).alias()));
+        }
       }
     }
     
@@ -635,6 +648,68 @@ namespace zypp
   
   ////////////////////////////////////////////////////////////////////////////
   
+  void RepoManager::removeRepository( const RepoInfo & info,
+                                      const ProgressData::ReceiverFnc & progressrcv)
+  {
+    std::list<RepoInfo> repos = knownRepositories();
+    for ( std::list<RepoInfo>::const_iterator it = repos.begin();
+          it != repos.end();
+          ++it )
+    {
+      // they can be the same only if the provided is empty, that means
+      // the provided repo has no alias
+      // then skip
+      if ( (!info.alias().empty()) && ( info.alias() != (*it).alias() ) )
+        continue;
+      
+      // TODO match by url
+       
+      // we have a matcing repository, now we need to know
+      // where it does come from.
+      if (info.filepath().empty())
+      {
+        ZYPP_THROW(RepoException("Can't figure where the repo is stored"));
+      }
+      else
+      {
+        // figure how many repos are there in the file:
+        std::list<RepoInfo> filerepos = repositories_in_file(info.filepath());
+        if ( (filerepos.size() == 1) && ( filerepos.front().alias() == info.alias() ) )
+        {
+          // easy, only this one, just delete the file
+          if ( filesystem::unlink(info.filepath()) != 0 )
+          {
+            ZYPP_THROW(RepoException("Can't delete " + info.filepath().asString()));
+          }
+          return;
+        }
+        else
+        {
+          // there are more repos in the same file
+          // write them back except the deleted one.
+          TmpFile tmp;
+          std::ofstream file(tmp.path().c_str());
+          if (!file) {
+            ZYPP_THROW (Exception( "Can't open " + tmp.path().asString() ) );
+          }
+          for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
+                fit != filerepos.end();
+                ++fit )
+          {
+            if ( (*fit).alias() != info.alias() )
+              (*fit).dumpRepoOn(file);
+          }
+          return;
+        }
+      } // else filepath is empty
+      
+    }
+    // should not be reached on a sucess workflow
+    ZYPP_THROW(RepoNotFoundException(info));
+  }
+  
+  ////////////////////////////////////////////////////////////////////////////
+  
   std::ostream & operator<<( std::ostream & str, const RepoManager & obj )
   {
     return str << *obj._pimpl;
index 54f5f94..2c767f7 100644 (file)
@@ -86,8 +86,9 @@ namespace zypp
       BuildForced
     };
     
-    enum RepoAddPolicy
+    enum RepoRemovePolicy
     {
+      
     };
     
    /**
@@ -209,9 +210,11 @@ namespace zypp
     void addRepositories( const Url &url,
                          const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
     /**
-     * PROPOSAL
+     * \short Remove the best matching repository from known repos list
+     *
+     * \throws RepoNotFoundException If no repo match
      */
-    void removeRepository( const std::string & alias,
+    void removeRepository( const RepoInfo & info,
                            const ProgressData::ReceiverFnc & progressrcv = ProgressData::ReceiverFnc() );
     
   protected:
index dd50859..119e565 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "zypp/base/Exception.h"
 #include "zypp/base/UserRequestException.h"
-
+#include "zypp/RepoInfo.h"
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
@@ -76,7 +76,17 @@ namespace zypp
      */
     class RepoNotFoundException : public RepoException
     {
-      RepoNotFoundException(){}
+    public:
+      RepoNotFoundException( const RepoInfo &info)
+        : _info(info)
+      {}
+      ~RepoNotFoundException() throw()
+      {}
+      
+      RepoInfo info()
+      { return _info; }
+    private:
+      RepoInfo _info;
     };
     
     /**