Imported Upstream version 15.15.0 75/94675/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 02:05:23 +0000 (11:05 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 02:05:24 +0000 (11:05 +0900)
Change-Id: I9c91cfb96282d1887e321aa3e36140cb70b31441
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
VERSION.cmake
package/libzypp.changes
tests/zypp/Selectable_test.cc
zypp/ProblemSolution.h
zypp/ResPoolProxy.h
zypp/repo/RepoVariables.cc
zypp/target/TargetImpl.h
zypp/ui/SelectableImpl.cc

index e7c2335..d2bebca 100644 (file)
@@ -60,9 +60,9 @@
 #
 SET(LIBZYPP_MAJOR "15")
 SET(LIBZYPP_COMPATMINOR "14")
-SET(LIBZYPP_MINOR "14")
+SET(LIBZYPP_MINOR "15")
 SET(LIBZYPP_PATCH "0")
 #
-# LAST RELEASED: 15.14.0 (14)
+# LAST RELEASED: 15.15.0 (14)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index 7d6c08d..550da71 100644 (file)
@@ -1,4 +1,13 @@
 -------------------------------------------------------------------
+Fri Sep  4 13:49:33 CEST 2015 - ma@suse.de
+
+- Don't cache repo releasever (bnc#943563)
+- Selectable: allow setPickStatus for non-multiversion packages
+  (bnc#943870)
+- ResPoolProxy: add ScopedSaveState
+- version 15.15.0 (14)
+
+-------------------------------------------------------------------
 Tue Sep  1 18:19:27 CEST 2015 - ma@suse.de
 
 - zypp.conf: add solver.dupAllow{Downgrade,NameChange,ArchChange,
index abd03a8..3f4e350 100644 (file)
@@ -296,11 +296,11 @@ void testStatusTable( ui::Selectable::Ptr sel )
   } while ( comb.next() );
 }
 
-BOOST_AUTO_TEST_CASE(status_change)
+BOOST_AUTO_TEST_CASE(status_verify)
 {
   // this verifies the Selectables computes ui::Status
   ResPoolProxy poolProxy( test.poolProxy() );
-  poolProxy.saveState();
+  ResPoolProxy::ScopedSaveState saveState( poolProxy );
   {
     ui::Selectable::Ptr sel( poolProxy.lookup( ResKind::package, "installed_only" ) );
     BOOST_REQUIRE( !sel->installedEmpty() );
@@ -329,3 +329,20 @@ BOOST_AUTO_TEST_CASE(status_change)
 
 /////////////////////////////////////////////////////////////////////////////
 
+BOOST_AUTO_TEST_CASE(pickstatus_cycle)
+{
+  return;
+  // TODO: automate it
+  ResPoolProxy poolProxy( test.poolProxy() );
+  ResPoolProxy::ScopedSaveState saveState( poolProxy );
+  ui::Selectable::Ptr sel( poolProxy.lookup( ResKind::package, "installed_and_available" ) );
+
+  USR << dump(sel) << endl;
+  for ( const PoolItem & pi : sel->picklist() )
+  {
+    (sel->pickInstall( pi, ResStatus::USER ) ? WAR : ERR) << (pi.multiversionInstall() ? "M " : "  " ) << pi << endl;
+    USR << dump(sel) << endl;
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////
index 0622f22..56ee1ce 100644 (file)
@@ -20,7 +20,7 @@ namespace zypp
 {
   /////////////////////////////////////////////////////////////////////////
   /// \class ProblemSolution
-  /// \brief Class representing one possible solution to one problem found during resolving
+  /// \brief Class representing one possible solution to a problem found during resolving
   ///
   /// All problems should have at least 2-3 (mutually exclusive) solutions:
   ///
@@ -70,12 +70,12 @@ namespace zypp
     const SolutionActionList & actions() const;
 
     /**
-     * Set description of the problem.
+     * Set description of the solution.
      **/
     void setDescription( std::string description );
 
     /**
-     * Set detail description of the problem.
+     * Set detail description of the solution.
      **/
     void setDetails( std::string details );
 
index 6234bc5..57a5793 100644 (file)
@@ -147,12 +147,14 @@ namespace zypp
 
   public:
     /** \name Save and restore state per kind of resolvable.
-     * Simple version, no savety net. So don't restore or diff,
+     * Simple version, no safety net. So don't restore or diff,
      * if you didn't save before.
      *
      * Diff returns true, if current stat differs from the saved
      * state.
-    */
+     *
+     * Use \ref scopedSaveState for exception safe scoped save/restore
+     */
     //@{
     void saveState() const;
 
@@ -177,6 +179,24 @@ namespace zypp
     template<class _Res>
       bool diffState() const
       { return diffState( ResTraits<_Res>::kind ); }
+
+    /**
+     * \class ScopedSaveState
+     * \brief Exception safe scoped save/restore state.
+     * Call \ref acceptState to prevent the class from restoring
+     * the remembered state.
+     * \ingroup g_RAII
+     */
+    struct ScopedSaveState;
+
+    ScopedSaveState scopedSaveState() const;
+
+    ScopedSaveState scopedSaveState( const ResKind & kind_r ) const;
+
+    template<class _Res>
+      ScopedSaveState && scopedSaveState() const
+      { return scopedSaveState( ResTraits<_Res>::kind ); }
+
     //@}
 
   private:
@@ -226,6 +246,52 @@ namespace zypp
   /** \relates ResPoolProxy Verbose stream output */
   std::ostream & dumpOn( std::ostream & str, const ResPoolProxy & obj );
 
+  ///////////////////////////////////////////////////////////////////
+
+  struct ResPoolProxy::ScopedSaveState
+  {
+    NON_COPYABLE_BUT_MOVE( ScopedSaveState );
+
+    ScopedSaveState( const ResPoolProxy & pool_r )
+    : _pimpl( new Impl( pool_r ) )
+    { _pimpl->saveState(); }
+
+    ScopedSaveState( const ResPoolProxy & pool_r, const ResKind & kind_r )
+    : _pimpl( new Impl( pool_r, kind_r ) )
+    { _pimpl->saveState(); }
+
+    ~ScopedSaveState()
+    { if ( _pimpl ) _pimpl->restoreState(); }
+
+    void acceptState()
+    { _pimpl.reset(); }
+
+  private:
+    struct Impl
+    {
+      Impl( const ResPoolProxy & pool_r )
+      : _pool( pool_r )
+      {}
+      Impl( const ResPoolProxy & pool_r, const ResKind & kind_r )
+      : _pool( pool_r ), _kind( new ResKind( kind_r ) )
+      {}
+      void saveState()
+      { if ( _kind ) _pool.saveState( *_kind ); else _pool.saveState(); }
+      void restoreState()
+      { if ( _kind ) _pool.restoreState( *_kind ); else _pool.restoreState(); }
+      ResPoolProxy _pool;
+      scoped_ptr<ResKind> _kind;
+
+    };
+    std::unique_ptr<Impl> _pimpl;
+  };
+
+  inline ResPoolProxy::ScopedSaveState ResPoolProxy::scopedSaveState() const
+  { return ScopedSaveState( *this ); }
+
+  inline ResPoolProxy::ScopedSaveState ResPoolProxy::scopedSaveState( const ResKind & kind_r ) const
+  { return ScopedSaveState( *this, kind_r ); }
+
   /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
index d53e534..93c0f20 100644 (file)
@@ -21,6 +21,7 @@ using std::endl;
 #include "zypp/base/String.h"
 #include "zypp/base/Regex.h"
 
+#include "zypp/ZYppFactory.h"
 #include "zypp/ZConfig.h"
 #include "zypp/Target.h"
 #include "zypp/Arch.h"
@@ -389,6 +390,23 @@ namespace zypp
     ///////////////////////////////////////////////////////////////////
     namespace
     {
+      inline std::string getReleaseverString()
+      {
+       std::string ret( env::ZYPP_REPO_RELEASEVER() );
+       if( ret.empty() )
+       {
+         Target_Ptr trg( getZYpp()->getTarget() );
+         if ( trg )
+           ret = trg->distributionVersion();
+         else
+           ret = Target::distributionVersion( Pathname()/*guess*/ );
+       }
+       else
+         WAR << "ENV overwrites $releasever=" << ret << endl;
+
+       return ret;
+      }
+
       /** \brief Provide lazy initialized repo variables
        */
       struct RepoVars : private zypp::base::NonCopyable
@@ -438,14 +456,11 @@ namespace zypp
 
        void assertReleaseverStr() const
        {
-         if ( _releasever.empty() )
+         // check for changing releasever (bnc#943563)
+         std::string check( getReleaseverString() );
+         if ( check != _releasever )
          {
-           _releasever = env::ZYPP_REPO_RELEASEVER();
-           if( _releasever.empty() )
-             _releasever = Target::distributionVersion( Pathname()/*guess*/ );
-           else
-             WAR << "ENV overwrites $releasever=" << _releasever << endl;
-
+           _releasever = std::move(check);
            // split major/minor for SLE
            std::string::size_type pos = _releasever.find( "." );
            if ( pos == std::string::npos )
index 0b6c015..b105a3e 100644 (file)
@@ -180,7 +180,7 @@ namespace zypp
       /** \overload */
       static std::string targetDistributionFlavor( const Pathname & root_r );
 
-      /** \copydoc Target::distributionVersion()*/
+      /** \copydoc Target::distributionLabel()*/
       Target::DistributionLabel distributionLabel() const;
       /** \overload */
       static Target::DistributionLabel distributionLabel( const Pathname & root_r );
index 1009743..6e1ae88 100644 (file)
@@ -102,6 +102,28 @@ namespace zypp
           return true;
         }
 
+        /** highlevel remove transact from non-multiversion packages. */
+        bool unsetNonMultiTransact(  const PoolItem & pi_r, Causer causer_r )
+       {
+         ResStatus & status( backup( pi_r ) );
+         if ( status.transacts() && ! pi_r.multiversionInstall() )
+         {
+           if ( ! status.setTransact( false, causer_r ) ) return false;
+         }
+         return true;
+       }
+
+        /** highlevel remove transact from multiversion packages. */
+        bool unsetMultiTransact(  const PoolItem & pi_r, Causer causer_r )
+       {
+         ResStatus & status( backup( pi_r ) );
+         if ( status.transacts() && pi_r.multiversionInstall() )
+         {
+           if ( ! status.setTransact( false, causer_r ) ) return false;
+         }
+         return true;
+       }
+
         /** Highlevel action. */
         typedef bool (StatusBackup::*Action)( const PoolItem &, Causer );
 
@@ -430,12 +452,6 @@ namespace zypp
       if ( pi_r.ident() != ident() )
         return false;  // not my PoolItem
 
-      if ( ! pi_r.multiversionInstall() )
-        return false;  // We're not yet ready for this.
-      // TODO: Without multiversionInstall take care at most ONE available is set
-      // to install. Upon install ALL installed get deleted. Only upon deletetion
-      // one might pick individual versions (but more than one would be an error here).
-
       StatusBackup backup;
       std::vector<PoolItem> i;
       std::vector<PoolItem> a;
@@ -482,29 +498,57 @@ namespace zypp
           }
           break;
 
-        case S_Install:
-          if ( i.empty() && ! a.empty() )
-          {
-            // maybe unlock candidate only?
-            if ( ! backup.forEach( a.begin(), a.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
-            const PoolItem & cand( pi_r.status().isInstalled() ? *a.begin() : pi_r ); // status already backed up above
-            if ( ! cand.status().setTransact( true, causer_r ) ) return backup.restore();
-            return true;
-          }
-          break;
-
-        case S_Update:
-          if ( ! i.empty() && ! a.empty() )
-          {
-            if ( ! backup.forEach( i.begin(), i.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
-            if ( ! backup.forEach( i.begin(), i.end(), &StatusBackup::setTransactTrue, ResStatus::SOLVER ) ) return backup.restore();
-            // maybe unlock candidate only?
-            if ( ! backup.forEach( a.begin(), a.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
-            const PoolItem & cand( pi_r.status().isInstalled() ? *a.begin() : pi_r ); // status already backed up above
-            if ( ! cand.status().setTransact( true, causer_r ) ) return backup.restore();
-            return true;
-          }
-          break;
+       case S_Install:
+         if ( i.empty() && ! a.empty() )
+         {
+           const PoolItem & cand( pi_r.status().isInstalled() ? *a.begin() : pi_r );
+           if ( cand.multiversionInstall() )
+           {
+             if ( ! backup.forEach( availableBegin(), availableEnd(), &StatusBackup::unsetNonMultiTransact, causer_r ) ) return backup.restore();
+             // maybe unlock candidate only?
+             if ( ! backup.forEach( a.begin(), a.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
+             if ( ! cand.status().setTransact( true, causer_r ) ) return backup.restore();
+             return true;
+           }
+           else
+           {
+             // For non-multiversion use ordinary setStatus
+             // NOTE that S_Update/S_Install here depends on !installedEmpty()
+             // and not on picklists identicalInstalled.
+             if ( ! backup.forEach( availableBegin(), availableEnd(), &StatusBackup::unsetMultiTransact, causer_r ) ) return backup.restore();
+             if ( ! setCandidate( cand, causer_r ) )  return backup.restore();
+             if ( ! setStatus( installedEmpty() ? S_Install : S_Update, causer_r ) )  return backup.restore();
+             return true;
+           }
+         }
+         break;
+
+       case S_Update:
+         if ( ! i.empty() && ! a.empty() )
+         {
+           const PoolItem & cand( pi_r.status().isInstalled() ? *a.begin() : pi_r );
+           if ( cand.multiversionInstall() )
+           {
+             if ( ! backup.forEach( i.begin(), i.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
+             if ( ! backup.forEach( i.begin(), i.end(), &StatusBackup::setTransactTrue, ResStatus::SOLVER ) ) return backup.restore();
+             if ( ! backup.forEach( availableBegin(), availableEnd(), &StatusBackup::unsetNonMultiTransact, causer_r ) ) return backup.restore();
+             // maybe unlock candidate only?
+             if ( ! backup.forEach( a.begin(), a.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
+             if ( ! cand.status().setTransact( true, causer_r ) ) return backup.restore();
+             return true;
+           }
+           else
+           {
+             // For non-multiversion use ordinary setStatus
+             // NOTE that S_Update/S_Install here depends on !installedEmpty()
+             // and not on picklists identicalInstalled.
+             if ( ! backup.forEach( availableBegin(), availableEnd(), &StatusBackup::unsetMultiTransact, causer_r ) ) return backup.restore();
+             if ( ! setCandidate( cand, causer_r ) )  return backup.restore();
+             if ( ! setStatus( installedEmpty() ? S_Install : S_Update, causer_r ) )  return backup.restore();
+             return true;
+           }
+         }
+         break;
 
         case S_KeepInstalled:
           if ( ! i.empty()  )