From: DongHun Kwak Date: Mon, 2 Sep 2019 07:18:53 +0000 (+0900) Subject: Imported Upstream version 17.10.3 X-Git-Tag: upstream/17.10.3^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=140f84c17380c7f447ee14212851157af9fe9dd3;p=platform%2Fupstream%2Flibzypp.git Imported Upstream version 17.10.3 --- diff --git a/VERSION.cmake b/VERSION.cmake index fb94ca5..c229567 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -61,8 +61,8 @@ SET(LIBZYPP_MAJOR "17") SET(LIBZYPP_COMPATMINOR "9") SET(LIBZYPP_MINOR "10") -SET(LIBZYPP_PATCH "2") +SET(LIBZYPP_PATCH "3") # -# LAST RELEASED: 17.10.2 (9) +# LAST RELEASED: 17.10.3 (9) # (The number in parenthesis is LIBZYPP_COMPATMINOR) #======= diff --git a/package/libzypp.changes b/package/libzypp.changes index 24831b1..08af145 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Tue Dec 18 14:01:19 CET 2018 - ma@suse.de + +- Simplify complex locks so zypper can display them (bsc#1112911) +- version 17.10.3 (9) + +------------------------------------------------------------------- Mon Dec 10 16:57:34 CET 2018 - ma@suse.de - commit: set `SYSTEMD_OFFLINE=1` during chrooted commits (bsc#1118758) diff --git a/tests/zypp/PoolQuery_test.cc b/tests/zypp/PoolQuery_test.cc index 94f53ef..b814e8d 100644 --- a/tests/zypp/PoolQuery_test.cc +++ b/tests/zypp/PoolQuery_test.cc @@ -870,4 +870,116 @@ BOOST_AUTO_TEST_CASE(addDependency) } } +namespace +{ + std::string q2str( const PoolQuery & q_r ) + { + str::Str s; + q_r.serialize( s.stream() ); + return s; + } + + template + void str2q( const std::string & s_r, OutputIterator out_r ) + { + std::istringstream s( s_r ); + do { + PoolQuery q; + if ( q.recover( s ) ) + *out_r++ = std::move(q); + else + break; + } while ( true ); + } + + typedef std::set Pqs; + + PoolQuery str2q( const std::string & s_r ) + { + Pqs ret; + str2q( s_r, std::insert_iterator( ret, ret.end() ) ); + return *ret.begin(); + } + + + std::string serialized( const std::string & arg_r ) + { return "\n" + arg_r + "\n\n"; } + + template + std::string serialized( const std::string & arg_r, Args... args_r ) + { return "\n" + arg_r + serialized( args_r... ); } + + + void testSerializeAndBack( const PoolQuery & q_r, const PoolQuery & expect_r, bool equal_r = true ) + { + static unsigned i = 0; + + std::string s { q2str( q_r ) }; + PoolQuery q { str2q( s ) }; + BOOST_CHECK_EQUAL( (q == expect_r), equal_r ); + + if ( ++i && (q == expect_r) != equal_r ) + { + cout << "+++" << endl; + cout << q << endl; + cout << "=== " << i << " ^v SerializeAndBack == " << equal_r << endl; + cout << expect_r << endl; + cout << "---" << endl; + } + } +} + +BOOST_AUTO_TEST_CASE(zypperLocksSerialize) +{ + // Fix/cleanup zypper locks (old style, new stule, complex) (bsc#1112911) + // As you may notice: locks (by now) ignore any arch component + cout << "****zypperLocksSerialize****" << endl; + std::string n { "n*" }; + Rel o { Rel::EQ }; + Edition e { "v", "r", 1 }; + Arch a { "a" }; + + { + // old style + // solvable_name: n* + PoolQuery oldq; + oldq.addAttribute( sat::SolvAttr::name, n ); + testSerializeAndBack( oldq, oldq ); + + { // new style + PoolQuery q; + q.addDependency( sat::SolvAttr::name, n, Rel::ANY, Edition(), Arch_empty ); + testSerializeAndBack( q, oldq ); + } + { // new style + arch rule however stays complex + PoolQuery q; + q.addDependency( sat::SolvAttr::name, n, Rel::ANY, Edition(), a ); + testSerializeAndBack( q, oldq, false ); + testSerializeAndBack( q, q ); + } + } + + { + // old style + // solvable_name: n* + // version: == 1:v-r + PoolQuery oldq; + oldq.addAttribute( sat::SolvAttr::name, n ); + oldq.setEdition( e, o ); + testSerializeAndBack( oldq, oldq ); + + { // new style + PoolQuery q; + q.addDependency( sat::SolvAttr::name, n, o, e, Arch_empty ); + testSerializeAndBack( q, oldq ); + } + + { // new style + arch rule however stays complex + PoolQuery q; + q.addDependency( sat::SolvAttr::name, n, o, e, a ); + testSerializeAndBack( q, oldq, false ); + testSerializeAndBack( q, q ); + } + } +} diff --git a/zypp/PoolQuery.cc b/zypp/PoolQuery.cc index 0ebb9fc..ca234b6 100644 --- a/zypp/PoolQuery.cc +++ b/zypp/PoolQuery.cc @@ -1302,6 +1302,70 @@ namespace zypp } while ( true ); + // OLD STYLE VERSIONED LOCKS: + // solvable_name: kernel + // version: > 1 + // + // NEW STYLE VERSIONED LOCKS: + // complex: AttrMatchData solvable:name kernel C SolvableRange\ >\ 1\ \"\" + // or + // solvable_name: kernel > 1 + // + // Semantically equivalent as locks, but due to the different syntax + // the complex lock is wrongly handled by zypper. + // + // bsc#1112911: Unfortunately all styles are found in real-life locks-files. + // libzypp will try to make sure, when parsing the locks-file, that complex + // locks are rewritten into to OLD STYLE queries zypper can handle. + if ( !_pimpl->_attrs.count(SolvAttr::name) && _pimpl->_uncompiledPredicated.size() == 1 ) + { + // No OLD STYLE lock for SolvAttr::name and exactly one complex lock... + const AttrMatchData & attrmatch { *_pimpl->_uncompiledPredicated.begin() }; + if ( attrmatch.attr == SolvAttr::name && attrmatch.strMatcher.flags().mode() == Match::OTHER ) + { + // ...for SolvAttr::name and following the global search flags. + // A candidate for a rewrite? + + std::vector words; + str::splitEscaped( attrmatch.predicateStr, std::back_inserter(words) ); + if ( words.size() < 4 || words[3].empty() ) + { + // We have _NO_ arch rule in the complex predicate, so we can simplify it. + // + // NOTE: AFAIK it's not possible to create (or have created) a complex lock + // with arch rule with zypper means. Nevertheless, in case such a rule made it + // into a locks file, it's better to have a strange looking 'zypper locks' list + // than to lock the wrong packages. + // (and remember that you can't use "addAttribute( SolvAttr::arch, ... )" because + // attributes are `OR`ed) + + // kind + if ( attrmatch.kindPredicate ) + { + _pimpl->_kinds.clear(); // an explicit kind overwrites any global one + addKind( attrmatch.kindPredicate ); + } + + // name + addAttribute( SolvAttr::name, attrmatch.strMatcher.searchstring() ); + + // edition + std::vector words; + str::splitEscaped( attrmatch.predicateStr, std::back_inserter(words) ); + if ( ! words.empty() ) + { + if ( words[0] == "EditionRange" || words[0] == "SolvableRange" ) + { + setEdition( Edition(words[2]), Rel(words[1]) ); + } + } + + // finally remove the complex lock + _pimpl->_uncompiledPredicated.clear(); + } + } + } + return finded_something; }