28f80292f02f9f61609bc63dd8d6f09d80f9617b
[platform/upstream/libzypp.git] / devel / devel.ma / Parse.cc
1 #include <ctime>
2
3 #include <iostream>
4 #include <list>
5 #include <map>
6 #include <set>
7
8 #include "Measure.h"
9 #include "Printing.h"
10 #include "Tools.h"
11
12 #include <zypp/Digest.h>
13 #include <zypp/KeyRing.h>
14
15 #include <zypp/base/Logger.h>
16 #include <zypp/base/LogControl.h>
17 #include <zypp/base/String.h>
18 #include <zypp/base/Exception.h>
19 #include <zypp/base/PtrTypes.h>
20 #include <zypp/base/Iterator.h>
21 #include <zypp/base/Algorithm.h>
22 #include <zypp/base/Functional.h>
23 #include <zypp/base/ProvideNumericId.h>
24 #include <zypp/base/ProvideNumericId.h>
25
26 #include "zypp/NVRAD.h"
27 #include "zypp/ResPool.h"
28 #include "zypp/ResFilters.h"
29 #include "zypp/CapFilters.h"
30 #include "zypp/Package.h"
31 #include "zypp/Language.h"
32 #include "zypp/NameKindProxy.h"
33
34 #include <zypp/SourceManager.h>
35 #include <zypp/SourceFactory.h>
36 #include <zypp/source/susetags/SuseTagsImpl.h>
37
38 #include "zypp/ZYppFactory.h"
39 #include "zypp/ResPoolProxy.h"
40 #include "zypp/ResPoolProxy.h"
41 #include "zypp/target/rpm/RpmDb.h"
42
43 using namespace std;
44 using namespace zypp;
45 using namespace zypp::ui;
46 using namespace zypp::functor;
47
48 ///////////////////////////////////////////////////////////////////
49
50 static const Pathname sysRoot( "/Local/ROOT" );
51 static const Url      instSrc( "dir:/Local/SLES10" );
52 //static const Url      instSrc( "dir:/Local/FACTORY" );
53
54 ///////////////////////////////////////////////////////////////////
55
56 namespace container
57 {
58   template<class _Tp>
59     bool isIn( const std::set<_Tp> & cont, const typename std::set<_Tp>::value_type & val )
60     { return cont.find( val ) != cont.end(); }
61 }
62
63 ///////////////////////////////////////////////////////////////////
64
65 template<class _Condition>
66   struct SetTrue
67   {
68     SetTrue( _Condition cond_r )
69     : _cond( cond_r )
70     {}
71
72     template<class _Tp>
73       bool operator()( _Tp t ) const
74       {
75         _cond( t );
76         return true;
77       }
78
79     _Condition _cond;
80   };
81
82 template<class _Condition>
83   inline SetTrue<_Condition> setTrue_c( _Condition cond_r )
84   {
85     return SetTrue<_Condition>( cond_r );
86   }
87
88 template <class _Iterator, class _Filter, class _Function>
89   inline _Function for_each_if( _Iterator begin_r, _Iterator end_r,
90                                 _Filter filter_r,
91                                 _Function fnc_r )
92   {
93     for ( _Iterator it = begin_r; it != end_r; ++it )
94       {
95         if ( filter_r( *it ) )
96           {
97             fnc_r( *it );
98           }
99       }
100     return fnc_r;
101   }
102
103 struct PrintPoolItem
104 {
105   void operator()( const PoolItem & pi ) const
106   {
107     USR << "S" << pi->source().numericId()
108         << "/M" << mediaId(pi)
109         << " " << pi << endl;
110   }
111   unsigned mediaId( const PoolItem & pi ) const
112   {
113     Package::constPtr pkg( asKind<Package>(pi.resolvable()) );
114     if ( pkg )
115       return pkg->mediaId();
116     return 0;
117   }
118 };
119
120 template <class _Iterator>
121   std::ostream & vdumpPoolStats( std::ostream & str,
122                                  _Iterator begin_r, _Iterator end_r )
123   {
124     pool::PoolStats stats;
125     std::for_each( begin_r, end_r,
126
127                    functor::chain( setTrue_c(PrintPoolItem()),
128                                    setTrue_c(functor::functorRef<void,ResObject::constPtr>(stats)) )
129
130                  );
131     return str << stats;
132   }
133
134 struct PoolItemSelect
135 {
136   void operator()( const PoolItem & pi ) const
137   {
138     if ( pi->source().numericId() == 2 )
139       pi.status().setTransact( true, ResStatus::USER );
140   }
141 };
142
143 ///////////////////////////////////////////////////////////////////
144 typedef std::list<PoolItem> PoolItemList;
145 typedef std::set<PoolItem>  PoolItemSet;
146 #include "zypp/solver/detail/InstallOrder.h"
147 using zypp::solver::detail::InstallOrder;
148 #include "Iorder.h"
149
150 ///////////////////////////////////////////////////////////////////
151 namespace zypp
152 {
153   struct CollectTransacting
154   {
155     typedef std::list<PoolItem> PoolItemList;
156
157     void operator()( const PoolItem & pi )
158     {
159       if ( pi.status().isToBeInstalled() )
160         {
161           _toInstall.insert( pi );
162         }
163       else if ( pi.status().isToBeUninstalled() )
164         {
165           if ( pi.status().isToBeUninstalledDueToObsolete()
166                || pi.status().isToBeUninstalledDueToUpgrade() )
167             _skipToDelete.insert( pi );
168           else
169             _toDelete.insert( pi );
170         }
171     }
172
173     PoolItemSet _toInstall;
174     PoolItemSet _toDelete;
175     PoolItemSet _skipToDelete;
176   };
177
178   std::ostream & operator<<( std::ostream & str, const CollectTransacting & obj )
179   {
180     str << "CollectTransacting:" << endl;
181     dumpPoolStats( str << " toInstall: ",
182                    obj._toInstall.begin(), obj._toInstall.end() ) << endl;
183     dumpPoolStats( str << " toDelete: ",
184                    obj._toDelete.begin(), obj._toDelete.end() ) << endl;
185     dumpPoolStats( str << " skipToDelete: ",
186                    obj._skipToDelete.begin(), obj._skipToDelete.end() ) << endl;
187     return str;
188   }
189 }
190
191 ///////////////////////////////////////////////////////////////////
192 #if 0
193 template<class _InstIterator, class _DelIterator, class _OutputIterator>
194 void strip_obsoleted_to_delete( _InstIterator instBegin_r, _InstIterator instEnd_r,
195                                 _DelIterator  delBegin_r,  _DelIterator  delEnd_r,
196                                 _OutputIterator skip_r )
197   {
198     if ( instBegin_r == instEnd_r
199          || delBegin_r == delEnd_r )
200     return; // ---> nothing to do
201
202     // build obsoletes from inst
203     CapSet obsoletes;
204     for ( /**/; instBegin_r != instEnd_r; ++instBegin_r )
205     {
206       //xxxxx
207       //PoolItem_Ref item( *it );
208       //obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() );
209     }
210   if ( obsoletes.size() == 0 )
211     return; // ---> nothing to do
212
213   // match them... ;(
214   PoolItemList undelayed;
215   // forall applDelete Packages...
216   for ( PoolItemList::iterator it = deleteList_r.begin();
217         it != deleteList_r.end(); ++it )
218     {
219       PoolItem_Ref ipkg( *it );
220       bool delayPkg = false;
221       // ...check whether an obsoletes....
222       for ( CapSet::iterator obs = obsoletes.begin();
223             ! delayPkg && obs != obsoletes.end(); ++obs )
224         {
225           // ...matches anything provided by the package?
226           for ( CapSet::const_iterator prov = ipkg->dep(Dep::PROVIDES).begin();
227                 prov != ipkg->dep(Dep::PROVIDES).end(); ++prov )
228             {
229               if ( obs->matches( *prov ) == CapMatch::yes )
230                 {
231                   // if so, delay package deletion
232                   DBG << "Ignore appl_delete (should be obsoleted): " << ipkg << endl;
233                   delayPkg = true;
234                   ipkg.status().setTransact( false, ResStatus::USER );
235                   break;
236                 }
237             }
238         }
239       if ( ! delayPkg ) {
240         DBG << "undelayed " << ipkg << endl;
241         undelayed.push_back( ipkg );
242       }
243     }
244   // Puhh...
245   deleteList_r.swap( undelayed );
246
247 }
248 #endif
249 ///////////////////////////////////////////////////////////////////
250
251 struct SetTransactValue
252 {
253   SetTransactValue( ResStatus::TransactValue newVal_r, ResStatus::TransactByValue causer_r )
254   : _newVal( newVal_r )
255   , _causer( causer_r )
256   {}
257
258   ResStatus::TransactValue   _newVal;
259   ResStatus::TransactByValue _causer;
260
261   bool operator()( const PoolItem & pi ) const
262   { return pi.status().setTransactValue( _newVal, _causer ); }
263 };
264
265 struct StatusReset : public SetTransactValue
266 {
267   StatusReset()
268   : SetTransactValue( ResStatus::KEEP_STATE, ResStatus::USER )
269   {}
270 };
271
272
273 inline bool keyDef( bool def )
274 { return def; }
275
276 struct DigestReceive : public zypp::callback::ReceiveReport<zypp::DigestReport>
277 {
278   virtual bool askUserToAcceptNoDigest( const zypp::Pathname & file )
279   {
280     bool def = zypp::DigestReport::askUserToAcceptNoDigest( file );
281     SEC << "AcceptNoDigest " << file << " (" << def << ')' << endl;
282     return keyDef( def );
283   }
284 };
285 struct KeyRingReceive : public zypp::callback::ReceiveReport<zypp::KeyRingReport>
286 {
287   virtual bool askUserToTrustKey( const std::string & keyid,
288                                   const std::string & keyname,
289                                   const std::string & keydetails )
290   {
291     bool def = zypp::KeyRingReport::askUserToTrustKey( keyid, keyname, keydetails );
292     SEC << "TrustKey " << keyid << ' ' << keyname << ' ' << keydetails << " (" << def << ')' << endl;
293     return keyDef( def );
294   }
295
296   virtual bool askUserToAcceptUnknownKey( const zypp::Pathname & path,
297                                           const std::string & keyid,
298                                           const std::string & keyname )
299   {
300     bool def = zypp::KeyRingReport::askUserToAcceptUnknownKey( path, keyid, keyname );
301     SEC << "AcceptUnknownKey " << path << ' ' << keyid << ' ' << keyname << " (" << def << ')' << endl;
302     return keyDef( def );
303   }
304
305   virtual bool askUserToAcceptUnsignedFile( const zypp::Pathname & file )
306   {
307     bool def = zypp::KeyRingReport::askUserToAcceptUnsignedFile( file );
308     SEC << "AcceptUnsignedFile " << file << " (" << def << ')' << endl;
309     return keyDef( def );
310   }
311
312   virtual bool askUserToAcceptVerificationFailed( const zypp::Pathname & file,
313                                                   const std::string & keyid,
314                                                   const std::string & keyname )
315   {
316     bool def = zypp::KeyRingReport::askUserToAcceptVerificationFailed( file, keyid, keyname );
317     SEC << "AcceptVerificationFailed " << file << ' ' << keyid << ' ' << keyname << " (" << def << ')' << endl;
318     return keyDef( def );
319   }
320 };
321
322 struct KeyRingCallbacks
323 {
324   KeyRingCallbacks()
325   {
326     _digestReceive.connect();
327     _keyRingReceive.connect();
328   }
329   ~KeyRingCallbacks()
330   {
331     _digestReceive.disconnect();
332     _keyRingReceive.disconnect();
333   }
334
335   DigestReceive _digestReceive;
336   KeyRingReceive _keyRingReceive;
337
338 };
339 static KeyRingCallbacks cbs;
340
341 void checkSource( const Url & url )
342 {
343   Source_Ref src( createSource( url ) );
344 }
345 void checkSource( const std::string & urlstr )
346 { checkSource( Url(urlstr) ); }
347
348
349 /******************************************************************
350 **
351 **      FUNCTION NAME : main
352 **      FUNCTION TYPE : int
353 */
354 int main( int argc, char * argv[] )
355 {
356   //zypp::base::LogControl::instance().logfile( "xxx" );
357   INT << "===[START]==========================================" << endl;
358   ResPool pool( getZYpp()->pool() );
359
360   checkSource( "ftp://ftp.gwdg.de/pub/linux/misc/suser-guru/rpm/10.0" );
361   return 0;
362
363   if ( 0 )
364     {
365       Measure x( "initTarget " + sysRoot.asString() );
366       getZYpp()->initTarget( sysRoot );
367       getZYpp()->addResolvables( getZYpp()->target()->resolvables(), true );
368       INT << "Added target: " << pool << endl;
369     }
370
371   if ( 0 ) {
372     SourceManager::sourceManager()->restore( sysRoot );
373     if ( SourceManager::sourceManager()->allSources().empty() )
374       {
375         Source_Ref src( createSource( instSrc ) );
376         SourceManager::sourceManager()->addSource( src );
377         SourceManager::sourceManager()->store( sysRoot, true );
378       }
379
380     Source_Ref src( *SourceManager::sourceManager()->Source_begin() );
381     getZYpp()->addResolvables( src.resolvables() );
382     INT << "Added source: " << pool << endl;
383   }
384
385
386   Source_Ref src2( createSource( "dir:/Local/SUSE-Linux-10.1-Build_830-i386/CD1" ) );
387   Source_Ref src1( createSource( "dir:/Local/SUSE-Linux-10.1-Build_830-Addon-BiArch/CD1" ) );
388   INT << "Pool: " << pool << endl;
389   getZYpp()->addResolvables( src1.resolvables() );
390   INT << "Added source1: " << pool << endl;
391   getZYpp()->addResolvables( src2.resolvables() );
392   INT << "Added source2: " << pool << endl;
393
394   vdumpPoolStats( INT,
395                   make_filter_begin<resfilter::ByTransact>(pool),
396                   make_filter_end<resfilter::ByTransact>(pool) ) << endl;
397   MIL << endl;
398   std::for_each( pool.begin(), pool.end(), SetTransactValue( ResStatus::TRANSACT, ResStatus::USER ) );
399   vdumpPoolStats( INT,
400                   make_filter_begin<resfilter::ByTransact>(pool),
401                   make_filter_end<resfilter::ByTransact>(pool) ) << endl;
402   MIL << endl;
403   std::for_each( pool.begin(), pool.end(), StatusReset() );
404   vdumpPoolStats( INT,
405                   make_filter_begin<resfilter::ByTransact>(pool),
406                   make_filter_end<resfilter::ByTransact>(pool) ) << endl;
407   MIL << endl;
408
409   return 0;
410
411   NameKindProxy s( nameKindProxy<Selection>( pool, "default" ) );
412   MIL << s << endl;
413   if ( ! s.availableEmpty() )
414     {
415       PoolItem def( * s.availableBegin() );
416       def.status().setTransact( true, ResStatus::USER );
417     }
418
419   bool eres, rres;
420   {
421     zypp::base::LogControl::TmpLineWriter shutUp;
422     eres = getZYpp()->resolver()->establishPool();
423     rres = getZYpp()->resolver()->resolvePool();
424   }
425   MIL << "est " << eres << " slv " << rres << endl;
426
427
428   for_each( pool.byKindBegin<Package>(), pool.byKindEnd<Package>(),
429             PoolItemSelect() );
430   INT << "FIN: " << pool << endl;
431   vdumpPoolStats( INT,
432                   make_filter_begin<resfilter::ByTransact>(pool),
433                   make_filter_end<resfilter::ByTransact>(pool) ) << endl;
434
435   if ( 1 )
436     {
437       PoolItemList errors_r;
438       PoolItemList remaining_r;
439       PoolItemList srcremaining_r;
440       commit( pool, 0, errors_r, remaining_r, srcremaining_r, false );
441
442       dumpPoolStats( WAR << "remaining_r ", remaining_r.begin(), remaining_r.end() ) << endl;
443       dumpPoolStats( WAR << "srcremaining_r ", srcremaining_r.begin(), srcremaining_r.end() ) << endl;
444     }
445   else
446     {
447       CollectTransacting toTransact;
448       std::for_each( make_filter_begin<resfilter::ByTransact>(pool),
449                      make_filter_end<resfilter::ByTransact>(pool),
450                      functor::functorRef<void,PoolItem>(toTransact) );
451       MIL << toTransact;
452     }
453
454 #if 0
455   Source_Ref src( *SourceManager::sourceManager()->Source_begin() );
456   const std::list<Pathname> srcKeys( src.publicKeys() );
457   MIL << src << endl;
458   DBG << srcKeys << endl;
459
460   target::rpm::RpmDb rpm;
461   rpm.initDatabase( sysRoot );
462   std::set<Edition> rpmKeys( rpm.pubkeys() );
463   MIL << rpm << endl;
464   DBG << rpmKeys << endl;
465
466   ResPool pool( getZYpp()->pool() );
467   getZYpp()->addResolvables( src.resolvables() );
468   SEC << pool << endl;
469
470   rpm.closeDatabase();
471 #endif
472
473   INT << "===[END]============================================" << endl << endl;
474   return 0;
475 }
476