libzypp 17.31.23
Pattern.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <zypp/base/LogTools.h>
14
15#include <zypp/ResPool.h>
16#include <zypp/Pattern.h>
17#include <zypp/Filter.h>
18
19using std::endl;
20
22namespace zypp
23{
25 namespace
26 {
27 inline Capability autoCapability( const Capabilities & provides_r )
28 {
29 static const Capability autopattern( "autopattern()" );
30 for ( const auto & cap : provides_r )
31 if ( cap.matches( autopattern ) == CapMatch::yes )
32 return cap;
33 return Capability();
34 }
35
37 //
38 // CLASS NAME : PatternExpander
39 //
46 class PatternExpander
47 {
48 public:
49 typedef std::map<Pattern::constPtr, DefaultIntegral<bool, false> > PatternMap;
50 typedef PatternMap::size_type size_type;
51 typedef PatternMap::key_type value_type;
53
54 public:
55 PatternExpander()
56 {}
57
59 size_type doExpand( Pattern::constPtr pat_r )
60 {
61 // INT << "+++ " << pat_r << " ++++++++++++++++++++++++++++++++++" << endl;
62 _patternMap.clear();
63 if ( pat_r )
64 {
65 _patternMap[pat_r];
66 Pattern::constPtr unprocessed( pat_r );
67 // MIL << _patternMap << endl;
68 do {
69 expandIncludes( unprocessed );
70 expandExtending( unprocessed );
71 _patternMap[unprocessed] = true;
72 // MIL << _patternMap << endl;
73 } while( (unprocessed = nextUnprocessed()) );
74 }
75 // SEC << "--- " << _patternMap.size() << " ----------------------------------" << endl;
76 return _patternMap.size();
77 }
78
79 const_iterator begin() const
80 { return make_map_key_begin( _patternMap ); }
81
82 const_iterator end() const
83 { return make_map_key_end( _patternMap ); }
84
85 private:
87 Pattern::constPtr nextUnprocessed() const
88 {
89 for_( it, _patternMap.begin(), _patternMap.end() )
90 {
91 if ( ! it->second )
92 return it->first;
93 }
94 return NULL;
95 }
96
97 private:
99 void expandIncludes( const Pattern::constPtr & pat_r )
100 {
101 Pattern::NameList c( pat_r->includes() );
102 for_( it, c.begin(), c.end() )
103 {
104 expandInclude( Capability( it->c_str()/*, *ResKind::pattern*/ ) );
105 }
106 }
107
109 void expandInclude( const Capability & include_r )
110 {
111 sat::WhatProvides w( include_r );
112 for_( it, w.begin(), w.end() )
113 {
114 _patternMap[asKind<Pattern>(PoolItem(*it))];
115 }
116 }
117
118 private:
120 void expandExtending( const Pattern::constPtr & pat_r )
121 {
122 ResPool pool( ResPool::instance() );
123 for_( it, pool.byKindBegin<Pattern>(), pool.byKindEnd<Pattern>() )
124 {
125 expandIfExtends( pat_r, *it );
126 }
127 }
128
130 void expandIfExtends( const Pattern::constPtr & pat_r, const PoolItem & extending_r )
131 {
132 Pattern::constPtr extending( asKind<Pattern>(extending_r) );
133 Pattern::NameList c( extending->extends() );
134 for_( it, c.begin(), c.end() )
135 {
136 if ( providedBy( pat_r, Capability( it->c_str()/*, *ResKind::pattern*/ ) ) )
137 {
138 // an extends matches the Pattern
139 _patternMap[extending];
140 break;
141 }
142 }
143 }
144
146 bool providedBy( const Pattern::constPtr & pat_r, const Capability & extends_r )
147 {
148 if ( !pat_r )
149 return false;
150
151 sat::Solvable pat( pat_r->satSolvable() );
152 sat::WhatProvides w( extends_r );
153 for_( it, w.begin(), w.end() )
154 {
155 if ( pat == *it )
156 return true;
157 }
158 return false;
159 }
160
161 private:
162 PatternMap _patternMap;
163 };
164 } // namespace
166
168 // Pattern
170
172
173 Pattern::Pattern( const sat::Solvable & solvable_r )
174 : ResObject( solvable_r )
175 {}
176
178 {}
179
182
184 {
185 // bsc#900769: If visibility is a string(solvable ident) the pattern
186 // is visible IFF ident is available in the pool.
189 : ! ResPool::instance().byIdent( ident ).empty() );
190 }
191
192 std::string Pattern::category( const Locale & lang_r ) const
193 { return lookupStrAttribute( sat::SolvAttr::category, lang_r ); }
194
197
200
201 std::string Pattern::order() const
203
205 { return bool(autoCapability( provides() )); }
206
208 {
209 Capability autocap( autoCapability( provides() ) );
210 if ( autocap )
211 {
212 Capability pkgCap( arch(), autocap.detail().ed().asString(), Rel::EQ, edition() );
213 for ( const auto & solv: sat::WhatProvides( pkgCap ) )
214 if ( solv.repository() == repository() )
215 return solv;
216 }
217 return sat::Solvable();
218 }
219
222
225
227 namespace
228 {
229 inline void addCaps( CapabilitySet & caps_r, sat::Solvable solv_r, Dep dep_r )
230 {
231 Capabilities c( solv_r[dep_r] );
232 if ( ! c.empty() )
233 {
234 caps_r.insert( c.begin(),c.end() );
235 }
236 }
237 } //namespace
239
241 {
242 // Content dependencies are either associated with
243 // the autoPackage or the (oldstype) pattern itself.
244 // load requires
245 CapabilitySet caps;
246 addCaps( caps, *this, Dep::REQUIRES );
247
248 sat::Solvable depKeeper( autoPackage() );
249 if ( depKeeper )
250 addCaps( caps, depKeeper, Dep::REQUIRES );
251 // get items providing the requirements
252 sat::WhatProvides prv( caps );
253 // return packages only.
254 return Pattern::Contents( make_filter_begin( filter::byKind<Package>(), prv ),
255 make_filter_end( filter::byKind<Package>(), prv ) );
256 }
257
258 Pattern::Contents Pattern::depends( bool includeSuggests_r ) const
259 {
260 // Content dependencies are either associated with
261 // the autoPackage or the (oldstype) pattern itself.
262 // load requires, recommends[, suggests]
263 CapabilitySet caps;
264 addCaps( caps, *this, Dep::REQUIRES );
265 addCaps( caps, *this, Dep::RECOMMENDS );
266 if ( includeSuggests_r )
267 addCaps( caps, *this, Dep::SUGGESTS );
268
269 sat::Solvable depKeeper( autoPackage() );
270 if ( depKeeper )
271 {
272 addCaps( caps, depKeeper, Dep::REQUIRES );
273 addCaps( caps, depKeeper, Dep::RECOMMENDS );
274 if ( includeSuggests_r )
275 addCaps( caps, depKeeper, Dep::SUGGESTS );
276 }
277 // get items providing the above
278 sat::WhatProvides prv( caps );
279 // return packages only.
280 return Pattern::Contents( make_filter_begin( filter::byKind<Package>(), prv ),
281 make_filter_end( filter::byKind<Package>(), prv ) );
282 }
283
284 Pattern::Contents Pattern::contents( bool includeSuggests_r ) const
285 {
286 PatternExpander expander;
287 if ( ! expander.doExpand( this ) )
288 return Contents(); // empty pattern set
289
290 Contents result;
291 for_( it, expander.begin(), expander.end() )
292 {
293 Contents c( (*it)->depends( includeSuggests_r ) );
294 result.get().insert( c.begin(), c.end() );
295 }
296 return result;
297 }
298
300 namespace
301 {
302 // Get packages referenced by depKeeper dependency.
303 inline void dependsSetDoCollect( sat::Solvable depKeeper_r, Dep dep_r, Pattern::Contents & set_r )
304 {
305 CapabilitySet caps;
306 addCaps( caps, depKeeper_r, dep_r );
307 sat::WhatProvides prv( caps );
308 for ( ui::Selectable::Ptr sel : prv.selectable() )
309 {
310 const PoolItem & pi( sel->theObj() );
311 if ( pi.isKind<Package>() )
312 set_r.insert( pi );
313 }
314 }
315
316 // Get packages referenced by depKeeper.
317 inline void dependsSet( sat::Solvable depKeeper_r, Pattern::ContentsSet & collect_r )
318 {
319 dependsSetDoCollect( depKeeper_r, Dep::REQUIRES, collect_r.req );
320 dependsSetDoCollect( depKeeper_r, Dep::RECOMMENDS, collect_r.rec ),
321 dependsSetDoCollect( depKeeper_r, Dep::SUGGESTS, collect_r.sug );
322 }
323
324 // Whether this is a patterns depkeeper.
325 inline bool isPatternsPackage( sat::Solvable depKeeper_r )
326 {
327 static const Capability indicator( "pattern()" );
328 return depKeeper_r.provides().matches( indicator );
329 }
330 } // namespace
332 void Pattern::contentsSet( ContentsSet & collect_r, bool recursively_r ) const
333 {
334 sat::Solvable depKeeper( autoPackage() ); // (my required) patterns-package
335 if ( ! depKeeper )
336 return;
337
338 // step 2 data
339 std::set<sat::Solvable> recTodo; // recommended patterns-packages to process
340 std::set<sat::Solvable> allDone; // patterns-packages already expanded
341 {
342 // step 1: Expand requirements, remember recommends....
343 // step 1 data (scoped to step1)
344 std::set<sat::Solvable> reqTodo; // required patterns-packages to process
345
346 collect_r.req.insert( depKeeper );// collect the depKeeper
347 reqTodo.insert( depKeeper ); // and expand it...
348
349 while ( ! reqTodo.empty() )
350 {
351 // pop one patterns-package from todo
352 depKeeper = ( *reqTodo.begin() );
353 reqTodo.erase( reqTodo.begin() );
354 allDone.insert( depKeeper );
355
356 // collects stats
357 ContentsSet result;
358 dependsSet( depKeeper, result );
359
360 // evaluate result....
361 for ( sat::Solvable solv : result.req ) // remember unprocessed required patterns-packages...
362 {
363 if ( collect_r.req.insert( solv ) && recursively_r && isPatternsPackage( solv ) )
364 reqTodo.insert( solv );
365 }
366 for ( sat::Solvable solv : result.rec ) // remember unprocessed recommended patterns-packages...
367 {
368 if ( collect_r.rec.insert( solv ) && recursively_r && isPatternsPackage( solv ) )
369 recTodo.insert( solv );
370 }
371 for ( sat::Solvable solv : result.sug ) // NOTE: We don't expand suggested patterns!
372 {
373 collect_r.sug.insert( solv );
374 }
375 }
376 }
377 // step 2: All requirements are expanded, now check remaining recommends....
378 while ( ! recTodo.empty() )
379 {
380 // pop one patterns-package from todo
381 depKeeper = ( *recTodo.begin() );
382 recTodo.erase( recTodo.begin() );
383 if ( ! allDone.insert( depKeeper ).second )
384 continue; // allready expanded (in requires)
385
386 // collects stats
387 ContentsSet result;
388 dependsSet( depKeeper, result );
389
390 // evaluate result....
391 for ( sat::Solvable solv : result.req ) // remember unprocessed required patterns-packages...
392 {
393 // NOTE: Requirements of recommended patterns count as 'recommended'
394 if ( collect_r.rec.insert( solv ) && recursively_r && isPatternsPackage( solv ) )
395 recTodo.insert( solv );
396 }
397 for ( sat::Solvable solv : result.rec ) // remember unprocessed recommended patterns-packages...
398 {
399 if ( collect_r.rec.insert( solv ) && recursively_r && isPatternsPackage( solv ) )
400 recTodo.insert( solv );
401 }
402 for ( sat::Solvable solv : result.sug ) // NOTE: We don't expand suggested patterns!
403 {
404 collect_r.sug.insert( solv );
405 }
406 }
407 }
408
409
411} // namespace zypp
PatternMap _patternMap
Definition: Pattern.cc:162
Edition ed() const
Definition: Capability.h:365
static const CapMatch yes
Definition: CapMatch.h:51
Container of Capability (currently read only).
Definition: Capabilities.h:36
A sat capability.
Definition: Capability.h:63
CapDetail detail() const
Helper providing more detailed information about a Capability.
Definition: Capability.h:397
std::string asString() const
Definition: IdStringType.h:106
Access to the sat-pools string space.
Definition: IdString.h:43
constexpr bool empty() const
Whether the string is empty.
Definition: IdString.h:87
'Language[_Country]' codes.
Definition: Locale.h:50
Package interface.
Definition: Package.h:33
Pattern interface.
Definition: Pattern.h:32
Contents core() const
Ui hint: Required Packages.
Definition: Pattern.cc:240
NameList extends() const
Ui hint: patterns this one extends.
Definition: Pattern.cc:223
sat::SolvableSet Contents
Definition: Pattern.h:41
std::string category(const Locale &lang_r=Locale()) const
Definition: Pattern.cc:192
Contents depends(bool includeSuggests_r=true) const
Ui hint: Dependent packages.
Definition: Pattern.cc:258
virtual ~Pattern()
Dtor.
Definition: Pattern.cc:177
TraitsType::constPtrType constPtr
Definition: Pattern.h:37
Pathname script() const
Definition: Pattern.cc:198
bool isDefault() const
Definition: Pattern.cc:180
Pattern(const sat::Solvable &solvable_r)
Ctor.
Definition: Pattern.cc:173
sat::ArrayAttr< IdString, IdString > NameList
Definition: Pattern.h:40
bool userVisible() const
Definition: Pattern.cc:183
std::string order() const
Definition: Pattern.cc:201
void contentsSet(ContentsSet &collect_r, bool recursively_r=false) const
Dependency based content set (does not evaluate includes/extends relation).
Definition: Pattern.cc:332
sat::Solvable autoPackage() const
The corresponding patterns- package if isAutoPattern.
Definition: Pattern.cc:207
NameList includes() const
Ui hint: included patterns.
Definition: Pattern.cc:220
Contents contents(bool includeSuggests_r=true) const
The collection of packages associated with this pattern.
Definition: Pattern.cc:284
Pathname icon() const
Definition: Pattern.cc:195
bool isAutoPattern() const
This patterns is auto-defined by a patterns- package.
Definition: Pattern.cc:204
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:51
Base for resolvable objects.
Definition: ResObject.h:38
static ResPool instance()
Singleton ctor.
Definition: ResPool.cc:37
LookupAttr::TransformIterator based container to retrieve list attributes.
static const SolvAttr icon
Definition: SolvAttr.h:139
static const SolvAttr isvisible
Definition: SolvAttr.h:138
static const SolvAttr category
Definition: SolvAttr.h:142
static const SolvAttr isdefault
Definition: SolvAttr.h:141
static const SolvAttr extends
Definition: SolvAttr.h:145
static const SolvAttr script
Definition: SolvAttr.h:143
static const SolvAttr order
Definition: SolvAttr.h:140
static const SolvAttr includes
Definition: SolvAttr.h:144
Solvable set wrapper to allow adding additional convenience iterators.
Definition: SolvableSet.h:36
Container & get()
The set.
Definition: SolvableSet.h:98
bool insert(const TSolv &solv_r)
Insert a Solvable.
Definition: SolvableSet.h:88
const_iterator end() const
Iterator pointing behind the last Solvable.
Definition: SolvableSet.h:76
const_iterator begin() const
Iterator pointing to the first Solvable.
Definition: SolvableSet.h:72
A Solvable object within the sat Pool.
Definition: Solvable.h:54
Container of Solvable providing a Capability (read only).
Definition: WhatProvides.h:89
intrusive_ptr< Selectable > Ptr
Definition: Selectable.h:57
SolvableIdType size_type
Definition: PoolMember.h:126
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
std::unordered_set< Capability > CapabilitySet
Definition: Capability.h:35
MapKVIteratorTraits< TMap >::Key_const_iterator make_map_key_begin(const TMap &map_r)
Convenience to create the key iterator from container::begin()
Definition: Iterator.h:228
filter_iterator< TFilter, typename TContainer::const_iterator > make_filter_begin(TFilter f, const TContainer &c)
Convenience to create filter_iterator from container::begin().
Definition: Iterator.h:101
MapKVIteratorTraits< TMap >::Key_const_iterator make_map_key_end(const TMap &map_r)
Convenience to create the key iterator from container::end()
Definition: Iterator.h:233
filter_iterator< TFilter, typename TContainer::const_iterator > make_filter_end(TFilter f, const TContainer &c)
Convenience to create filter_iterator from container::end().
Definition: Iterator.h:117
Enumeration class of dependency types.
Definition: Dep.h:30
static const Dep SUGGESTS
Definition: Dep.h:48
static const Dep REQUIRES
Definition: Dep.h:44
static const Dep RECOMMENDS
Definition: Dep.h:47
transform_iterator< GetPairFirst< typename MapType::value_type >, typename MapType::const_iterator > Key_const_iterator
The key iterator type.
Definition: Iterator.h:218
Contents req
required content set
Definition: Pattern.h:103
Contents sug
suggested content set
Definition: Pattern.h:105
Contents rec
recommended content set
Definition: Pattern.h:104
static const Rel EQ
Definition: Rel.h:50
bool lookupBoolAttribute(const SolvAttr &attr) const
Definition: SolvableType.h:142
std::string lookupStrAttribute(const SolvAttr &attr) const
Definition: SolvableType.h:140
Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition: SolvableType.h:57
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
#define IMPL_PTR_TYPE(NAME)