libzypp  17.16.0
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 
19 using std::endl;
20 
22 namespace 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;
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 
171  IMPL_PTR_TYPE(Pattern);
172 
173  Pattern::Pattern( const sat::Solvable & solvable_r )
174  : ResObject( solvable_r )
175  {}
176 
178  {}
179 
180  bool Pattern::isDefault() const
182 
183  bool Pattern::userVisible() const
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
bool isAutoPattern() const
This patterns is auto-defined by a patterns- package.
Definition: Pattern.cc:204
Contents sug
suggested content set
Definition: Pattern.h:105
A Solvable object within the sat Pool.
Definition: Solvable.h:53
Container of Solvable providing a Capability (read only).
Definition: WhatProvides.h:87
static const Dep RECOMMENDS
Definition: Dep.h:47
static const SolvAttr order
Definition: SolvAttr.h:132
Iterable< byIdent_iterator > byIdent(const ByIdent &ident_r) const
Definition: ResPool.h:228
static const SolvAttr isvisible
Definition: SolvAttr.h:130
static const SolvAttr isdefault
Definition: SolvAttr.h:133
Container of Capability (currently read only).
Definition: Capabilities.h:35
Edition ed() const
Definition: Capability.h:347
sat::ArrayAttr< IdString, IdString > NameList
Definition: Pattern.h:40
Enumeration class of dependency types.
Definition: Dep.h:29
intrusive_ptr< Selectable > Ptr
Definition: Selectable.h:57
static const Rel EQ
Definition: Rel.h:50
Pathname script() const
Definition: Pattern.cc:198
std::string order() const
Definition: Pattern.cc:201
Access to the sat-pools string space.
Definition: IdString.h:41
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
Contents depends(bool includeSuggests_r=true) const
Ui hint: Dependent packages.
Definition: Pattern.cc:258
LookupAttr::TransformIterator based container to retrieve list attributes.
Definition: LookupAttr.h:592
Contents core() const
Ui hint: Required Packages.
Definition: Pattern.cc:240
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
Contents rec
recommended content set
Definition: Pattern.h:104
static const SolvAttr icon
Definition: SolvAttr.h:131
static const Dep SUGGESTS
Definition: Dep.h:48
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
bool isDefault() const
Definition: Pattern.cc:180
constexpr bool empty() const
Whether the string is empty.
Definition: IdString.h:80
std::string asString() const
Definition: IdStringType.h:106
sat::SolvableSet Contents
Definition: Pattern.h:41
Package interface.
Definition: Package.h:32
IMPL_PTR_TYPE(Application)
static const SolvAttr category
Definition: SolvAttr.h:134
NameList includes() const
Ui hint: included patterns.
Definition: Pattern.cc:220
static const Dep REQUIRES
Definition: Dep.h:44
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
Base for resolvable objects.
Definition: ResObject.h:37
sat::Solvable autoPackage() const
The corresponding patterns- package if isAutoPattern.
Definition: Pattern.cc:207
TraitsType::constPtrType constPtr
Definition: Pattern.h:37
Container & get()
The set.
Definition: SolvableSet.h:98
bool userVisible() const
Definition: Pattern.cc:183
NameList extends() const
Ui hint: patterns this one extends.
Definition: Pattern.cc:223
SolvableIdType size_type
Definition: PoolMember.h:126
static const SolvAttr includes
Definition: SolvAttr.h:136
'Language[_Country]' codes.
Definition: Locale.h:49
transform_iterator< GetPairFirst< typename MapType::value_type >, typename MapType::const_iterator > Key_const_iterator
The key iterator type.
Definition: Iterator.h:218
std::unordered_set< Capability > CapabilitySet
Definition: Capability.h:33
virtual ~Pattern()
Dtor.
Definition: Pattern.cc:177
Pattern(const sat::Solvable &solvable_r)
Ctor.
Definition: Pattern.cc:173
A sat capability.
Definition: Capability.h:59
void contentsSet(ContentsSet &collect_r, bool recursively_r=false) const
Dependency based content set (does not evaluate includes/extends relation).
Definition: Pattern.cc:332
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:50
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
Contents req
required content set
Definition: Pattern.h:103
static const CapMatch yes
Definition: CapMatch.h:51
PatternMap _patternMap
Definition: Pattern.cc:162
CapDetail detail() const
Helper providing more detailed information about a Capability.
Definition: Capability.h:379
bool lookupBoolAttribute(const SolvAttr &attr) const
Definition: SolvableType.h:136
std::string lookupStrAttribute(const SolvAttr &attr) const
Definition: SolvableType.h:134
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
static const SolvAttr extends
Definition: SolvAttr.h:137
std::string category(const Locale &lang_r=Locale()) const
Definition: Pattern.cc:192
Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition: SolvableType.h:57
Contents contents(bool includeSuggests_r=true) const
The collection of packages associated with this pattern.
Definition: Pattern.cc:284
static const SolvAttr script
Definition: SolvAttr.h:135
bool insert(const TSolv &solv_r)
Insert a Solvable.
Definition: SolvableSet.h:88
static ResPool instance()
Singleton ctor.
Definition: ResPool.cc:33
Solvable set wrapper to allow adding additional convenience iterators.
Definition: SolvableSet.h:35
Pathname icon() const
Definition: Pattern.cc:195