libzypp
10.5.0
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include "zypp/base/LogTools.h" 00014 00015 #include "zypp/Product.h" 00016 #include "zypp/Url.h" 00017 00018 #include "zypp/sat/LookupAttr.h" 00019 #include "zypp/sat/WhatProvides.h" 00020 #include "zypp/sat/WhatObsoletes.h" 00021 #include "zypp/PoolItem.h" 00022 00023 using std::endl; 00024 00026 namespace zypp 00027 { 00028 00029 IMPL_PTR_TYPE(Product); 00030 00031 namespace 00032 { 00033 void fillList( std::list<Url> & ret_r, sat::Solvable solv_r, sat::SolvAttr attr_r ) 00034 { 00035 sat::LookupAttr query( attr_r, solv_r ); 00036 for_( it, query.begin(), query.end() ) 00037 { 00038 try // ignore malformed urls 00039 { 00040 ret_r.push_back( Url( it.asString() ) ); 00041 } 00042 catch( const url::UrlException & ) 00043 {} 00044 } 00045 } 00046 00047 void fillList( std::list<std::string> & ret_r, sat::Solvable solv_r, sat::SolvAttr attr_r ) 00048 { 00049 sat::LookupAttr query( attr_r, solv_r ); 00050 for_( it, query.begin(), query.end() ) 00051 { 00052 ret_r.push_back( it.asString() ); 00053 } 00054 } 00055 } 00056 00058 // 00059 // METHOD NAME : Product::Product 00060 // METHOD TYPE : Ctor 00061 // 00062 Product::Product( const sat::Solvable & solvable_r ) 00063 : ResObject( solvable_r ) 00064 {} 00065 00067 // 00068 // METHOD NAME : Product::~Product 00069 // METHOD TYPE : Dtor 00070 // 00071 Product::~Product() 00072 {} 00073 00075 00076 sat::Solvable Product::referencePackage() const 00077 { 00078 // Look for a provider of 'product(name) = version' of same 00079 // architecture and within the same repo. 00080 // 00081 // bnc #497696: Update repos may have multiple release package versions 00082 // providing the same product. As a workaround we link to the one with 00083 // the highest version. 00084 Capability identCap( str::form( "product(%s) = %s", name().c_str(), edition().c_str() ) ); 00085 00086 sat::Solvable found; 00087 sat::WhatProvides providers( identCap ); 00088 for_( it, providers.begin(), providers.end() ) 00089 { 00090 if ( it->repository() == repository() 00091 && it->arch() == arch() ) 00092 { 00093 if ( ! found || found.edition() < it->edition() ) 00094 found = *it; 00095 } 00096 } 00097 if ( ! found ) 00098 WAR << *this << ": no reference package found: " << identCap << endl; 00099 return found; 00100 } 00101 00102 std::string Product::referenceFilename() const 00103 { return lookupStrAttribute( sat::SolvAttr::productReferenceFile ); } 00104 00105 Product::ReplacedProducts Product::replacedProducts() const 00106 { 00107 std::vector<constPtr> ret; 00108 // By now we simply collect what is obsoleted by the Product, 00109 // or by the products buddy (release-package). 00110 00111 // Check our own dependencies. We should not have any, 00112 // but just to be shure. 00113 sat::WhatObsoletes obsoleting( satSolvable() ); 00114 for_( it, obsoleting.begin(), obsoleting.end() ) 00115 { 00116 if ( it->isKind( ResKind::product ) ) 00117 ret.push_back( make<Product>( *it ) ); 00118 } 00119 00120 // If we have a buddy, we check what product buddies the 00121 // buddy replaces. 00122 obsoleting = sat::WhatObsoletes( poolItem().buddy() ); 00123 for_( it, obsoleting.poolItemBegin(), obsoleting.poolItemEnd() ) 00124 { 00125 if ( (*it).buddy().isKind( ResKind::product ) ) 00126 ret.push_back( make<Product>( (*it).buddy() ) ); 00127 } 00128 return ret; 00129 } 00130 00131 CapabilitySet Product::droplist() const 00132 { return poolItem().buddy().valuesOfNamespace( "weakremover" ); } 00133 00134 std::string Product::productLine() const 00135 { return lookupStrAttribute( sat::SolvAttr::productProductLine ); } 00136 00138 00139 std::string Product::shortName() const 00140 { return lookupStrAttribute( sat::SolvAttr::productShortlabel ); } 00141 00142 std::string Product::flavor() const 00143 { 00144 // Look for a provider of 'product_flavor(name) = version' 00145 // within the same repo. Unlike the reference package, we 00146 // can be relaxed and ignore the architecture. 00147 Capability identCap( str::form( "product_flavor(%s) = %s", name().c_str(), edition().c_str() ) ); 00148 00149 sat::WhatProvides providers( identCap ); 00150 for_( it, providers.begin(), providers.end() ) 00151 { 00152 if ( it->repository() == repository() ) 00153 { 00154 // Got the package now try to get the provided 'flavor(...)' 00155 Capabilities provides( it->provides() ); 00156 for_( cap, provides.begin(), provides.end() ) 00157 { 00158 std::string capstr( cap->asString() ); 00159 if ( str::hasPrefix( capstr, "flavor(" ) ) 00160 { 00161 capstr = str::stripPrefix( capstr, "flavor(" ); 00162 capstr.erase( capstr.size()-1 ); // trailing ')' 00163 return capstr; 00164 } 00165 } 00166 } 00167 } 00168 return std::string(); 00169 } 00170 00171 std::string Product::type() const 00172 { return lookupStrAttribute( sat::SolvAttr::productType ); } 00173 00174 std::list<std::string> Product::flags() const 00175 { 00176 std::list<std::string> ret; 00177 fillList( ret, satSolvable(), sat::SolvAttr::productFlags ); 00178 return ret; 00179 } 00180 00181 bool Product::isTargetDistribution() const 00182 { return isSystem() && lookupStrAttribute( sat::SolvAttr::productType ) == "base"; } 00183 00184 std::string Product::registerTarget() const 00185 { return lookupStrAttribute( sat::SolvAttr::productRegisterTarget ); } 00186 00187 std::string Product::registerRelease() const 00188 { return lookupStrAttribute( sat::SolvAttr::productRegisterRelease ); } 00189 00191 00192 Product::UrlList Product::urls( const std::string & key_r ) const 00193 { 00194 UrlList ret; 00195 00196 sat::LookupAttr url( sat::SolvAttr::productUrl, *this ); 00197 sat::LookupAttr url_type( sat::SolvAttr::productUrlType, *this ); 00198 00199 sat::LookupAttr::iterator url_it(url.begin()); 00200 sat::LookupAttr::iterator url_type_it(url_type.begin()); 00201 00202 for (;url_it != url.end(); ++url_it, ++url_type_it) 00203 { 00204 /* safety checks, shouldn't happen (tm) */ 00205 if (url_type_it == url_type.end()) 00206 { 00207 ERR << *this << " : The thing that should not happen, happened." << endl; 00208 break; 00209 } 00210 00211 if ( url_type_it.asString() == key_r ) 00212 { 00213 ret._list.push_back(url_it.asString()); 00214 } 00215 } /* while (attribute array) */ 00216 00217 return ret; 00218 } 00219 00220 Product::UrlList Product::releaseNotesUrls() const { return urls( "releasenotes" ); } 00221 Product::UrlList Product::registerUrls() const { return urls( "register" ); } 00222 Product::UrlList Product::smoltUrls() const { return urls( "smolt" ); } 00223 Product::UrlList Product::updateUrls() const { return urls( "update" ); } 00224 Product::UrlList Product::extraUrls() const { return urls( "extra" ); } 00225 Product::UrlList Product::optionalUrls() const { return urls( "optional" ); } 00226 00227 std::ostream & operator<<( std::ostream & str, const Product::UrlList & obj ) 00228 { return dumpRange( str << obj.key() << ' ', obj.begin(), obj.end() ); } 00229 00231 } // namespace zypp