378fbcec6bd27f5922c3ed51da40ab41a27447c1
[platform/upstream/libzypp.git] / tools / NameReqPrv.cc
1 #define INCLUDE_TESTSETUP_WITHOUT_BOOST
2 #include "zypp/../tests/lib/TestSetup.h"
3 #undef  INCLUDE_TESTSETUP_WITHOUT_BOOST
4
5 #include <algorithm>
6 #include <zypp/PoolQuery.h>
7
8 static std::string appname( "NameReqPrv" );
9
10 #define message cout
11 using std::flush;
12
13 int errexit( const std::string & msg_r = std::string(), int exit_r = 100 )
14 {
15   if ( ! msg_r.empty() )
16   {
17     cerr << endl << msg_r << endl << endl;
18   }
19   return exit_r;
20 }
21
22 int usage( const std::string & msg_r = std::string(), int exit_r = 100 )
23 {
24   if ( ! msg_r.empty() )
25   {
26     cerr << endl << msg_r << endl << endl;
27   }
28   cerr << "Usage: " << appname << " [--root ROOTDIR] [OPTIONS] NAME... [[OPTIONS] NAME...]..." << endl;
29   cerr << "  Load all enabled repositories (no refresh) and search for" << endl;
30   cerr << "  occurrences of NAME (regex) in package names, provides or" << endl;
31   cerr << "  requires." << endl;
32   cerr << "  --root   Load repos from the system located below ROOTDIR. If ROOTDIR" << endl;
33   cerr << "           denotes a sover testcase, the testcase is loaded." << endl;
34   cerr << "  --installed Process installed packages only." << endl;
35   cerr << "  -i/-I    turn on/off case insensitive search (default on)" << endl;
36   cerr << "  -n/-N    turn on/off looking for names       (default on)" << endl;
37   cerr << "  -p/-P    turn on/off looking for provides    (default off)" << endl;
38   cerr << "  -r/-R    turn on/off looking for requires    (default off)" << endl;
39   cerr << "  -a       short for -n -p -r" << endl;
40   cerr << "  -A       short for -n -P -R" << endl;
41   cerr << "" << endl;
42   return exit_r;
43 }
44
45 void tableOut( const std::string & s1 = std::string(),
46                const std::string & s2 = std::string(),
47                const std::string & s3 = std::string(),
48                const std::string & s4 = std::string(),
49                const std::string & s5 = std::string() )
50 {
51   message << "  ";
52 #define TABEL(N) static unsigned w##N = 0; if ( ! s##N.empty() ) w##N = std::max( w##N, unsigned(s##N.size()) ); message << str::form( " %-*s ", w##N, s##N.c_str() )
53 #define TABER(N) static unsigned w##N = 0; if ( ! s##N.empty() ) w##N = std::max( w##N, unsigned(s##N.size()) ); message << str::form( " %*s ", w##N, s##N.c_str() )
54   TABER( 1 ); TABEL( 2 ); TABEL( 3 ); TABEL( 4 ); TABEL( 5 );
55 #undef TABEL
56   message << endl;
57 }
58
59 /******************************************************************
60 **
61 **      FUNCTION NAME : main
62 **      FUNCTION TYPE : int
63 */
64 int main( int argc, char * argv[] )
65 {
66   INT << "===[START]==========================================" << endl;
67   appname = Pathname::basename( argv[0] );
68   --argc,++argv;
69
70   if ( ! argc )
71   {
72     return usage();
73   }
74
75   ///////////////////////////////////////////////////////////////////
76
77   ZConfig::instance();
78   Pathname sysRoot("/");
79   sat::Pool satpool( sat::Pool::instance() );
80
81   if ( argc && (*argv) == std::string("--root") )
82   {
83     --argc,++argv;
84     if ( ! argc )
85       return errexit("--root requires an argument.");
86
87     if ( ! PathInfo( *argv ).isDir() )
88       return errexit("--root requires a directory.");
89
90     sysRoot = *argv;
91     --argc,++argv;
92   }
93
94   bool onlyInstalled( false );
95   if ( argc && (*argv) == std::string("--installed") )
96   {
97     --argc,++argv;
98     onlyInstalled = true;
99   }
100
101   if ( TestSetup::isTestcase( sysRoot ) )
102   {
103     message << str::form( "*** Load Testcase from '%s'", sysRoot.c_str() ) << endl;
104     TestSetup test;
105     test.loadTestcaseRepos( sysRoot );
106     dumpRange( message, satpool.reposBegin(), satpool.reposEnd() ) << endl;
107   }
108   else if ( TestSetup::isTestSetup( sysRoot ) )
109   {
110     message << str::form( "*** Load TestSetup from '%s'", sysRoot.c_str() ) << endl;
111     TestSetup test( sysRoot, Arch_x86_64 );
112     test.loadRepos();
113     dumpRange( message, satpool.reposBegin(), satpool.reposEnd() ) << endl;
114   }
115   else
116   {
117     // a system
118     message << str::form( "*** Load system at '%s'", sysRoot.c_str() ) << endl;
119     if ( true )
120     {
121       message << "*** load target '" << Repository::systemRepoAlias() << "'\t" << endl;
122       getZYpp()->initializeTarget( sysRoot );
123       getZYpp()->target()->load();
124       message << satpool.systemRepo() << endl;
125     }
126
127     if ( !onlyInstalled )
128     {
129       RepoManager repoManager( sysRoot );
130       RepoInfoList repos = repoManager.knownRepositories();
131       for_( it, repos.begin(), repos.end() )
132       {
133         RepoInfo & nrepo( *it );
134
135         if ( ! nrepo.enabled() )
136           continue;
137
138         if ( ! repoManager.isCached( nrepo ) )
139         {
140           message << str::form( "*** omit uncached repo '%s' (do 'zypper refresh')", nrepo.name().c_str() ) << endl;
141           continue;
142         }
143
144         message << str::form( "*** load repo '%s'\t", nrepo.name().c_str() ) << flush;
145         try
146         {
147           repoManager.loadFromCache( nrepo );
148           message << satpool.reposFind( nrepo.alias() ) << endl;
149         }
150         catch ( const Exception & exp )
151         {
152           message << exp.asString() + "\n" + exp.historyAsString() << endl;
153           message << str::form( "*** omit broken repo '%s' (do 'zypper refresh')", nrepo.name().c_str() ) << endl;
154           continue;
155         }
156       }
157     }
158   }
159
160   ///////////////////////////////////////////////////////////////////
161
162   bool ignorecase( true );
163   bool names     ( true );
164   bool provides  ( false );
165   bool requires  ( false );
166
167   for ( ; argc; --argc,++argv )
168   {
169     if ( (*argv)[0] == '-' )
170     {
171       switch ( (*argv)[1] )
172       {
173         case 'a':  names =      true,   requires = provides =   true;   break;
174         case 'A':  names =      true,   requires = provides =   false;  break;
175         case 'i': ignorecase =  true;   break;
176         case 'I': ignorecase =  false;  break;
177         case 'n': names =       true;   break;
178         case 'N': names =       false;  break;
179         case 'r': requires =    true;   break;
180         case 'R': requires =    false;  break;
181         case 'p': provides =    true;   break;
182         case 'P': provides =    false;  break;
183       }
184       continue;
185     }
186
187     PoolQuery q;
188     if ( onlyInstalled )
189       q.setInstalledOnly();
190     std::string qstr( *argv );
191
192     if ( *argv == ResKind::product )
193     {
194       q.addKind( ResKind::product );
195     }
196     else if ( *argv == ResKind::patch )
197     {
198       q.addKind( ResKind::patch );
199     }
200     else if ( *argv == ResKind::pattern )
201     {
202       q.addKind( ResKind::pattern );
203     }
204     else
205     {
206     q.addString( qstr );
207     q.setMatchRegex();
208     q.setCaseSensitive( ! ignorecase );
209
210     if ( names )
211       q.addAttribute( sat::SolvAttr::name );
212     if ( provides )
213       q.addDependency( sat::SolvAttr::provides );
214     if ( requires )
215       q.addDependency( sat::SolvAttr::requires );
216     }
217
218     message << *argv << " [" << (ignorecase?'i':'_') << (names?'n':'_') << (requires?'r':'_') << (provides?'p':'_') << "] {" << endl;
219
220     for_( it, q.begin(), q.end() )
221     {
222       tableOut( str::numstring( it->id() ), it->asString(), it->repository().name(), it->vendor().asString(),
223                 str::numstring( PoolItem(*it)->buildtime() ) );
224       if ( ! it.matchesEmpty() )
225       {
226         for_( match, it.matchesBegin(), it.matchesEnd() )
227         {
228           tableOut( "", "", "", match->inSolvAttr().asString().substr( 9, 1 )+" " +match->asString() );
229         }
230       }
231     }
232
233     message << "}" << endl;
234   }
235
236   INT << "===[END]============================================" << endl << endl;
237   return 0;
238 }