Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libzypp for openSUSE:Factory checked in at 2021-03-10 08:47:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libzypp (Old) and /work/SRC/openSUSE:Factory/.libzypp.new.2378 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libzypp" Wed Mar 10 08:47:12 2021 rev:440 rq:874902 version:17.25.8 Changes: -------- --- /work/SRC/openSUSE:Factory/libzypp/libzypp.changes 2021-02-23 20:20:42.899672152 +0100 +++ /work/SRC/openSUSE:Factory/.libzypp.new.2378/libzypp.changes 2021-03-10 08:47:31.570286444 +0100 @@ -1,0 +2,10 @@ +Wed Feb 24 17:07:52 CET 2021 - [email protected] + +- Try to provide a mounted /proc in --root installs (bsc#1181328) + Some systemd tools require /proc to be mounted and fail if it's + not there. +- Enable release packages to request a releaxed suse/opensuse + vendorcheck in dup when migrating. (bsc#1182629) +- version 17.25.8 (22) + +------------------------------------------------------------------- Old: ---- libzypp-17.25.7.tar.bz2 New: ---- libzypp-17.25.8.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libzypp.spec ++++++ --- /var/tmp/diff_new_pack.M2GTeq/_old 2021-03-10 08:47:32.490287393 +0100 +++ /var/tmp/diff_new_pack.M2GTeq/_new 2021-03-10 08:47:32.494287397 +0100 @@ -31,7 +31,7 @@ %bcond_without mediabackend_tests Name: libzypp -Version: 17.25.7 +Version: 17.25.8 Release: 0 URL: https://github.com/openSUSE/libzypp Summary: Library for package, patch, pattern and product management ++++++ libzypp-17.25.7.tar.bz2 -> libzypp-17.25.8.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/VERSION.cmake new/libzypp-17.25.8/VERSION.cmake --- old/libzypp-17.25.7/VERSION.cmake 2021-02-17 09:16:38.000000000 +0100 +++ new/libzypp-17.25.8/VERSION.cmake 2021-02-24 17:11:46.000000000 +0100 @@ -61,8 +61,8 @@ SET(LIBZYPP_MAJOR "17") SET(LIBZYPP_COMPATMINOR "22") SET(LIBZYPP_MINOR "25") -SET(LIBZYPP_PATCH "7") +SET(LIBZYPP_PATCH "8") # -# LAST RELEASED: 17.25.7 (22) +# LAST RELEASED: 17.25.8 (22) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/package/libzypp.changes new/libzypp-17.25.8/package/libzypp.changes --- old/libzypp-17.25.7/package/libzypp.changes 2021-02-17 09:16:38.000000000 +0100 +++ new/libzypp-17.25.8/package/libzypp.changes 2021-02-24 17:11:46.000000000 +0100 @@ -1,4 +1,14 @@ ------------------------------------------------------------------- +Wed Feb 24 17:07:52 CET 2021 - [email protected] + +- Try to provide a mounted /proc in --root installs (bsc#1181328) + Some systemd tools require /proc to be mounted and fail if it's + not there. +- Enable release packages to request a releaxed suse/opensuse + vendorcheck in dup when migrating. (bsc#1182629) +- version 17.25.8 (22) + +------------------------------------------------------------------- Wed Feb 17 09:06:49 CET 2021 - [email protected] - Patch: Identify well-known category names (bsc#117984) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/tests/zypp/StringV_test.cc new/libzypp-17.25.8/tests/zypp/StringV_test.cc --- old/libzypp-17.25.7/tests/zypp/StringV_test.cc 2021-02-10 15:19:44.000000000 +0100 +++ new/libzypp-17.25.8/tests/zypp/StringV_test.cc 2021-02-24 16:52:50.000000000 +0100 @@ -34,7 +34,7 @@ } // namespace tools -BOOST_AUTO_TEST_CASE(splitRxCallbacks) +BOOST_AUTO_TEST_CASE(WordConsumerSignature) { std::string l { "0b2" }; regex r { "^|b|$" }; @@ -88,57 +88,148 @@ namespace tools { - void expect( const std::string & l, const regex & rx, const std::initializer_list<const char*> & words ) + using zypp::strv::detail::WordConsumer; + + /* Call splitter_r and check whether CB results match word_r. May CB abort at stopAt_r. */ + void checkSplit( std::function<unsigned(WordConsumer&&)> splitter_r, const std::initializer_list<const char*> & words_r, + unsigned stopAt_r = -1U ) { - //cout << "??? <" << rx << "> <" << l << "> " << words.size() << endl; - auto next = words.begin(); - unsigned ret = splitRx( l, rx, [&]( std::string_view w, unsigned i ) { + //cout << "??? " << words_r.size() << endl; + auto next = words_r.begin(); + unsigned ret = splitter_r( [&]( std::string_view w, unsigned i, bool f )->bool { //cout << " ["<<i<<"] <"<<w<<">"<<endl; - BOOST_REQUIRE( next != words.end() ); + BOOST_REQUIRE( next != words_r.end() ); BOOST_CHECK_EQUAL( *next, w ); ++next; + BOOST_CHECK_EQUAL( f, next == words_r.end() ); + return i != stopAt_r; }); //cout << " => " << ret << endl; - BOOST_CHECK_EQUAL( next, words.end() ); - BOOST_CHECK_EQUAL( ret, words.size() ); + BOOST_CHECK_EQUAL( next, words_r.end() ); + BOOST_CHECK_EQUAL( ret, words_r.size() ); } + + void expectRx( const std::string & l, const regex & rx, const std::initializer_list<const char*> & words, unsigned stopAt = -1U ) + { checkSplit( [&](WordConsumer && wc) { return splitRx( l, rx, wc ); }, words, stopAt ); } + + void expectSp( std::string_view l, std::string_view sep, const std::initializer_list<const char*> & words, unsigned stopAt = -1U ) + { checkSplit( [&](WordConsumer && wc) { return split( l, sep, wc ); }, words, stopAt ); } + + void expectTp( std::string_view l, std::string_view sep, const std::initializer_list<const char*> & words, unsigned stopAt = -1U ) + { checkSplit( [&](WordConsumer && wc) { return split( l, sep, Trim::trim, wc ); }, words, stopAt ); } } // namespace tools + BOOST_AUTO_TEST_CASE(splitRxResults) { - using tools::expect; + using tools::expectRx ; regex rx; // no regex, no match ==> input reported - expect( "", rx, {""} ); - expect( "0", rx, {"0"} ); - expect( "01", rx, {"01"} ); - expect( "012", rx, {"012"} ); + expectRx( "", rx, {""} ); + expectRx( "0", rx, {"0"} ); + expectRx( "01", rx, {"01"} ); + expectRx( "012", rx, {"012"} ); rx = ""; // Empty regex, empty matches - expect( "", rx, {"",""} ); - expect( "0", rx, {"","0",""} ); - expect( "01", rx, {"","0","1",""} ); - expect( "012", rx, {"","0","1","2",""} ); + expectRx( "", rx, {"",""} ); + expectRx( "0", rx, {"","0",""} ); + expectRx( "01", rx, {"","0","1",""} ); + expectRx( "012", rx, {"","0","1","2",""} ); rx = "x*"; // Empty matches as above - expect( "", rx, {"",""} ); - expect( "0", rx, {"","0",""} ); - expect( "01", rx, {"","0","1",""} ); - expect( "012", rx, {"","0","1","2",""} ); + expectRx( "", rx, {"",""} ); + expectRx( "0", rx, {"","0",""} ); + expectRx( "01", rx, {"","0","1",""} ); + expectRx( "012", rx, {"","0","1","2",""} ); rx = "1*"; - expect( "", rx, {"",""} ); - expect( "0", rx, {"","0",""} ); - expect( "01", rx, {"","0",""} ); - expect( "012", rx, {"","0","2",""} ); - expect( "012\n", rx, {"","0","2","\n"} ); // no match behind a trailing NL - expect( "012\n\n", rx, {"","0","2","\n","\n"} ); // no match behind a trailing NL + expectRx( "", rx, {"",""} ); + expectRx( "0", rx, {"","0",""} ); + expectRx( "01", rx, {"","0",""} ); + expectRx( "012", rx, {"","0","2",""} ); + expectRx( "012\n", rx, {"","0","2","\n"} ); // no match behind a trailing NL + expectRx( "012\n\n", rx, {"","0","2","\n","\n"} ); // no match behind a trailing NL rx = "^|1|$"; - expect( "", rx, {"",""} ); - expect( "0", rx, {"","0",""} ); - expect( "01", rx, {"","0",""} ); - expect( "012", rx, {"","0","2",""} ); - expect( "012\n", rx, {"","0","2","\n"} ); // no match behind a trailing NL - expect( "012\n\n", rx, {"","0","2","\n","\n"} ); // no match behind a trailing NL + expectRx( "", rx, {"",""} ); + expectRx( "0", rx, {"","0",""} ); + expectRx( "01", rx, {"","0",""} ); + expectRx( "012", rx, {"","0","2",""} ); + expectRx( "012\n", rx, {"","0","2","\n"} ); // no match behind a trailing NL + expectRx( "012\n\n", rx, {"","0","2","\n","\n"} ); // no match behind a trailing NL +} + +BOOST_AUTO_TEST_CASE(splitResults) +{ + using tools::expectSp; + + std::string sep; // empty sep; split [[:blank:]]+; report not empty words + expectSp( "", sep, {} ); + expectSp( " ", sep, {} ); + expectSp( " ", sep, {} ); + expectSp( " 1 ", sep, {"1"} ); + expectSp( " 1 2 ", sep, {"1","2"} ); + expectSp( " 1 2 ", sep, {"1","2"} ); + expectSp( " 1 2 ", sep, {"1","2"}, 0 ); // CB aborted + expectSp( " 1 2 ", sep, {"1","2"}, 1 ); // CB aborted + + sep = ","; // not empty seps.... + expectSp( "", sep, {""} ); + expectSp( ",", sep, {"",""} ); + expectSp( ",,", sep, {"","",""} ); + expectSp( "1", sep, {"1"} ); + expectSp( ",1,", sep, {"","1",""} ); + expectSp( ",1,2,", sep, {"","1","2",""} ); + expectSp( ",1,,2,", sep, {"","1","","2",""} ); + + expectSp( " ", sep, {" "} ); + expectSp( " , ", sep, {" "," "} ); + expectSp( " , , ", sep, {" "," "," "} ); + expectSp( " 1 ", sep, {" 1 "} ); + expectSp( " , 1 , ", sep, {" "," 1 "," "} ); + expectSp( " , 1 , 2 , ", sep, {" "," 1 "," 2 "," "} ); + expectSp( " , 1 , , 2 , ", sep, {" "," 1 "," "," 2 "," "} ); + expectSp( " , 1 , , 2 , ", sep, {" "," 1 , , 2 , "}, 0 ); // CB aborted + + using tools::expectTp; // trimmed split + expectTp( " ", sep, {""} ); + expectTp( " , ", sep, {"",""} ); + expectTp( " , , ", sep, {"","",""} ); + expectTp( " 1 ", sep, {"1"} ); + expectTp( " , 1 , ", sep, {"","1",""} ); + expectTp( " , 1 , 2 , ", sep, {"","1","2",""} ); + expectTp( " , 1 , , 2 , ", sep, {"","1","","2",""} ); + expectTp( " , 1 , , 2 , ", sep, {"","1 , , 2 ,"}, 0 ); // CB aborted +} + +BOOST_AUTO_TEST_CASE(trimming) +{ + BOOST_CHECK_EQUAL( ltrim(""), "" ); + BOOST_CHECK_EQUAL( ltrim(" "), "" ); + BOOST_CHECK_EQUAL( ltrim("1"), "1" ); + BOOST_CHECK_EQUAL( ltrim(" 1"), "1" ); + BOOST_CHECK_EQUAL( ltrim("1 "), "1 " ); + BOOST_CHECK_EQUAL( ltrim(" 1 "), "1 " ); + + BOOST_CHECK_EQUAL( rtrim(""), "" ); + BOOST_CHECK_EQUAL( rtrim(" "), "" ); + BOOST_CHECK_EQUAL( rtrim("1"), "1" ); + BOOST_CHECK_EQUAL( rtrim(" 1"), " 1" ); + BOOST_CHECK_EQUAL( rtrim("1 "), "1" ); + BOOST_CHECK_EQUAL( rtrim(" 1 "), " 1" ); + + BOOST_CHECK_EQUAL( trim(""), "" ); + BOOST_CHECK_EQUAL( trim(" "), "" ); + BOOST_CHECK_EQUAL( trim("1"), "1" ); + BOOST_CHECK_EQUAL( trim(" 1"), "1" ); + BOOST_CHECK_EQUAL( trim("1 "), "1" ); + BOOST_CHECK_EQUAL( trim(" 1 "), "1" ); + + BOOST_CHECK_EQUAL( ltrim(" 1 "), trim(" 1 ", Trim::left) ); + BOOST_CHECK_EQUAL( rtrim(" 1 "), trim(" 1 ", Trim::right) ); + BOOST_CHECK_EQUAL( trim(" 1 "), trim(" 1 ", Trim::left|Trim::right) ); + + BOOST_CHECK_EQUAL( trim(" \t1\t "), "1" ); + BOOST_CHECK_EQUAL( trim(" \t1\t ", " "), "\t1\t" ); + BOOST_CHECK_EQUAL( trim(" \t1\t ", ""), " \t1\t " ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/tests/zypp/Vendor_test.cc new/libzypp-17.25.8/tests/zypp/Vendor_test.cc --- old/libzypp-17.25.7/tests/zypp/Vendor_test.cc 2020-09-14 16:35:23.000000000 +0200 +++ new/libzypp-17.25.8/tests/zypp/Vendor_test.cc 2021-02-24 16:52:50.000000000 +0100 @@ -50,6 +50,13 @@ BOOST_REQUIRE( !VendorAttr::instance().equivalent("opensuse as prefix", "SuSE as prefix") ); BOOST_REQUIRE( !VendorAttr::instance().equivalent("opensuse", "opensuse as prefix") ); BOOST_REQUIRE( !VendorAttr::instance().equivalent("opensuse as prefix", "opensuse but different prefix") ); + + // bsc#1182629: relaxed equivalence just adds suse/opensuse + BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("SuSE as prefix","foreign") ); + BOOST_REQUIRE( VendorAttr::instance().relaxedEquivalent("opensuse", "SuSE as prefix") ); + BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("opensuse as prefix", "SuSE as prefix") ); + BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("opensuse", "opensuse as prefix") ); + BOOST_REQUIRE( !VendorAttr::instance().relaxedEquivalent("opensuse as prefix", "opensuse but different prefix") ); } BOOST_AUTO_TEST_CASE(vendor_test2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/zypp/VendorAttr.cc new/libzypp-17.25.8/zypp/VendorAttr.cc --- old/libzypp-17.25.7/zypp/VendorAttr.cc 2020-10-27 18:06:45.000000000 +0100 +++ new/libzypp-17.25.8/zypp/VendorAttr.cc 2021-02-24 16:52:50.000000000 +0100 @@ -58,6 +58,23 @@ bool equivalent( IdString lVendor, IdString rVendor ) const { return lVendor == rVendor || vendorMatchId( lVendor ) == vendorMatchId( rVendor ); } + /** Return whether two vendor strings should be treated as equivalent or are (suse/opensuse).*/ + bool relaxedEquivalent( IdString lVendor, IdString rVendor ) const + { + if ( equivalent( lVendor, rVendor ) ) + return true; + + static const IdString suse { "suse" }; + static const IdString opensuse { "opensuse" }; + unsigned sid = vendorMatchId( suse ); + unsigned oid = vendorMatchId( opensuse ); + if ( sid == oid ) + return false; // (suse/opensuse) are equivalent, so these are not + + auto isSuse = [sid,oid]( unsigned v )-> bool { return v==sid || v==oid; }; + return isSuse( vendorMatchId(lVendor) ) && isSuse( vendorMatchId(rVendor) ); + } + unsigned foreachVendorList( std::function<bool(VendorList)> fnc_r ) const { std::map<unsigned,VendorList> lists; @@ -320,6 +337,19 @@ bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const { return _pimpl->equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); } + + bool VendorAttr::relaxedEquivalent( IdString lVendor, IdString rVendor ) const + { return _pimpl->relaxedEquivalent( lVendor, rVendor );} + + bool VendorAttr::relaxedEquivalent( const Vendor & lVendor, const Vendor & rVendor ) const + { return _pimpl->relaxedEquivalent( IdString( lVendor ), IdString( rVendor ) ); } + + bool VendorAttr::relaxedEquivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const + { return _pimpl->relaxedEquivalent( lVendor.vendor(), rVendor.vendor() ); } + + bool VendorAttr::relaxedEquivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const + { return _pimpl->relaxedEquivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); } + ////////////////////////////////////////////////////////////////// std::ostream & operator<<( std::ostream & str, const VendorAttr & obj ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/zypp/VendorAttr.h new/libzypp-17.25.8/zypp/VendorAttr.h --- old/libzypp-17.25.7/zypp/VendorAttr.h 2020-10-27 18:06:45.000000000 +0100 +++ new/libzypp-17.25.8/zypp/VendorAttr.h 2021-02-24 16:52:50.000000000 +0100 @@ -142,6 +142,15 @@ /** \overload using \ref PoolItem */ bool equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const; + /** Like \ref equivalent but always unifies suse and openSUSE vendor */ + bool relaxedEquivalent( const Vendor & lVendor, const Vendor & rVendor ) const; + /** \overload using \ref IdStrings */ + bool relaxedEquivalent( IdString lVendor, IdString rVendor ) const; + /** \overload using \ref sat::Solvable */ + bool relaxedEquivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const; + /** \overload using \ref PoolItem */ + bool relaxedEquivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const; + public: /** Call \a fnc_r for each equivalent vendor list (return \c false to break). * \return The number of calls to \a fnc_r. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/zypp/base/StringV.cc new/libzypp-17.25.8/zypp/base/StringV.cc --- old/libzypp-17.25.7/zypp/base/StringV.cc 2021-02-10 15:19:44.000000000 +0100 +++ new/libzypp-17.25.8/zypp/base/StringV.cc 2021-02-24 16:52:50.000000000 +0100 @@ -16,22 +16,118 @@ { namespace strv { + namespace detail + { + /** \ref split working horse for empty \a sep_r case. + * Split at /[BLANK,TAB]+/ and report no-empty words. Trim::right is + * applied to the rest of the line in case the callback aborts further + * processing. + */ + unsigned _splitSimple( std::string_view line_r, WordConsumer && fnc_r ) + { + // callback stats + unsigned fncCall = 0; + + // NOTE: line_r is not null-terminated! + const char *const eol = line_r.data() + line_r.size(); // the '\0' + const char * searchfrom = line_r.data(); // start of the next search (moves with each cycle!) + + // Empty sep: split at /[BLANK,TAB]+/ and report no-empty words + auto isSep = []( char ch )->bool { return ch == ' '|| ch == '\t'; }; + + auto skipSep = [eol,&isSep]( const char *& ptr )->bool { + while ( ptr < eol && isSep( *ptr ) ) + ++ptr; + return ptr < eol; // whether we ended up at a new wordstart + }; + + auto skipWord = [eol,&isSep]( const char *& ptr )->void { + while ( ptr < eol && ! isSep( *ptr ) ) + ++ptr; + }; + + // For the 'last' CB argument: we must remember a word + // until we know whether another one is following + std::string_view word; + + while ( skipSep( searchfrom ) ) { + const char * wordstart = searchfrom; + // Report a previous word found + if ( ! word.empty() ) { + if ( fnc_r ) { + if ( ! fnc_r( word, fncCall, false/*more to come*/ ) ) { + // Stop searching for further matches. Final report will + // be the remaining line (right trimmed) + const char * wordend = eol; + while ( isSep( *(wordend-1) ) ) // noSep at wordstart stops loop + --wordend; + word = std::string_view( wordstart, wordend-wordstart ); + ++fncCall; + break; + } + } + ++fncCall; + } + // remember new word + ++searchfrom; + skipWord( searchfrom ); + word = std::string_view( wordstart, searchfrom-wordstart ); + } + + // finally report the last word + if ( ! word.empty() ) { + if ( fnc_r ) { + fnc_r( word, fncCall, true/*last*/ ); + } + ++fncCall; + } - unsigned split( std::string_view line_r, std::string_view sep_r, Trim trim_r, - std::function<void(std::string_view)> fnc_r ) + return fncCall; + } + } // namespace detail + + unsigned detail::_split( std::string_view line_r, std::string_view sep_r, Trim trim_r, WordConsumer && fnc_r ) { -#warning REIMPLEMENT - std::vector<std::string> words; - str::split( std::string(line_r), std::back_inserter(words), std::string(sep_r), str::TRIM ); + if ( sep_r.empty() ) + return _splitSimple( line_r, std::move( fnc_r ) ); + + // callback stats + bool fncStop = false; + unsigned fncCall = 0; + + using size_type = std::string_view::size_type; + size_type wordstart = 0; // start of the next string to be reported + size_type searchfrom = 0; // start of the next search for a separator + do { // report lhs word of separator matches... + searchfrom = line_r.find( sep_r, searchfrom ); + if ( fncStop || searchfrom == line_r.npos ) { + break; + } + + // Report lhs word of the match and advance... + if ( fnc_r ) { + if ( ! fnc_r( trim( line_r.substr(wordstart,searchfrom-wordstart), trim_r ), fncCall, false/*more to come*/ ) ) + fncStop= true; // stop searching for further matches + } + ++fncCall; + + // Next wordstart is behind the separator match. + searchfrom += sep_r.size(); + wordstart = searchfrom; + } while( wordstart < line_r.size() ); + + // finally report rhs word of the last separator match (or no match) if ( fnc_r ) { - for ( const auto & w : words ) - fnc_r( std::string_view(w) ); + if ( wordstart < line_r.size() ) + fnc_r( trim( line_r.substr(wordstart,line_r.size()-wordstart), trim_r ), fncCall, true/*last*/ ); + else // a final match at $ so a final empty word reported (no trim needed) + fnc_r( std::string_view( line_r.data()+line_r.size(), 0 ), fncCall, true/*last*/ ); } - return words.size(); + ++fncCall; + return fncCall; } - unsigned detail::_splitRx( const std::string & line_r, const regex & rx_r, WordConsumer && fnc_r ) { // callback stats diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/zypp/base/StringV.h new/libzypp-17.25.8/zypp/base/StringV.h --- old/libzypp-17.25.7/zypp/base/StringV.h 2021-02-10 15:19:44.000000000 +0100 +++ new/libzypp-17.25.8/zypp/base/StringV.h 2021-02-24 16:52:50.000000000 +0100 @@ -29,13 +29,67 @@ /** Define how to trim. */ enum class Trim { notrim = 0, - right = 1<<0, - left = 1<<1, + left = 1<<0, + right = 1<<1, trim = (left|right), }; ZYPP_DECLARE_FLAGS_AND_OPERATORS( TrimFlag, Trim ); + /** The default blank. */ + inline constexpr std::string_view blank = " \t"; + + /** Trim \a chars_r at the beginning of \a str_r. */ + inline std::string_view ltrim( std::string_view str_r, std::string_view chars_r = blank ) + { + if ( str_r.empty() ) + return str_r; + auto pos = str_r.find_first_not_of( chars_r ); + if ( pos == str_r.npos ) + str_r.remove_prefix( str_r.size() ); + else if ( pos ) + str_r.remove_prefix( pos ); + return str_r; + } + + /** Trim \a chars_r at the end of \a str_r. */ + inline std::string_view rtrim( std::string_view str_r, std::string_view chars_r = blank ) + { + if ( str_r.empty() ) + return str_r; + auto pos = str_r.find_last_not_of( chars_r ); + if ( pos == str_r.npos ) + str_r.remove_suffix( str_r.size() ); + else if ( (pos = str_r.size()-1-pos) ) + str_r.remove_suffix( pos ); + return str_r; + } + + /** Trim \a chars_r at both sides of \a str_r. */ + inline std::string_view trim( std::string_view str_r, std::string_view chars_r = blank ) + { + if ( str_r.empty() ) + return str_r; + str_r = ltrim( std::move(str_r), chars_r ); + str_r = rtrim( std::move(str_r), chars_r ); + return str_r; + } + + /** Trim \a chars_r at \a trim_r sides of \a str_r. */ + inline std::string_view trim( std::string_view str_r, std::string_view chars_r, TrimFlag trim_r ) + { + if ( str_r.empty() || trim_r == Trim::notrim ) + return str_r; + if ( trim_r.testFlag( Trim::left ) ) + str_r = ltrim( std::move(str_r), chars_r ); + if ( trim_r.testFlag( Trim::right ) ) + str_r = rtrim( std::move(str_r), chars_r ); + return str_r; + } + /** \overload Trimming blanks at \a trim_r sides of \a str_r. */ + inline std::string_view trim( std::string_view str_r, TrimFlag trim_r ) + { return trim( std::move(str_r), blank, std::move(trim_r) ); } + /////////////////////////////////////////////////////////////////// namespace detail { @@ -113,8 +167,12 @@ { return [&fnc_r](std::string_view,unsigned,bool)->bool { fnc_r(); return true; }; } //@} + /** \ref split working horse */ + unsigned _split( std::string_view line_r, std::string_view sep_r, Trim trim_r, WordConsumer && fnc_r ); + /** \ref splitRx working horse */ unsigned _splitRx( const std::string & line_r, const regex & rx_r, WordConsumer && fnc_r ); + } // namespace detail /////////////////////////////////////////////////////////////////// @@ -125,7 +183,7 @@ * of \a line_r, or it there are consecutive separator match occurrences. * * Accepted callbacks: [bool|void]( [std::string_view[, unsigned[, bool]]] ) - * (or no callback at all ) + * (or no callback at all) * * A callback may take the \a word, the \a index of word (starting with 0) and a boolean * indicating whether this is going to be the \a last report. @@ -145,17 +203,28 @@ /** Split \a line_r into words separated by \a sep_r and invoke \a fnc_r with each word. * - * If \a sep_r is not empty, each separator found in \a line_r will be enclosed by 2 + * - If \a sep_r is not empty, each separator found in \a line_r will be enclosed by 2 * words being reported. Words may be empty if the separator is located at the beginning - * or the end of \a line_r of it there are consecutive occurrences. If the separator does - * not occur on the line the whole string is reported. + * or the end of \a line_r or it there are consecutive occurrences. * - * If \a sep_r is unspecified or empty, it splits on whitespace /[BLANK,TAB]+/. In this - * case only the (not empty) words found on the line are reported. + * - If \a sep_r is unspecified or empty, it splits on whitespace /[BLANK,TAB]+/. In this + * case only the (not empty) words found on the line are reported (trimmed). * * The optional \a trim_r argument tells whether whitespace around the words found * should be trimmed before reporting them. The default is not to trim. * + * Accepted callbacks: [bool|void]( [std::string_view[, unsigned[, bool]]] ) + * (or no callback at all) + * + * A callback may take the \a word, the \a index of word (starting with 0) and a boolean + * indicating whether this is going to be the \a last report. + * + * A callback may optionally return a value convertible to \c bool. Returning \c false + * causes split to stop looking further separators. The final report will contain the + * remaining part of the \a line_r then. + * + * If the separator does not occur on the line the whole string is reported. + * * \returns the number of words reported. * * \code @@ -192,18 +261,19 @@ * // ['1', '3 4 5'] * \endcode */ - unsigned split( std::string_view line_r, std::string_view sep_r, Trim trim_r, - std::function<void(std::string_view)> fnc_r ); + template <typename Callable = detail::WordConsumer> + unsigned split( std::string_view line_r, std::string_view sep_r, Trim trim_r, Callable && fnc_r = Callable() ) + { return detail::_split( line_r, sep_r, trim_r, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); } /** \overload Split at \a sep_r and Trim::notrim */ - inline unsigned split( std::string_view line_r, std::string_view sep_r, - std::function<void(std::string_view)> fnc_r ) - { return split( line_r, sep_r, Trim::notrim, fnc_r ); } + template <typename Callable = detail::WordConsumer> + inline unsigned split( std::string_view line_r, std::string_view sep_r, Callable && fnc_r = Callable() ) + { return detail::_split( line_r, sep_r, Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); } /** \overload Split at whitespace */ - inline unsigned split( std::string_view line_r, - std::function<void(std::string_view)> fnc_r ) - { return split( line_r, std::string_view(), Trim::notrim, fnc_r ); } + template <typename Callable = detail::WordConsumer> + inline unsigned split( std::string_view line_r, Callable && fnc_r = Callable() ) + { return detail::_split( line_r, std::string_view(), Trim::notrim, detail::wordConsumer( std::forward<Callable>(fnc_r) ) ); } } // namespace strv } // namespace zypp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/zypp/solver/detail/SATResolver.cc new/libzypp-17.25.8/zypp/solver/detail/SATResolver.cc --- old/libzypp-17.25.7/zypp/solver/detail/SATResolver.cc 2021-01-12 19:31:38.000000000 +0100 +++ new/libzypp-17.25.8/zypp/solver/detail/SATResolver.cc 2021-02-24 16:52:50.000000000 +0100 @@ -175,10 +175,10 @@ //--------------------------------------------------------------------------- int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2 ) -{ - return VendorAttr::instance().equivalent( IdString(solvable1->vendor), - IdString(solvable2->vendor) ) ? 0 : 1; -} +{ return VendorAttr::instance().equivalent( IdString(solvable1->vendor), IdString(solvable2->vendor) ) ? 0 : 1; } + +int relaxedVendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2 ) +{ return VendorAttr::instance().relaxedEquivalent( IdString(solvable1->vendor), 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 @@ -468,8 +468,6 @@ SATResolver::solving(const CapabilitySet & requires_caps, const CapabilitySet & conflict_caps) { - _satSolver = solver_create( _satPool ); - ::pool_set_custom_vendorcheck( _satPool, &vendorCheck ); if (_fixsystem) { queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL); queue_push( &(_jobQueue), 0 ); @@ -669,6 +667,23 @@ // remove old stuff solverEnd(); + _satSolver = solver_create( _satPool ); + { + // bsc#1182629: in dup allow an available -release package providing 'dup-vendor-relax(suse)' + // to let (suse/opensuse) vendor being treated as being equivalent. + bool toRelax = false; + if ( _distupgrade ) { + for ( sat::Solvable solv : sat::WhatProvides( Capability("dup-vendor-relax(suse)") ) ) { + if ( ! solv.isSystem() ) { + MIL << "Relaxed vendor check requested by " << solv << endl; + toRelax = true; + break; + } + } + } + ::pool_set_custom_vendorcheck( _satPool, toRelax ? &relaxedVendorCheck : &vendorCheck ); + } + queue_init( &_jobQueue ); // clear and rebuild: _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep @@ -861,8 +876,6 @@ // set locks for the solver setLocks(); - _satSolver = solver_create( _satPool ); - ::pool_set_custom_vendorcheck( _satPool, &vendorCheck ); if (_fixsystem) { queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL); queue_push( &(_jobQueue), 0 ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libzypp-17.25.7/zypp/target/TargetImpl.cc new/libzypp-17.25.8/zypp/target/TargetImpl.cc --- old/libzypp-17.25.7/zypp/target/TargetImpl.cc 2021-02-10 16:39:47.000000000 +0100 +++ new/libzypp-17.25.8/zypp/target/TargetImpl.cc 2021-02-24 17:11:46.000000000 +0100 @@ -210,6 +210,56 @@ /////////////////////////////////////////////////////////////////// namespace { + /// \brief Try to provide /proc fs if not present. + /// bsc#1181328: Some systemd tools require /proc to be mounted + class AssertProcMounted + { + NON_COPYABLE(AssertProcMounted); + NON_MOVABLE(AssertProcMounted); + public: + + AssertProcMounted( Pathname root_r ) + { + root_r /= "/proc"; + if ( ! PathInfo(root_r/"self").isDir() ) { + MIL << "Try to make sure proc is mounted at" << _mountpoint << endl; + if ( filesystem::assert_dir(root_r) == 0 + && execute({ "mount", "-t", "proc", "proc", root_r.asString() }) == 0 ) { + _mountpoint = std::move(root_r); // so we'll later unmount it + } + else { + WAR << "Mounting proc at " << _mountpoint << " failed" << endl; + } + } + } + + ~AssertProcMounted( ) + { + if ( ! _mountpoint.empty() ) { + // we mounted it so we unmount... + MIL << "We mounted " << _mountpoint << " so we unmount it" << endl; + execute({ "umount", "-l", _mountpoint.asString() }); + } + } + + private: + int execute( ExternalProgram::Arguments && cmd_r ) const + { + ExternalProgram prog( cmd_r, ExternalProgram::Stderr_To_Stdout ); + for( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() ) + { DBG << line; } + return prog.close(); + } + + private: + Pathname _mountpoint; + }; + } // namespace + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + namespace + { SolvIdentFile::Data getUserInstalledFromHistory( const Pathname & historyFile_r ) { SolvIdentFile::Data onSystemByUserList; @@ -1491,6 +1541,9 @@ bool abort = false; + // bsc#1181328: Some systemd tools require /proc to be mounted + AssertProcMounted assertProcMounted( _root ); + RpmPostTransCollector postTransCollector( _root ); std::vector<sat::Solvable> successfullyInstalledPackages; TargetImpl::PoolItemList remaining;
