diff --git a/doc/prt-get.8 b/doc/prt-get.8 index bc1938d..2bcbcb3 100644 --- a/doc/prt-get.8 +++ b/doc/prt-get.8 @@ -29,7 +29,8 @@ install/update a list of packages with one command .TP \ \ \ \(bu -list dependencies for a list of packages +list dependencies for a list of packages and search for missing +dependencies of installed packages .TP \ \ \ \(bu @@ -192,6 +193,13 @@ Print the path of a port .B readme Print the port's README file if it exists; if set, uses $PAGER +.TP +.B depcheck [--deps|--ports] +Checks for missing dependencies of installed packages. When called +with '--deps', show only missing dependencies in simply format. +When called with '--ports', show only packages that have missing +dependencies + .TP .B depends [ ...] print a recursive list of dependencies to install the packages passed diff --git a/misc/prt-get_complete b/misc/prt-get_complete index a06dfcd..fa19fe2 100644 --- a/misc/prt-get_complete +++ b/misc/prt-get_complete @@ -28,7 +28,7 @@ _prt-get() if [[ "$cur" != -* ]]; then case ${COMP_WORDS[1]} in "install" | "depinst" | "grpinst" | "path" | "dependent" | \ - "depends" | "quickdep" | "info" | "readme" | \ + "depcheck" | "depends" | "quickdep" | "info" | "readme" | \ "ls" | "isinst" | "deptree" ) if [ -f /var/lib/pkg/prt-get.cache ]; then plist=`prt-cache list` diff --git a/src/argparser.cpp b/src/argparser.cpp index 50667e1..0e0d95a 100644 --- a/src/argparser.cpp +++ b/src/argparser.cpp @@ -48,7 +48,9 @@ ArgParser::ArgParser( int argc, char** argv ) m_fullPath(false), m_recursive(false), m_printTree(false), - m_depSort(false) + m_depSort(false), + m_depcheckPrintOnlyDeps(false), + m_depcheckPrintOnlyPorts(false) { } @@ -122,10 +124,10 @@ const string& ArgParser::alternateConfigFile() const */ bool ArgParser::parse() { - const int commandCount = 35; + const int commandCount = 36; string commands[commandCount] = { "list", "search", "dsearch", "info", - "depends", "install", "depinst", + "depcheck", "depends", "install", "depinst", "help", "isinst", "dup", "update", "quickdep", "diff", "quickdiff", "grpinst", "version", "cache", @@ -137,7 +139,7 @@ bool ArgParser::parse() "listorphans" }; Type commandID[commandCount] = { LIST, SEARCH, DSEARCH, INFO, - DEPENDS, INSTALL, DEPINST, + DEPCHECK, DEPENDS, INSTALL, DEPINST, HELP, ISINST, DUP, UPDATE, QUICKDEP, DIFF, QUICKDIFF, GRPINST, SHOW_VERSION, CREATE_CACHE, @@ -206,6 +208,10 @@ bool ArgParser::parse() m_printTree = true; } else if ( s == "--depsort" ) { m_depSort = true; + } else if ( s == "--deps" || s == "-d" ) { + m_depcheckPrintOnlyDeps = true; + } else if ( s == "--ports" || s == "-p" ) { + m_depcheckPrintOnlyPorts = true; } else if ( s == "-f" ) { m_pkgaddArgs += " " + s; @@ -472,3 +478,13 @@ const string& ArgParser::ignore() const { return m_ignore; } + +bool ArgParser::depcheckPrintOnlyDeps() const +{ + return m_depcheckPrintOnlyDeps; +} + +bool ArgParser::depcheckPrintOnlyPorts() const +{ + return m_depcheckPrintOnlyPorts; +} diff --git a/src/argparser.h b/src/argparser.h index c24e7bd..6696cf9 100644 --- a/src/argparser.h +++ b/src/argparser.h @@ -31,7 +31,7 @@ public: /*! Command type */ enum Type { HELP, LIST, SEARCH, DSEARCH, INSTALL, DEPINST, - INFO, DEPENDS, ISINST, DUP, UPDATE, + INFO, DEPCHECK, DEPENDS, ISINST, DUP, UPDATE, QUICKDEP, DIFF, GRPINST, GRPUPDATE, QUICKDIFF, SHOW_VERSION, CREATE_CACHE, PATH, LISTINST, PRINTF, README, DEPENDENT, SYSUP, @@ -60,6 +60,8 @@ public: bool recursive() const; bool printTree() const; bool depSort() const; + bool depcheckPrintOnlyDeps() const; + bool depcheckPrintOnlyPorts() const; const string& alternateConfigFile() const; const string& pkgmkArgs() const; @@ -112,8 +114,9 @@ private: bool m_recursive; bool m_printTree; - bool m_depSort; + bool m_depcheckPrintOnlyDeps; + bool m_depcheckPrintOnlyPorts; string m_alternateConfigFile; string m_pkgmkArgs; diff --git a/src/main.cpp b/src/main.cpp index d3eb097..b99faae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -92,6 +92,9 @@ int main( int argc, char** argv ) case ArgParser::GRPINST: prtGet.install( false, true ); break; + case ArgParser::DEPCHECK: + prtGet.printDepcheck(); + break; case ArgParser::DEPENDS: prtGet.printDepends(); break; diff --git a/src/prtget.cpp b/src/prtget.cpp index 5e5bdc3..6730c6a 100644 --- a/src/prtget.cpp +++ b/src/prtget.cpp @@ -141,6 +141,16 @@ void PrtGet::printUsage() << endl; cout << "\nDEPENDENCIES" << endl; + cout << " depcheck [opt] check for missing dependencies of " + << "installed ports" + << endl; + cout << " where opt can be:" << endl; + cout << " --deps list only dependencies in simple " + << "format" + << endl; + cout << " --ports list only ports that have missing " + << "dependencies in simple format" + << endl; cout << " depends show dependencies for these ports" << endl; cout << " quickdep same as 'depends' but simple format" @@ -729,6 +739,90 @@ void PrtGet::executeTransaction( InstallTransaction& transaction, m_currentTransaction = 0; } +/*! + print missing dependencies of installed ports +*/ +void PrtGet::printDepcheck() +{ + map l; + m_pkgDB->getMatchingPackages( "*", l, m_useRegex ); + map ::iterator it = l.begin(); + list missdeps, missports; + + initRepo(); + + if ( l.empty() ) { + cerr << m_appName << ": No packages found" << endl; + m_returnValue = PG_GENERAL_ERROR; + return; + } + + for ( ; it != l.end(); ++it ) { + + InstallTransaction transaction( it->first, m_repo, m_pkgDB, m_config ); + InstallTransaction::InstallResult result = transaction.calcDependencies(); + if ( result == InstallTransaction::CYCLIC_DEPEND ) { + cerr << m_appName << ": cyclic dependencies found" << endl; + m_returnValue = PG_GENERAL_ERROR; + return; + } else if ( result == InstallTransaction::PACKAGE_NOT_FOUND ) { + warnPackageNotFound(transaction); + m_returnValue = PG_GENERAL_ERROR; + return; + } + + const list& deps = transaction.dependencies(); + if ( !deps.size() ) + continue; + + if ( !m_parser->depcheckPrintOnlyDeps() ) + missdeps.clear(); + + list::const_iterator dep = deps.begin(); + for ( ; dep != deps.end(); ++dep ) { + if ( !m_pkgDB->isInstalled( *dep ) ) + missdeps.push_back(*dep); + } + + if ( m_parser->depcheckPrintOnlyDeps() || !missdeps.size() ) + continue; + + if ( m_parser->depcheckPrintOnlyPorts() ) { + missports.push_back(it->first); + continue; + } + + cout << it->first.c_str() << endl; + + dep = missdeps.begin(); + for ( ; dep != missdeps.end(); ++dep ) + cout << " " << *dep << endl; + } + + if ( ! ( missdeps.size() || missports.size() ) ) + return; + + list::const_iterator arg, end; + + if ( m_parser->depcheckPrintOnlyDeps() ) { + missdeps.sort(); + missdeps.unique(); + arg = missdeps.begin(); + end = missdeps.end(); + } else if ( m_parser->depcheckPrintOnlyPorts() ) { + arg = missports.begin(); + end = missports.end(); + } else { + return; + } + + bool const tty = isatty(1); + for ( ; arg != end; ++arg ) + cout << *arg << (tty ? " " : "\n"); + if (tty) + cout << endl; +} + /*! print dependency listing \param simpleListing Whether it should be in a simple format diff --git a/src/prtget.h b/src/prtget.h index 6a82975..d97e3b1 100644 --- a/src/prtget.h +++ b/src/prtget.h @@ -66,6 +66,7 @@ public: bool dependencies=false ); void sysup(); void current(); + void printDepcheck(); void printDepends( bool simpleListing=false ); void printDependTree(); void printDependent();