1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
10 * \file zypp/ui/UserWantedPackages.cc
12 * \author Stefan Hundhammer <sh@suse.de>
16 #include "zypp/base/Logger.h"
18 #include "zypp/ui/UserWantedPackages.h"
20 #include "zypp/base/PtrTypes.h"
21 #include "zypp/ui/Selectable.h"
22 #include "zypp/ResObject.h"
23 #include "zypp/Package.h"
24 #include "zypp/Selection.h"
25 #include "zypp/Pattern.h"
26 #include "zypp/Language.h"
27 #include "zypp/Patch.h"
28 #include "zypp/ZYppFactory.h"
29 #include "zypp/ResPoolProxy.h"
41 typedef ResPoolProxy::const_iterator PoolProxyIterator;
43 static inline ResPoolProxy poolProxy() { return getZYpp()->poolProxy(); }
45 template<class T> PoolProxyIterator poolProxyBegin() { return poolProxy().byKindBegin<T>(); }
46 template<class T> PoolProxyIterator poolProxyEnd() { return poolProxy().byKindEnd<T>(); }
48 static inline PoolProxyIterator pkgBegin() { return poolProxyBegin<Package>(); }
49 static inline PoolProxyIterator pkgEnd() { return poolProxyEnd<Package>(); }
51 static inline PoolProxyIterator langBegin() { return poolProxyBegin<Language>(); }
52 static inline PoolProxyIterator langEnd() { return poolProxyEnd<Language>(); }
54 static inline PoolProxyIterator patchesBegin() { return poolProxyBegin<Patch>(); }
55 static inline PoolProxyIterator patchesEnd() { return poolProxyEnd<Patch>(); }
57 template<typename T> bool contains( const std::set<T> & container, T search )
59 return container.find( search ) != container.end();
64 static void addDirectlySelectedPackages ( set<string> & pkgNames );
65 template<class PkgSet_T> void addPkgSetPackages( set<string> & pkgNames );
67 static void addSelectionPackages ( set<string> & pkgNames );
68 static void addPatternPackages ( set<string> & pkgNames );
69 static void addLanguagePackages ( set<string> & pkgNames );
70 static void addPatchPackages ( set<string> & pkgNames );
74 set<string> userWantedPackageNames()
78 DBG << "Collecting packages the user explicitly asked for" << endl;
80 addDirectlySelectedPackages ( pkgNames );
81 addSelectionPackages ( pkgNames );
82 addPatternPackages ( pkgNames );
83 addLanguagePackages ( pkgNames );
84 addPatchPackages ( pkgNames );
91 static void addDirectlySelectedPackages( set<string> & pkgNames )
93 for ( PoolProxyIterator it = pkgBegin();
97 // Add all packages the user wanted to transact directly,
98 // no matter what the transaction is (install, update, delete)
100 if ( (*it)->toModify() && (*it)->modifiedBy() == ResStatus::USER )
102 DBG << "Explicit user transaction on pkg \"" << (*it)->name() << "\"" << endl;
104 pkgNames.insert( (*it)->name() );
111 static void addSelectionPackages( set<string> & pkgNames )
113 addPkgSetPackages<Selection>( pkgNames );
117 static void addPatternPackages( set<string> & pkgNames )
119 addPkgSetPackages<Pattern>( pkgNames );
124 * Template to handle Selections and Patterns
126 template<class PkgSet_T> void addPkgSetPackages( set<string> & pkgNames )
128 for ( PoolProxyIterator it = poolProxyBegin<PkgSet_T>();
129 it != poolProxyEnd<PkgSet_T>();
132 // Take all pkg sets (selections or patterns) into account that
133 // will be transacted, no matter if the user explicitly asked
134 // for that pkg set or if the selection is required by another
135 // pkg set of the same class
137 typename PkgSet_T::constPtr pkgSet = dynamic_pointer_cast<const PkgSet_T>( (*it)->theObj() );
139 if ( pkgSet && (*it)->toModify() )
141 DBG << (*it)->theObj()->kind().asString()
142 << " will be transacted: \"" << pkgSet->name() << "\"" << endl;
144 set<string> setPkgs = pkgSet->install_packages();
145 pkgNames.insert( setPkgs.begin(), setPkgs.end() );
152 static void addLanguagePackages( set<string> & pkgNames )
154 // Build a set of all languages that are to be transacted
156 set<string> wantedLanguages;
158 for ( PoolProxyIterator lang_it = langBegin();
159 lang_it != langEnd();
162 if ( (*lang_it)->toModify() )
164 DBG << "Language will be transacted: \"" << (*lang_it)->name() << "\"" << endl;
166 wantedLanguages.insert( (*lang_it)->name() );
171 // Check all packages if they support any of the wanted languages
173 for ( PoolProxyIterator pkg_it = pkgBegin();
177 ResObject::constPtr obj = (*pkg_it)->theObj();
181 CapSet freshens = obj->dep( Dep::FRESHENS );
183 for ( CapSet::const_iterator cap_it = freshens.begin();
184 cap_it != freshens.end();
187 if ( contains( wantedLanguages, (*cap_it).index() ) )
188 pkgNames.insert( obj->name() );
196 static void addPatchPackages( set<string> & pkgNames )
198 for ( PoolProxyIterator patch_it = patchesBegin();
199 patch_it != patchesEnd();
202 Patch::constPtr patch = dynamic_pointer_cast<const Patch>( (*patch_it)->theObj() );
204 if ( patch && (*patch_it)->toModify() )
206 DBG << "Patch will be transacted: \"" << patch->name()
207 << "\" - \"" << patch->summary() << "\"" << endl;
209 Patch::AtomList atomList = patch->atoms();
211 for ( Patch::AtomList::iterator atom_it = atomList.begin();
212 atom_it != atomList.end();
215 pkgNames.insert( (*atom_it)->name() );