Imported Upstream version 17.23.0 upstream/17.23.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 27 Nov 2020 06:47:48 +0000 (15:47 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 27 Nov 2020 06:47:48 +0000 (15:47 +0900)
30 files changed:
CMakeLists.txt
VERSION.cmake
libzypp.spec.cmake
package/libzypp.changes
po/es.po
po/fr.po
po/it.po
po/zh_CN.po
po/zh_TW.po
tests/CMakeLists.txt
tests/parser/HistoryLogReader_test.dat
tests/repo/CMakeLists.txt
tests/zypp/CMakeLists.txt
tests/zyppng/EventLoop_test.cc
tests/zyppng/media/CMakeLists.txt
zypp/HistoryLog.cc
zypp/HistoryLog.h
zypp/HistoryLogData.cc
zypp/PoolItem.cc
zypp/PoolItem.h
zypp/ResPool.cc
zypp/ResPool.h
zypp/ResStatus.cc
zypp/ResStatus.h
zypp/base/LogControl.h
zypp/pool/PoolImpl.cc
zypp/pool/PoolImpl.h
zypp/sat/Transaction.h
zypp/solver/detail/SATResolver.cc
zypp/target/TargetImpl.cc

index 68009d1..e79e871 100644 (file)
@@ -10,6 +10,7 @@ OPTION (ENABLE_BUILD_TRANS "Build translation files by default?" OFF)
 OPTION (ENABLE_BUILD_TESTS "Build and run test suite by default?" OFF)
 OPTION (ENABLE_USE_THREADS "Enable using threads (NOT being used by threads!)?" OFF)
 OPTION (ENABLE_ZCHUNK_COMPRESSION "Build with zchunk compression support?" OFF)
+OPTION (DISABLE_MEDIABACKEND_TESTS "Disable Tests depending on Nginx and libfcgi?" OFF)
 
 OPTION (DISABLE_LIBPROXY "Build without libproxy support even if package is installed?" OFF)
 OPTION (DISABLE_AUTODOCS "Do not require doxygen being installed (required to build autodocs)?" OFF)
@@ -100,7 +101,13 @@ MACRO(ADD_TESTS)
   FOREACH( loop_var ${ARGV} )
     SET_SOURCE_FILES_PROPERTIES( ${loop_var}_test.cc COMPILE_FLAGS "-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN -DBOOST_AUTO_TEST_MAIN=\"\" " )
     ADD_EXECUTABLE( ${loop_var}_test ${loop_var}_test.cc )
-    TARGET_LINK_LIBRARIES( ${loop_var}_test zypp-allsym ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} zypp_test_utils)
+
+    SET(TEST_REQ_LIBS zypp-allsym ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} )
+    IF(NOT DISABLE_MEDIABACKEND_TESTS)
+      LIST( APPEND TEST_REQ_LIBS zypp_test_utils)
+    ENDIF()
+
+    TARGET_LINK_LIBRARIES( ${loop_var}_test ${TEST_REQ_LIBS} )
     ADD_TEST( ${loop_var}_test ${CMAKE_CURRENT_BINARY_DIR}/${loop_var}_test --catch_system_errors=no)
   ENDFOREACH( loop_var )
 ENDMACRO(ADD_TESTS)
index 612d80c..9cefbe0 100644 (file)
@@ -60,9 +60,9 @@
 #
 SET(LIBZYPP_MAJOR "17")
 SET(LIBZYPP_COMPATMINOR "22")
-SET(LIBZYPP_MINOR "22")
-SET(LIBZYPP_PATCH "1")
+SET(LIBZYPP_MINOR "23")
+SET(LIBZYPP_PATCH "0")
 #
-# LAST RELEASED: 17.22.1 (22)
+# LAST RELEASED: 17.23.0 (22)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index 01024e8..6eb36fd 100644 (file)
@@ -21,6 +21,8 @@
 %bcond_with zchunk
 %endif
 
+%bcond_without mediabackend_tests
+
 Name:           libzypp
 Version:        @VERSION@
 Release:        0
@@ -88,7 +90,9 @@ BuildRequires:  glib2-devel
 BuildRequires:  libsigc++2-devel
 
 # required for testsuite
+%if %{with mediabackend_tests}
 BuildRequires:  nginx
+%endif
 
 Requires:       rpm
 
@@ -108,12 +112,16 @@ BuildRequires:  librpm-devel > 4.4
 %if 0%{?suse_version}
 BuildRequires:  libgpgme-devel
 #testsuite
+%if %{with mediabackend_tests}
 BuildRequires:  FastCGI-devel
+%endif
 %else
 BuildRequires:  gpgme-devel
 #testsuite
+%if %{with mediabackend_tests}
 BuildRequires: fcgi-devel
 %endif
+%endif
 
 %define min_curl_version 7.19.4
 %if 0%{?suse_version}
@@ -235,6 +243,7 @@ cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \
       -DCMAKE_BUILD_TYPE=Release \
       -DCMAKE_SKIP_RPATH=1 \
       %{?with_zchunk:-DENABLE_ZCHUNK_COMPRESSION=1} \
+      %{!?with_mediabackend_tests:-DDISABLE_MEDIABACKEND_TESTS=1} \
       ${EXTRA_CMAKE_OPTIONS} \
       ..
 make %{?_smp_mflags} VERBOSE=1
index e23b5a1..7cf0bee 100644 (file)
@@ -1,4 +1,14 @@
 -------------------------------------------------------------------
+Fri Feb 21 16:06:57 CET 2020 - ma@suse.de
+
+- Log patch status changes to history (jsc#SLE-5116)
+- Allow to disable all WebServer dependent tests when building. OBS
+  wants to be able to get rid of the nginx/FastCGI-devel build
+  requirement. Use 'rpmbuild --without mediabackend_tests' or
+  'cmake -DDISABLE_MEDIABACKEND_TESTS=1'.
+- version 17.23.0 (22)
+
+-------------------------------------------------------------------
 Fri Feb  7 14:56:40 CET 2020 - ma@suse.de
 
 - update translations
index 6a2a3ab..f619f95 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -17,7 +17,7 @@ msgstr ""
 "Project-Id-Version: zypp\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-12-05 14:22+0100\n"
-"PO-Revision-Date: 2019-03-23 20:19+0000\n"
+"PO-Revision-Date: 2020-02-19 23:54+0000\n"
 "Last-Translator: Juan Sarria <juansarriam@gmail.com>\n"
 "Language-Team: Spanish <https://l10n.opensuse.org/projects/libzypp/master/es/"
 ">\n"
@@ -26,7 +26,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.3\n"
+"X-Generator: Weblate 3.6.1\n"
 
 #. dubious: Throw on malformed known types, otherwise log a warning.
 #: zypp/CheckSum.cc:136
@@ -4640,19 +4640,19 @@ msgstr "instalar %s desde el repositorio excluido"
 #: zypp/solver/detail/SATResolver.cc:1386
 #, boost-format
 msgid "install %1% although it has been retracted"
-msgstr ""
+msgstr "instalar %1% aunque se haya retraído"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1389
 #, boost-format
 msgid "allow to install the PTF %1%"
-msgstr ""
+msgstr "permitir la instalación de PTF %1%"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1392
 #, boost-format
 msgid "install %1% although it is blacklisted"
-msgstr ""
+msgstr "instalar %1% aunque esté en la lista negra"
 
 #: zypp/solver/detail/SATResolver.cc:1412
 #, c-format, boost-format
index 8c21cda..38c7169 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -20,16 +20,16 @@ msgstr ""
 "Project-Id-Version: zypp.fr\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-12-05 14:22+0100\n"
-"PO-Revision-Date: 2019-03-23 20:19+0000\n"
+"PO-Revision-Date: 2020-02-20 18:54+0000\n"
 "Last-Translator: Christine Gabriel <christine@stoquart.com>\n"
-"Language-Team: French <https://l10n.opensuse.org/projects/libzypp/master/fr/"
-">\n"
+"Language-Team: French <https://l10n.opensuse.org/projects/libzypp/master/fr/>"
+"\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.3\n"
+"X-Generator: Weblate 3.6.1\n"
 
 #. dubious: Throw on malformed known types, otherwise log a warning.
 #: zypp/CheckSum.cc:136
@@ -124,7 +124,7 @@ msgstr "Aruba"
 #. :ABW:533:
 #: zypp/CountryCode.cc:173
 msgid "Aland Islands"
-msgstr "Îles Aland"
+msgstr "Îles Åland"
 
 #. :ALA:248:
 #: zypp/CountryCode.cc:174
@@ -4642,19 +4642,19 @@ msgstr "installer %s depuis le dépôt exclu"
 #: zypp/solver/detail/SATResolver.cc:1386
 #, boost-format
 msgid "install %1% although it has been retracted"
-msgstr ""
+msgstr "installer %1% bien qu'il ait été retiré"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1389
 #, boost-format
 msgid "allow to install the PTF %1%"
-msgstr ""
+msgstr "autoriser l'installation du PTF %1%"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1392
 #, boost-format
 msgid "install %1% although it is blacklisted"
-msgstr ""
+msgstr "installer %1% bien qu'il ait été placé en liste noire"
 
 #: zypp/solver/detail/SATResolver.cc:1412
 #, c-format, boost-format
index a7844db..55ae262 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -15,7 +15,7 @@ msgstr ""
 "Project-Id-Version: zypp\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-12-05 14:22+0100\n"
-"PO-Revision-Date: 2019-03-23 20:19+0000\n"
+"PO-Revision-Date: 2020-02-19 17:54+0000\n"
 "Last-Translator: Davide Aiello <davidea@novilinguists.com>\n"
 "Language-Team: Italian <https://l10n.opensuse.org/projects/libzypp/master/it/"
 ">\n"
@@ -24,7 +24,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.3\n"
+"X-Generator: Weblate 3.6.1\n"
 "X-Poedit-Bookmarks: 370,-1,-1,-1,-1,-1,-1,-1,-1,-1\n"
 
 #. dubious: Throw on malformed known types, otherwise log a warning.
@@ -4624,19 +4624,19 @@ msgstr "installa %s da repository escluso"
 #: zypp/solver/detail/SATResolver.cc:1386
 #, boost-format
 msgid "install %1% although it has been retracted"
-msgstr ""
+msgstr "installare %1% anche se è stato ritirato"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1389
 #, boost-format
 msgid "allow to install the PTF %1%"
-msgstr ""
+msgstr "consentire installazione di PTF %1%"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1392
 #, boost-format
 msgid "install %1% although it is blacklisted"
-msgstr ""
+msgstr "Installare %1% anche se è nella black list"
 
 #: zypp/solver/detail/SATResolver.cc:1412
 #, c-format, boost-format
index 00d634b..d5489b9 100644 (file)
@@ -12,8 +12,8 @@ msgstr ""
 "Project-Id-Version: YaST (@memory@)\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-12-05 14:22+0100\n"
-"PO-Revision-Date: 2019-03-14 18:32+0000\n"
-"Last-Translator: Marguerite Su <i@marguerite.su>\n"
+"PO-Revision-Date: 2020-02-17 05:54+0000\n"
+"Last-Translator: Grace Yu <grace.yu@excel-gits.com>\n"
 "Language-Team: Chinese (China) <https://l10n.opensuse.org/projects/libzypp/"
 "master/zh_CN/>\n"
 "Language: zh_CN\n"
@@ -21,7 +21,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.3\n"
+"X-Generator: Weblate 3.6.1\n"
 
 #. dubious: Throw on malformed known types, otherwise log a warning.
 #: zypp/CheckSum.cc:136
@@ -4601,19 +4601,19 @@ msgstr "从排除的软件源安装 %s"
 #: zypp/solver/detail/SATResolver.cc:1386
 #, boost-format
 msgid "install %1% although it has been retracted"
-msgstr ""
+msgstr "尽管 %1% 已收回,仍予以安装"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1389
 #, boost-format
 msgid "allow to install the PTF %1%"
-msgstr ""
+msgstr "允许安装 PTF %1%"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1392
 #, boost-format
 msgid "install %1% although it is blacklisted"
-msgstr ""
+msgstr "尽管 %1% 已列入黑名单,仍予以安装"
 
 #: zypp/solver/detail/SATResolver.cc:1412
 #, c-format, boost-format
index 86718dc..171e5e3 100644 (file)
@@ -11,8 +11,8 @@ msgstr ""
 "Project-Id-Version: zypp\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-12-05 14:22+0100\n"
-"PO-Revision-Date: 2019-05-03 09:49+0000\n"
-"Last-Translator: Ramax Lo <ramaxlo@gmail.com>\n"
+"PO-Revision-Date: 2020-02-17 14:54+0000\n"
+"Last-Translator: Grace Yu <grace.yu@excel-gits.com>\n"
 "Language-Team: Chinese (Taiwan) <https://l10n.opensuse.org/projects/libzypp/"
 "master/zh_TW/>\n"
 "Language: zh_TW\n"
@@ -20,7 +20,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.3\n"
+"X-Generator: Weblate 3.6.1\n"
 
 #. dubious: Throw on malformed known types, otherwise log a warning.
 #: zypp/CheckSum.cc:136
@@ -4592,19 +4592,19 @@ msgstr "自排除的套件庫中安裝 %s"
 #: zypp/solver/detail/SATResolver.cc:1386
 #, boost-format
 msgid "install %1% although it has been retracted"
-msgstr ""
+msgstr "儘管 %1% 已收回,仍予以安裝"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1389
 #, boost-format
 msgid "allow to install the PTF %1%"
-msgstr ""
+msgstr "允許安裝 PTF %1%"
 
 #. translator: %1% is a package name
 #: zypp/solver/detail/SATResolver.cc:1392
 #, boost-format
 msgid "install %1% although it is blacklisted"
-msgstr ""
+msgstr "儘管 %1% 已列入黑名單,仍予以安裝"
 
 #: zypp/solver/detail/SATResolver.cc:1412
 #, c-format, boost-format
index 0501775..6cc4b9f 100644 (file)
@@ -1,8 +1,9 @@
 
 ADD_DEFINITIONS( -DTESTS_SRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}" -DTESTS_BUILD_DIR="${CMAKE_CURRENT_BINARY_DIR}" )
 
-
+IF( NOT DISABLE_MEDIABACKEND_TESTS )
 ADD_SUBDIRECTORY(lib)
+ENDIF()
 
 ENABLE_TESTING()
 INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/lib )
index 1732b8a..b8b2deb 100644 (file)
@@ -11,4 +11,4 @@
 discard\|one field
 discard|to fields but bad date
 2015-08-11 18:42:49|command|root@fibonacci|'/Local/ma/zypp/BUILD/zypper/src/zypper' 'in' '-f' 'xteddy'|
-2011-07-18 18:08:09|pstate|patch-name|2.6.37.6-0.5.1|noarch|repo-update|moderate|security|needed|satisfied
+2011-07-18 18:08:09|patch|patch-name|2.6.37.6-0.5.1|noarch|repo-update|moderate|security|needed|applied|
index 5110460..69f5011 100644 (file)
@@ -7,9 +7,14 @@ INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/tests/zypp )
 ADD_TESTS(
   DUdata
   ExtendedMetadata
-  MirrorList
   PluginServices
   RepoLicense
   RepoSigcheck
   RepoVariables
 )
+
+IF( NOT DISABLE_MEDIABACKEND_TESTS )
+ADD_TESTS(
+  MirrorList
+)
+ENDIF()
index b6a08ed..9bed39b 100644 (file)
@@ -18,7 +18,6 @@ ADD_TESTS(
   Deltarpm
   Edition
   ExtendedPool
-  Fetcher
   FileChecker
   Flags
   GZStream
@@ -26,7 +25,6 @@ ADD_TESTS(
   KeyRing
   Locale
   Locks
-  MediaSetAccess
   PathInfo
   Pathname
   PluginFrame
@@ -37,7 +35,6 @@ ADD_TESTS(
   PublicKey
   PurgeKernels
   RWPtr
-  RepoInfo
   RepoManager
   RepoStatus
   ResKind
@@ -61,3 +58,11 @@ IF (ENABLE_ZCHUNK_COMPRESSION)
   )
 ENDIF(ENABLE_ZCHUNK_COMPRESSION)
 
+IF( NOT DISABLE_MEDIABACKEND_TESTS )
+  ADD_TESTS(
+    Fetcher
+    MediaSetAccess
+    RepoInfo
+  )
+ENDIF()
+
index fd19b60..ef944dc 100644 (file)
@@ -48,7 +48,8 @@ BOOST_AUTO_TEST_CASE(eventloop)
     hitT4++;
 
     //timer deviation should not be too big, can only be tested on a singleShot timer
-    BOOST_REQUIRE_LE( t.now() - t.expires(), 3 );
+    // ma: disabled as OBS builder have quite big deviation >15
+    // BOOST_REQUIRE_LE( t.now() - t.expires(), 3 );
   });
 
   //convenience function to execute a function later
index 3ce9228..379a57c 100644 (file)
@@ -1,4 +1,6 @@
-ADD_TESTS(
-  NetworkRequestDispatcher
-  EvDownloader
-)
+IF( NOT DISABLE_MEDIABACKEND_TESTS)
+  ADD_TESTS(
+    NetworkRequestDispatcher
+    EvDownloader
+  )
+ENDIF()
index 7911326..c4b20d7 100644 (file)
@@ -332,7 +332,7 @@ namespace zypp
     }
   }
 
-  void HistoryLog::patchStateChange( const PoolItem & pi, const std::string &oldstate )
+  void HistoryLog::patchStateChange( const PoolItem & pi, ResStatus::ValidateValue oldstate )
   {
     if ( ! pi.isKind<Patch>() ) return;
     const Patch::constPtr p = asKind<Patch>(pi.resolvable());
@@ -346,8 +346,8 @@ namespace zypp
       << _sep << p->repoInfo().alias()                                 // 6 repo alias
       << _sep << p->severity()                                         // 7 severity
       << _sep << p->category()                                         // 8 category
-      << _sep << oldstate                                              // 9 old state
-      << _sep << pi.patchStatusAsString()                              // 10 new state
+      << _sep << ResStatus::validateValueAsString( oldstate )          // 9 old state
+      << _sep << pi.status().validateValueAsString()                   // 10 new state
       << _sep << str::escape(ZConfig::instance().userData(), _sep)     // 11 userdata
       << endl;
   }
index d956a39..91914c6 100644 (file)
@@ -15,6 +15,7 @@
 #include <iosfwd>
 
 #include "zypp/Pathname.h"
+#include "zypp/ResStatus.h"
 
 namespace zypp
 {
@@ -128,7 +129,7 @@ namespace zypp
      *
      * \param oldstate info about the old state
      */
-    void patchStateChange ( const PoolItem & pi, const std::string &oldstate );
+    void patchStateChange( const PoolItem & pi, ResStatus::ValidateValue oldstate );
 
   };
   ///////////////////////////////////////////////////////////////////
index bc9e396..0307a5d 100644 (file)
@@ -60,7 +60,7 @@ namespace zypp
       _table["ralias"] = REPO_CHANGE_ALIAS_e;
       _table["rurl"]   = REPO_CHANGE_URL_e;
       _table["command"]        = STAMP_COMMAND_e;
-      _table["pstate"] = PATCH_STATE_CHANGE_e;
+      _table["patch"]  = PATCH_STATE_CHANGE_e;
       _table["NONE"]   = _table["none"] = NONE_e;
     }
 
@@ -88,7 +88,7 @@ namespace zypp
       _table[REPO_CHANGE_ALIAS_e] = PairType( "ralias" , "ralias " );
       _table[REPO_CHANGE_URL_e]   = PairType( "rurl"   , "rurl   " );
       _table[STAMP_COMMAND_e]     = PairType( "command"        , "command" );
-      _table[PATCH_STATE_CHANGE_e]= PairType( "pstate"  , "pstate " );
+      _table[PATCH_STATE_CHANGE_e]= PairType( "patch"   , "patch  " );
       _table[NONE_e]              = PairType( "NONE"   , "NONE   " );
     }
 
index 5efda63..37f401a 100644 (file)
@@ -100,17 +100,6 @@ namespace zypp
        return isBroken() && status().isLocked();
       }
 
-      std::string patchStatusAsString() const
-      {
-        if ( isUndetermined() ) return "undetermined";
-        if ( isRelevant() )     return "relevant";
-        if ( isSatisfied() )    return "satisfied";
-        if ( isBroken() )       return "broken";
-        if ( isNeeded() )       return "needed";
-        if ( isUnwanted() )     return "unwanted";
-        return "none";
-      }
-
     private:
       mutable ResStatus     _status;
       ResObject::constPtr   _resolvable;
@@ -222,7 +211,6 @@ namespace zypp
   bool PoolItem::isBroken() const                      { return _pimpl->isBroken(); }
   bool PoolItem::isNeeded() const                      { return _pimpl->isNeeded(); }
   bool PoolItem::isUnwanted() const                    { return _pimpl->isUnwanted(); }
-  std::string PoolItem::patchStatusAsString() const     { return _pimpl->patchStatusAsString(); }
 
   void PoolItem::saveState() const                     { _pimpl->saveState(); }
   void PoolItem::restoreState() const                  { _pimpl->restoreState(); }
index e137832..d3d94e7 100644 (file)
@@ -77,6 +77,7 @@ namespace zypp
 
       /** Reset status. */
       ResStatus & statusReset() const;
+      //@}
 
 
       /** \name Status validation.
@@ -104,12 +105,8 @@ namespace zypp
 
       /** Broken (needed) but locked patches. */
       bool isUnwanted() const;
-
-      std::string patchStatusAsString () const;
-
       //@}
 
-      //@}
     public:
       /** Return the \ref ResPool the item belongs to. */
       ResPool pool() const;
index fa708ee..25f730d 100644 (file)
@@ -26,6 +26,10 @@ namespace zypp
 { /////////////////////////////////////////////////////////////////
 
   ///////////////////////////////////////////////////////////////////
+  // class ResPool
+  ///////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
   //
   //   METHOD NAME : ResPool::instance
   //   METHOD TYPE : ResPool
@@ -66,10 +70,11 @@ namespace zypp
   ResPool::size_type ResPool::size() const
   { return _pimpl->size(); }
 
-
   PoolItem ResPool::find( const sat::Solvable & slv_r ) const
   { return _pimpl->find( slv_r ); }
 
+  ResPool::EstablishedStates ResPool::establishedStates() const
+  { return _pimpl->establishedStates(); }
 
   ResPool::size_type ResPool::knownRepositoriesSize() const
   { return _pimpl->knownRepositoriesSize(); }
index b64b7ad..572151f 100644 (file)
@@ -297,9 +297,57 @@ namespace zypp
       //@}
 
     public:
-      /** \name Special iterators. */
+      /** \name Misc Data. */
       //@{
+      ///////////////////////////////////////////////////////////////////
+      /// A copy of the Pools initial ValidateValues of pseudo installed items.
+      ///
+      /// AKA Patch status. Whenever the Pools content changes, the status
+      /// of pseudo installed items (like Patches) is computed (roughly whether
+      /// their dependencies are broken or satisfied) and remembered.
+      ///
+      /// Comparing the items established state against it's current state
+      /// tells how the current transaction would influence the item (break
+      /// or repair a Patch).
+      ///
+      class EstablishedStates
+      {
+      public:
+       ~EstablishedStates();
+       /** Map holding pseudo installed items where current and established status differ. */
+       typedef std::map<PoolItem,ResStatus::ValidateValue> ChangedPseudoInstalled;
+       /** Return all pseudo installed items whose current state differs from the established one */
+       ChangedPseudoInstalled changedPseudoInstalled() const;
+      private:
+       class Impl;
+       RW_pointer<Impl> _pimpl;
+      private:
+       friend class pool::PoolImpl;
+       /** Factory: \ref ResPool::establishedStates */
+       EstablishedStates( shared_ptr<Impl> pimpl_r )
+       : _pimpl { pimpl_r }
+       {}
+      };
+      ///////////////////////////////////////////////////////////////////
+
+      /** Factory for \ref EstablishedStates.
+       * A few internal algorithms benefit from keeping an instance across pool
+       * content changes. User code usually want's to call \ref changedPseudoInstalled
+       * directly.
+       */
+      EstablishedStates establishedStates() const;
 
+      /** Map holding pseudo installed items where current and established status differ. */
+      typedef EstablishedStates::ChangedPseudoInstalled ChangedPseudoInstalled;
+
+      /** Return all pseudo installed items whose current state differs from their initial one.
+       * E.g. a Patch may become SATISFIED by updating the packages it refers to.
+       * For this to happen it does not matter whether you selected the Patch or
+       * whether you selected the individual Packages.
+       * A Patches status is computed and updated with every solver run.
+       */
+      ChangedPseudoInstalled changedPseudoInstalled() const
+      { return establishedStates().changedPseudoInstalled(); }
       //@}
    public:
       /** \name Iterate over all Repositories that contribute ResObjects.
index ee770f3..803ac7b 100644 (file)
@@ -62,6 +62,37 @@ namespace zypp
     }
   }
 
+  namespace
+  {
+    // NOTE: Strings defined here are written to the history file
+    // and used by zypper. Do not change them!
+    static const char* strBROKEN = "needed";
+    static const char* strSATISFIED = "applied";
+    static const char* strNONRELEVANT = "not-needed";
+    static const char* strUNDETERMINED = "undetermined";
+  }
+
+  std::string ResStatus::validateValueAsString( ValidateValue val_r )
+  {
+    const char* ret = strUNDETERMINED;
+    switch ( val_r )
+    {
+      case BROKEN:     ret = strBROKEN; break;
+      case SATISFIED:  ret = strSATISFIED; break;
+      case NONRELEVANT:        ret = strNONRELEVANT; break;
+      case UNDETERMINED:break;// to avoid default:
+    }
+    return ret;
+  }
+
+  ResStatus::ValidateValue ResStatus::stringToValidateValue( const std::string & str_r )
+  {
+    ValidateValue ret = UNDETERMINED;
+    if      ( str_r == strBROKEN )      ret = BROKEN;
+    else if ( str_r == strSATISFIED )   ret = SATISFIED;
+    else if ( str_r == strNONRELEVANT ) ret = NONRELEVANT;
+    return ret;
+  }
 
   /******************************************************************
   **
index 89ebe40..652cc39 100644 (file)
@@ -225,6 +225,15 @@ namespace zypp
     bool isNonRelevant() const
     { return fieldValueIs<ValidateField>( NONRELEVANT ); }
 
+    std::string validateValueAsString() const
+    { return validateValueAsString( validate() ); }
+
+    /** ValidateValue to string used in the history file. */
+    static std::string validateValueAsString( ValidateValue val_r );
+
+    /** ValidateValue from string used in the history file. */
+    static ValidateValue stringToValidateValue( const std::string & str_r );
+
   public:
     // These two are IMMUTABLE!
 
index b31c453..75cc36a 100644 (file)
@@ -13,6 +13,7 @@
 #define ZYPP_BASE_LOGCONTROL_H
 
 #include <iosfwd>
+#include <ostream> //for std::endl
 
 #include "zypp/base/Logger.h"
 #include "zypp/base/PtrTypes.h"
index 23d803a..c10c8f0 100644 (file)
@@ -20,6 +20,12 @@ using std::endl;
 namespace zypp
 { /////////////////////////////////////////////////////////////////
 
+  ResPool::EstablishedStates::~EstablishedStates()
+  {}
+
+  ResPool::EstablishedStates::ChangedPseudoInstalled ResPool::EstablishedStates::changedPseudoInstalled() const
+  { return _pimpl->changedPseudoInstalled(); }
+
   ///////////////////////////////////////////////////////////////////
   namespace pool
   { /////////////////////////////////////////////////////////////////
index 807f4a7..60d5cf7 100644 (file)
@@ -105,6 +105,57 @@ namespace zypp
   }
 
   ///////////////////////////////////////////////////////////////////
+  namespace solver {
+    namespace detail {
+      void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r );        // in solver/detail/SATResolver.cc
+    }
+  }
+  ///////////////////////////////////////////////////////////////////
+  /// Store initial establish status of pseudo installed items.
+  ///
+  class ResPool::EstablishedStates::Impl
+  {
+  public:
+    Impl()
+    { solver::detail::establish( _pseudoItems, _pseudoFlags ); }
+
+    /** Return all pseudo installed items whose current state differs from their initial one. */
+    ResPool::EstablishedStates::ChangedPseudoInstalled changedPseudoInstalled() const
+    {
+      ChangedPseudoInstalled ret;
+
+      if ( ! _pseudoItems.empty() )
+      {
+       for ( sat::Queue::size_type i = 0; i < _pseudoItems.size(); ++i )
+       {
+         PoolItem pi { sat::Solvable(_pseudoItems[i]) };
+         ResStatus::ValidateValue vorig { validateValue( i ) };
+         if ( pi.status().validate() != vorig )
+           ret[pi] = vorig;
+       }
+      }
+      return ret;
+    }
+
+  private:
+    ResStatus::ValidateValue validateValue( sat::Queue::size_type i ) const
+    {
+      ResStatus::ValidateValue ret { ResStatus::UNDETERMINED };
+      switch ( _pseudoFlags[i] )
+      {
+       case  0: ret = ResStatus::BROKEN      /*2*/; break;
+       case  1: ret = ResStatus::SATISFIED   /*4*/; break;
+       case -1: ret = ResStatus::NONRELEVANT /*6*/; break;
+      }
+      return ret;
+    }
+
+  private:
+    sat::Queue _pseudoItems;
+    sat::Queue _pseudoFlags;
+  };
+
+  ///////////////////////////////////////////////////////////////////
   namespace pool
   { /////////////////////////////////////////////////////////////////
 
@@ -128,6 +179,8 @@ namespace zypp
 
         typedef sat::detail::SolvableIdType            SolvableIdType;
 
+       typedef ResPool::EstablishedStates::Impl        EstablishedStatesImpl;
+
       public:
         /** Default ctor */
         PoolImpl();
@@ -198,6 +251,14 @@ namespace zypp
           return *_poolProxy;
         }
 
+        /** True factory for \ref ResPool::EstablishedStates.
+        * Internally we maintain the ResPool::EstablishedStates::Impl
+        * reference shared_ptr. Updated whenever the pool content changes.
+        * On demand hand it out as ResPool::EstablishedStates Impl.
+        */
+        ResPool::EstablishedStates establishedStates() const
+        { store(); return ResPool::EstablishedStates( _establishedStates ); }
+
       public:
         /** Forward list of Repositories that contribute ResObjects from \ref sat::Pool */
         size_type knownRepositoriesSize() const
@@ -352,6 +413,10 @@ namespace zypp
             {
               reapplyHardLocks();
             }
+
+           // Compute the initial status of Patches etc.
+            if ( !_establishedStates )
+             _establishedStates.reset( new EstablishedStatesImpl );
           }
           return _store;
         }
@@ -394,6 +459,7 @@ namespace zypp
          _id2itemDirty = true;
          _id2item.clear();
           _poolProxy.reset();
+         _establishedStates.reset();
         }
 
       private:
@@ -408,6 +474,7 @@ namespace zypp
 
       private:
         mutable shared_ptr<ResPoolProxy>      _poolProxy;
+       mutable shared_ptr<EstablishedStatesImpl> _establishedStates;
 
       private:
         /** Set of queries that define hardlocks. */
index 60406a4..5d1793e 100644 (file)
@@ -165,6 +165,8 @@ namespace zypp
        /** Pointer behind the last action step in transaction. */
        action_iterator actionEnd() const;
 
+       /** Iterate the [filtered] transaction steps. */
+       Iterable<action_iterator> action( StepStages filter_r = StepStages() ) const;
        //@}
 
       public:
@@ -392,6 +394,9 @@ namespace zypp
       return cnt;
     }
 
+    inline Iterable<Transaction::action_iterator> Transaction::action( StepStages filter_r ) const
+    { return makeIterable( actionBegin( filter_r ), actionEnd() ); }
+
      /////////////////////////////////////////////////////////////////
   } // namespace sat
   ///////////////////////////////////////////////////////////////////
index f529f62..ad30275 100644 (file)
@@ -37,6 +37,7 @@ extern "C"
 
 #include "zypp/ZConfig.h"
 #include "zypp/Product.h"
+#include "zypp/AutoDispose.h"
 #include "zypp/sat/WhatProvides.h"
 #include "zypp/sat/WhatObsoletes.h"
 #include "zypp/sat/detail/PoolImpl.h"
@@ -90,6 +91,74 @@ namespace zypp
          }
        }
 
+       /** Helper collecting pseudo installed items from the pool.
+        * \todo: pseudoItems are cachable as long as pool content does not change
+        */
+       inline sat::Queue collectPseudoInstalled( const ResPool & pool_r )
+       {
+         sat::Queue ret;
+         for ( const PoolItem & pi : pool_r )
+           if ( traits::isPseudoInstalled( pi.kind() ) ) ret.push( pi.id() );
+         return ret;
+       }
+
+       /** Copy back new \ref WeakValue to \ref PoolItem after solving.
+        * On the fly collect orphaned items (cached by the solver for the UI)
+        */
+       inline void solverCopyBackWeak( sat::detail::CSolver & satSolver_r, PoolItemList & orphanedItems_r )
+       {
+         // NOTE: assert all items weak stati are reset (resetWeak was called)
+         {
+           sat::Queue recommendations;
+           sat::Queue suggestions;
+           ::solver_get_recommendations( &satSolver_r, recommendations, suggestions, 0 );
+           for ( sat::Queue::size_type i = 0; i < recommendations.size(); ++i )
+             PoolItem(sat::Solvable(i)).status().setRecommended( true );
+           for ( sat::Queue::size_type i = 0; i < suggestions.size(); ++i )
+             PoolItem(sat::Solvable(i)).status().setSuggested( true );
+         }
+         {
+           orphanedItems_r.clear();    // cached on the fly
+           sat::Queue orphaned;
+           ::solver_get_orphaned( &satSolver_r, orphaned );
+           for ( sat::Queue::size_type i = 0; i < orphaned.size(); ++i )
+           {
+             PoolItem pi { sat::Solvable(i) };
+             pi.status().setOrphaned( true );
+             orphanedItems_r.push_back( pi );
+           }
+         }
+         {
+           sat::Queue unneeded;
+           ::solver_get_unneeded( &satSolver_r, unneeded, 1 );
+           for ( sat::Queue::size_type i = 0; i < unneeded.size(); ++i )
+             PoolItem(sat::Solvable(i)).status().setUnneeded( true );
+         }
+       }
+
+       /** Copy back new \ref ValidateValue to \ref PoolItem after solving. */
+       inline void solverCopyBackValidate( sat::detail::CSolver & satSolver_r, const ResPool & pool_r )
+       {
+         sat::Queue pseudoItems { collectPseudoInstalled( pool_r ) };
+         if ( ! pseudoItems.empty() )
+         {
+           sat::Queue pseudoFlags;
+           ::solver_trivial_installable( &satSolver_r, pseudoItems, pseudoFlags );
+
+           for ( sat::Queue::size_type i = 0; i < pseudoItems.size(); ++i )
+           {
+             PoolItem pi { sat::Solvable(pseudoItems[i]) };
+             switch ( pseudoFlags[i] )
+             {
+               case 0:  pi.status().setBroken(); break;
+               case 1:  pi.status().setSatisfied(); break;
+               case -1: pi.status().setNonRelevant(); break;
+               default: pi.status().setUndetermined(); break;
+             }
+           }
+         }
+       }
+
       } //namespace
       ///////////////////////////////////////////////////////////////////////
 
@@ -110,6 +179,50 @@ int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvab
                                             IdString(solvable2->vendor) ) ? 0 : 1;
 }
 
+/** ResPool helper to compute the initial status of Patches etc.
+ * An empty solver run (no jobs) just to compute the initial status
+ * of pseudo installed items (patches).
+ */
+void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r )
+{
+  pseudoItems_r = collectPseudoInstalled( ResPool::instance() );
+  if ( ! pseudoItems_r.empty() )
+  {
+    MIL << "Establish..." << endl;
+    sat::detail::CPool * cPool { sat::Pool::instance().get() };
+    ::pool_set_custom_vendorcheck( cPool, &vendorCheck );
+
+    sat::Queue jobQueue;
+    // Add rules for parallel installable resolvables with different versions
+    for ( const sat::Solvable & solv : sat::Pool::instance().multiversion() )
+    {
+      jobQueue.push( SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
+      jobQueue.push( solv.id() );
+    }
+
+    AutoDispose<sat::detail::CSolver*> cSolver { ::solver_create( cPool ), ::solver_free };
+    sat::Pool::instance().prepare();
+    if ( ::solver_solve( cSolver, jobQueue ) != 0 )
+      INT << "How can establish fail?" << endl;
+
+    ::solver_trivial_installable( cSolver, pseudoItems_r, pseudoFlags_r );
+
+    for ( sat::Queue::size_type i = 0; i < pseudoItems_r.size(); ++i )
+    {
+      PoolItem pi { sat::Solvable(pseudoItems_r[i]) };
+      switch ( pseudoFlags_r[i] )
+      {
+       case 0:  pi.status().setBroken(); break;
+       case 1:  pi.status().setSatisfied(); break;
+       case -1: pi.status().setNonRelevant(); break;
+       default: pi.status().setUndetermined(); break;
+      }
+    }
+    MIL << "Establish DONE" << endl;
+  }
+  else
+    MIL << "Establish not needed." << endl;
+}
 
 inline std::string itemToString( const PoolItem & item )
 {
@@ -127,14 +240,6 @@ inline std::string itemToString( const PoolItem & item )
   return ret;
 }
 
-inline PoolItem getPoolItem( Id id_r )
-{
-  PoolItem ret( (sat::Solvable( id_r )) );
-  if ( !ret && id_r )
-    INT << "id " << id_r << " not found in ZYPP pool." << endl;
-  return ret;
-}
-
 //---------------------------------------------------------------------------
 
 std::ostream &
@@ -358,24 +463,6 @@ class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
 };
 
 
-class CollectPseudoInstalled : public resfilter::PoolItemFilterFunctor
-{
-  public:
-    Queue *solvableQueue;
-
-    CollectPseudoInstalled( Queue *queue )
-       :solvableQueue (queue)
-    {}
-
-    // collecting PseudoInstalled items
-    bool operator()( PoolItem item )
-    {
-      if ( traits::isPseudoInstalled( item.satSolvable().kind() ) )
-        queue_push( solvableQueue, item.satSolvable().id() );
-      return true;
-    }
-};
-
 bool
 SATResolver::solving(const CapabilitySet & requires_caps,
                     const CapabilitySet & conflict_caps)
@@ -441,7 +528,7 @@ SATResolver::solving(const CapabilitySet & requires_caps,
          {
            if ( id < 0 )
              continue;
-           sat::Solvable slv { id };
+           sat::Solvable slv { (sat::detail::SolvableIdType)id };
            // get product buddies (they carry the weakremover)...
            static const Capability productCap { "product()" };
            if ( slv && slv.provides().matches( productCap ) )
@@ -484,7 +571,7 @@ SATResolver::solving(const CapabilitySet & requires_caps,
       if ( p < 0 )
        continue;
 
-      sat::Solvable slv { p };
+      sat::Solvable slv { (sat::detail::SolvableIdType)p };
       if ( ! slv || slv.isSystem() )
        continue;
 
@@ -534,81 +621,10 @@ SATResolver::solving(const CapabilitySet & requires_caps,
       }
     }
 
-    Queue recommendations;
-    Queue suggestions;
-    Queue orphaned;
-    Queue unneeded;
-    queue_init(&recommendations);
-    queue_init(&suggestions);
-    queue_init(&orphaned);
-    queue_init(&unneeded);
-    solver_get_recommendations(_satSolver, &recommendations, &suggestions, 0);
-    solver_get_orphaned(_satSolver, &orphaned);
-    solver_get_unneeded(_satSolver, &unneeded, 1);
-    /*  solvables which are recommended */
-    for ( int i = 0; i < recommendations.count; ++i )
-    {
-      PoolItem poolItem( getPoolItem( recommendations.elements[i] ) );
-      poolItem.status().setRecommended( true );
-    }
-
-    /*  solvables which are suggested */
-    for ( int i = 0; i < suggestions.count; ++i )
-    {
-      PoolItem poolItem( getPoolItem( suggestions.elements[i] ) );
-      poolItem.status().setSuggested( true );
-    }
-
-    _problem_items.clear();
-    /*  solvables which are orphaned */
-    for ( int i = 0; i < orphaned.count; ++i )
-    {
-      PoolItem poolItem( getPoolItem( orphaned.elements[i] ) );
-      poolItem.status().setOrphaned( true );
-      _problem_items.push_back( poolItem );
-    }
-
-    /*  solvables which are unneeded */
-    for ( int i = 0; i < unneeded.count; ++i )
-    {
-      PoolItem poolItem( getPoolItem( unneeded.elements[i] ) );
-      poolItem.status().setUnneeded( true );
-    }
-
-    queue_free(&recommendations);
-    queue_free(&suggestions);
-    queue_free(&orphaned);
-    queue_free(&unneeded);
-
-    /* Write validation state back to pool */
-    Queue flags, solvableQueue;
-
-    queue_init(&flags);
-    queue_init(&solvableQueue);
-
-    CollectPseudoInstalled collectPseudoInstalled(&solvableQueue);
-    invokeOnEach( _pool.begin(),
-                 _pool.end(),
-                 functor::functorRef<bool,PoolItem> (collectPseudoInstalled) );
-    solver_trivial_installable(_satSolver, &solvableQueue, &flags );
-    for (int i = 0; i < solvableQueue.count; i++) {
-       PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i]));
-       item.status().setUndetermined();
-
-       if (flags.elements[i] == -1) {
-           item.status().setNonRelevant();
-           XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
-       } else if (flags.elements[i] == 1) {
-           item.status().setSatisfied();
-           XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
-       } else if (flags.elements[i] == 0) {
-           item.status().setBroken();
-           XDEBUG("SATSolutionToPool(" << item << " ) broken !");
-       }
-    }
-    queue_free(&(solvableQueue));
-    queue_free(&flags);
-
+    // copy back computed status values to pool
+    // (on the fly cache orphaned items for the UI)
+    solverCopyBackWeak( *_satSolver, _problem_items );
+    solverCopyBackValidate( *_satSolver, _pool );
 
     // Solvables which were selected due requirements which have been made by the user will
     // be selected by APPL_LOW. We can't use any higher level, because this setting must
@@ -895,7 +911,7 @@ void SATResolver::doUpdate()
       if ( p < 0 )
        continue;
 
-      sat::Solvable solv { p };
+      sat::Solvable solv { (sat::detail::SolvableIdType)p };
       if ( ! solv || solv.isSystem() )
        continue;
 
@@ -927,6 +943,12 @@ void SATResolver::doUpdate()
          ERR << "id " << i << " not found in ZYPP pool." << endl;
       }
     }
+
+    // copy back computed status values to pool
+    // (on the fly cache orphaned items for the UI)
+    solverCopyBackWeak( *_satSolver, _problem_items );
+    solverCopyBackValidate( *_satSolver, _pool );
+
     MIL << "SATResolver::doUpdate() done" << endl;
 }
 
index ab0dc34..a387060 100644 (file)
@@ -698,6 +698,31 @@ namespace zypp
         sendNotification( root_r, result_r.updateMessages() );
       }
 
+      /** jsc#SLE-5116: Log patch status changes to history.
+       * Adjust precomputed set if transaction is incomplete.
+       */
+      void logPatchStatusChanges( const sat::Transaction & transaction_r, TargetImpl & target_r )
+      {
+       ResPool::ChangedPseudoInstalled changedPseudoInstalled { ResPool::instance().changedPseudoInstalled() };
+       if ( changedPseudoInstalled.empty() )
+         return;
+
+       if ( ! transaction_r.actionEmpty( ~sat::Transaction::STEP_DONE ) )
+       {
+         // Need to recompute the patch list if commit is incomplete!
+         // We remember the initially established status, then reload the
+         // Target to get the current patch status. Then compare.
+         WAR << "Need to recompute the patch status changes as commit is incomplete!" << endl;
+         ResPool::EstablishedStates establishedStates{ ResPool::instance().establishedStates() };
+         target_r.load();
+         changedPseudoInstalled = establishedStates.changedPseudoInstalled();
+       }
+
+       HistoryLog historylog;
+       for ( const auto & el : changedPseudoInstalled )
+         historylog.patchStateChange( el.first, el.second );
+      }
+
       /////////////////////////////////////////////////////////////////
     } // namespace
     ///////////////////////////////////////////////////////////////////
@@ -1711,8 +1736,14 @@ namespace zypp
                           result_r );
       }
 
+      // jsc#SLE-5116: Log patch status changes to history
+      // NOTE: Should be the last action as it may need to reload
+      // the Target in case of an incomplete transaction.
+      logPatchStatusChanges( result_r.transaction(), *this );
+
       if ( abort )
       {
+       HistoryLog().comment( "Commit was aborted." );
         ZYPP_THROW( TargetAbortedException( ) );
       }
     }