From 38bb3aa21ab13d530365a16d7a45ed7330be20b6 Mon Sep 17 00:00:00 2001 From: John McQuah Date: Fri, 10 Mar 2023 10:03:11 -0500 Subject: [PATCH] add support for optional dependencies update docs to explain how optional dependencies are handled --- ChangeLog | 5 ++ README | 15 ++-- TODO | 2 +- doc/prt-get.conf.5 | 16 +++- misc/prt-get.conf | 3 + src/argparser.cpp | 11 +++ src/argparser.h | 2 + src/configuration.cpp | 13 +++ src/configuration.h | 2 + src/installtransaction.cpp | 59 +++++++++++-- src/installtransaction.h | 3 +- src/package.cpp | 48 +++++++--- src/package.h | 9 +- src/prtget.cpp | 177 +++++++++++++++++++++++++------------ src/prtget.h | 4 +- src/repository.cpp | 4 +- 16 files changed, 278 insertions(+), 95 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b9160b..d6567f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +* 10.03.2023 John McQuah +- make it possible to consider optional dependencies when updating +- bump version of the cache file format, to warn users about the +'Packager' field being replaced by 'Optional' + * 5.16 26.06.2008 Johannes Winkelmann - don't loop forever when version= contains unsupported $() tokens - gcc 4.3 fixes (thanks Fredrik) diff --git a/README b/README index c43a40c..846f774 100644 --- a/README +++ b/README @@ -11,8 +11,8 @@ process. Installing: ----------- -Just install the crux port from -- http://www.hta-bi.bfh.ch/~winkj/files/crux/prt-get.prt.gz +Download an iso of the latest CRUX release for a precompiled package. +Otherwise, build from the sources in this repository. prt-get has to know where to look for ports. You can specify those in /etc/prt-get.conf, one directory per line. Note that the order @@ -20,15 +20,16 @@ matters, when the same port is in multiple direcories (e.g. /usr/ports/contrib/mutt and /usr/ports/local/mutt), the one found _first_ will be used. -Feel free to contact me in case of problems (jw@tks6.net) - +Feel free to file a bug report on the Gitea issue tracker: +https://git.crux.nu:82/farkuhar/prt-get/issues/ more information ---------------- See the man pages for prt-get(8), prt-get.conf(5) and prt-cache for more -information. There is also a user manual in the doc directory (as a -tex file). This document should also be available as PDF from -http://www.hta-bi.bfh.ch/~winkj/files/crux/manual.pdf +information. The CRUX homepage also offers a (somewhat dated) User Manual +and Quick Start guide: +https://crux.nu/doc/prt-get%20-%20User%20Manual.html +https://crux.nu/doc/prt-get%20-%20Quick%20start.html "it must be user error" (thinkgeek) ----------------------------------- diff --git a/TODO b/TODO index b596cd8..92b775c 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,7 @@ CONSIDER: - default formats for printf and dup -- add update-footprint, update-md5sum commands (patch in trac) +- add update-footprint, update-signature commands - sysup - allow injecting of new (uninstalled) dependencies - allow to prohibit recompilation of packages when a dependency failed diff --git a/doc/prt-get.conf.5 b/doc/prt-get.conf.5 index 7006277..a03b87e 100644 --- a/doc/prt-get.conf.5 +++ b/doc/prt-get.conf.5 @@ -48,6 +48,9 @@ preferhigher yes # use regexps for searching (default no) useregex yes + +# consider soft dependencies when sorting the update/sysup targets +softdeps no .fi .LP @@ -90,6 +93,17 @@ if set to yes, prt-get will interpret search and filter patterns in list, listinst, printf, search, dsearch and fsearch as regular expressions. This will be the default in prt-get 0.6. +.B softdeps +if set to yes, during an update operation prt-get will perform a greedy search +of the dependency graph, visiting any \fBinstalled\fP optional dependency of +the ports specified on the command line and recursing until either a leaf node is +found (port that doesn't depend on anything else) or a cycle is created. If a +cycle is \fBnot\fP created by following a soft dependency, then this dependency +relationship is added to the list of edges, and topological sort of the +resulting graph can proceed as usual. The default is \fBsoftdeps no\fP, which +means prt-get will only consider hard dependencies when walking the directed +graph. + .LP .B makecommand .B addcommand @@ -155,6 +169,6 @@ problem :-) .SH "AUTHORS" -Johannes Winkelmann +Johannes Winkelmann , John McQuah .SH "SEE ALSO" prt-get(8), pkgmk(8) pkgadd(8), ports(8) diff --git a/misc/prt-get.conf b/misc/prt-get.conf index 2d013b5..66a1bef 100644 --- a/misc/prt-get.conf +++ b/misc/prt-get.conf @@ -41,3 +41,6 @@ logfile /var/log/pkgbuild/%n.log ### use regexp search # useregex no # (yes|no) + +### consider optional dependencies when sorting the update/sysup targets +# softdeps no # (yes|no) diff --git a/src/argparser.cpp b/src/argparser.cpp index 7828242..904e430 100644 --- a/src/argparser.cpp +++ b/src/argparser.cpp @@ -29,6 +29,7 @@ ArgParser::ArgParser( int argc, char** argv ) m_noStdConfig( false ), m_writeLog( false ), m_nodeps( false ), + m_softdeps( false ), m_all( false ), m_printPath( false ), m_execPreInstall( false ), @@ -182,6 +183,8 @@ bool ArgParser::parse() m_useCache = true; } else if ( s == "--nodeps" ) { m_nodeps = true; + } else if ( s == "--softdeps" ) { + m_softdeps = true; } else if ( s == "--all" ) { m_all = true; } else if ( s == "--path" ) { @@ -388,6 +391,14 @@ bool ArgParser::nodeps() const return m_nodeps; } +/*! + \return whether there was a --softdeps argument +*/ +bool ArgParser::followSoftdeps() const +{ + return m_softdeps; +} + /*! \return whether there was a --all argument */ diff --git a/src/argparser.h b/src/argparser.h index c24e7bd..ec9cbe5 100644 --- a/src/argparser.h +++ b/src/argparser.h @@ -60,6 +60,7 @@ public: bool recursive() const; bool printTree() const; bool depSort() const; + bool followSoftdeps() const; const string& alternateConfigFile() const; const string& pkgmkArgs() const; @@ -99,6 +100,7 @@ private: bool m_writeLog; bool m_nodeps; + bool m_softdeps; bool m_all; bool m_printPath; diff --git a/src/configuration.cpp b/src/configuration.cpp index 8f3d60f..5e814db 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -34,6 +34,7 @@ Configuration::Configuration( const std::string& configFile, m_runScripts( false ), m_preferHigher( false ), m_useRegex( false ), + m_followSoftdeps( false ), m_makeCommand( "" ), m_addCommand( "" ), m_removeCommand( "" ), m_runscriptCommand( "" ) { @@ -188,6 +189,14 @@ void Configuration::parseLine(const string& line, bool prepend) if ( s == "yes" ) { m_useRegex = true; } + } else if ( startsWithNoCase( s, "softdeps" ) ) { + s = stripWhiteSpace( s.replace( 0, 8, "" ) ); + if ( s == "yes" ) { + m_followSoftdeps = true; + } + if ( s == "no" ) { + m_followSoftdeps = false; + } } else if ( startsWithNoCase( s, "makecommand" ) ) { m_makeCommand = stripWhiteSpace( s.replace( 0, 11, "" ) ); } else if ( startsWithNoCase( s, "addcommand" ) ) { @@ -234,4 +243,8 @@ bool Configuration::useRegex() const return m_useRegex; } +bool Configuration::followSoftdeps() const +{ + return m_followSoftdeps; +} diff --git a/src/configuration.h b/src/configuration.h index 5d721ae..3b69ff6 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -43,6 +43,7 @@ public: bool runScripts() const; bool preferHigher() const; bool useRegex() const; + bool followSoftdeps() const; void addConfig(const std::string& line, bool configSet, @@ -72,6 +73,7 @@ private: bool m_runScripts; bool m_preferHigher; bool m_useRegex; + bool m_followSoftdeps; std::string m_makeCommand; std::string m_addCommand; diff --git a/src/installtransaction.cpp b/src/installtransaction.cpp index 59834f1..e0c6600 100644 --- a/src/installtransaction.cpp +++ b/src/installtransaction.cpp @@ -467,12 +467,13 @@ bool InstallTransaction::calculateDependencies() return false; } + vector treeWalk; list< pair >::const_iterator it = m_packages.begin(); for ( ; it != m_packages.end(); ++it ) { const Package* package = it->second; if ( package ) { - checkDependecies( package ); + checkDependencies( false, package ); } } list indexList; @@ -491,14 +492,17 @@ bool InstallTransaction::calculateDependencies() /*! recursive method to calculate dependencies - \param package package for which we want to calculate dependencies - \param depends index if the package \a package depends on (-1 for none) + \param greedy (=true if any soft dependencies took us to the current node) + \param package, package for which we want to calculate dependencies + \param depends, index of the package \a package depends on (-1 for none) */ -void InstallTransaction::checkDependecies( const Package* package, +void InstallTransaction::checkDependencies( bool greedy, + const Package* package, int depends ) { int index = -1; bool newPackage = true; + for ( unsigned int i = 0; i < m_depList.size(); ++i ){ if ( m_depList[i] == package->name() ) { index = i; @@ -507,17 +511,28 @@ void InstallTransaction::checkDependecies( const Package* package, } } - if ( index == -1 ) { index = m_depList.size(); + if (( not greedy ) or ( m_pkgDB->isInstalled(package->name(),false) )) { m_depList.push_back( package->name() ); + } } - if ( depends != -1 ) { - m_resolver.addDependency( index, depends ); - } else { + // did we already visit the current node when walking the tree? + // return to the caller if such a cycle is detected + for ( unsigned int i = 0; i < treeWalk.size(); ++i) { + if ( treeWalk[i] == package->name() ) { + return; + } + } + + treeWalk.push_back(package->name()); + + if ( depends == -1 ) { // this just adds index to the dependency resolver m_resolver.addDependency( index, index ); + } else { + m_resolver.addDependency( index, depends ); } if ( newPackage ) { @@ -534,15 +549,41 @@ void InstallTransaction::checkDependecies( const Package* package, } const Package* p = m_repo->getPackage( dep ); if ( p ) { - checkDependecies( p, index ); + checkDependencies( greedy, p, index ); } else { m_missingPackages. push_back( make_pair( dep, package->name() ) ); } } } + } + if ( (m_config->followSoftdeps()) and (!package->optionals().empty()) ) { + list softDeps; + split( package->optionals(), ',', softDeps ); + list::iterator it = softDeps.begin(); + for ( ; it != softDeps.end(); ++it ) { + string softdep = *it; + if ( !softdep.empty() ) { + string::size_type pos = softdep.find_last_of( '/' ); + if ( pos != string::npos && (pos+1) < softdep.length() ) { + softdep = softdep.substr( pos + 1 ); + } + if ( m_pkgDB->isInstalled(softdep, true) ) { + const Package* p = m_repo->getPackage( softdep ); + if ( p ) { + checkDependencies( true, p, index ); + } else { + m_missingPackages. + push_back( make_pair( softdep, package->name() ) ); + } + } + } + } } } + + // reset the tree traversal history + treeWalk.pop_back(); } diff --git a/src/installtransaction.h b/src/installtransaction.h index 113abf2..8985e3e 100644 --- a/src/installtransaction.h +++ b/src/installtransaction.h @@ -103,7 +103,7 @@ public: private: bool calculateDependencies(); - void checkDependecies( const Package* package, int depends=-1 ); + void checkDependencies( bool greedy, const Package* package, int depends=-1 ); InstallResult installPackage( const Package* package, const ArgParser* parser, @@ -136,6 +136,7 @@ private: list m_depNameList; vector m_depList; + vector treeWalk; // packages requested to be installed not found in the ports tree list< pair > m_missingPackages; diff --git a/src/package.cpp b/src/package.cpp index 458451c..f547658 100644 --- a/src/package.cpp +++ b/src/package.cpp @@ -44,7 +44,7 @@ Package::Package( const string& name, const string& description, const string& dependencies, const string& url, - const string& packager, + const string& optionals, const string& maintainer, const string& hasReadme, const string& hasPreInstall, @@ -53,7 +53,7 @@ Package::Package( const string& name, { m_data = new PackageData( name, path, version, release, description, dependencies, url, - packager, maintainer, hasReadme, + optionals, maintainer, hasReadme, hasPreInstall, hasPostInstall ); } @@ -110,11 +110,11 @@ const string& Package::url() const return m_data->url; } -/*! \return the packager of this package */ -const string& Package::packager() const +/*! \return the optional dependencies of this package */ +const string& Package::optionals() const { load(); - return m_data->packager; + return m_data->optionals; } /*! \return the maintainer of this package */ const string& Package::maintainer() const @@ -202,15 +202,36 @@ void Package::load() const if ( startsWithNoCase( line, "desc" ) ) { m_data->description = stripWhiteSpace( getValue( line, ':' ) ); - - } else if ( startsWithNoCase( line, "pack" ) ) { - m_data->packager = - stripWhiteSpace( getValue( line, ':' ) ); } else if ( startsWithNoCase( line, "maint" ) ) { m_data->maintainer = stripWhiteSpace( getValue( line, ':' ) ); } else if ( startsWithNoCase( line, "url" ) ) { m_data->url = stripWhiteSpace( getValue( line, ':' ) ); + } else if ( startsWithNoCase( line, "optional" ) or + startsWithNoCase( line, "nice to have" ) ) { + string softdeps = stripWhiteSpace( getValue( line, ':' ) ); + + StringHelper::replaceAll( softdeps, " ", "," ); + StringHelper::replaceAll( softdeps, ",,", "," ); + + // TODO: decide which one to use +#if 0 + // remove commented out packages + list softDepList = StringHelper::split( softdeps, ',' ); + list::iterator it = deps.begin(); + for ( ; it != softDepList.end(); ++it ) { + if ( (*it)[0] == '#' ) { + cerr << "Commented dep: " << *it << endl; + } else { + if ( it != softDepsList.begin() ) { + m_data->optionals += ","; + } + m_data->optionals += *it; + } + } +#else + m_data->optionals = softdeps; +#endif } else if ( startsWithNoCase( line, "dep" ) ) { string depends = stripWhiteSpace( getValue( line, ':' ) ); @@ -265,6 +286,11 @@ void Package::setDependencies( const std::string& dependencies ) m_data->depends = dependencies; } +void Package::setOptionals( const std::string& optionals ) +{ + m_data->optionals = optionals; +} + PackageData::PackageData( const string& name_, @@ -274,7 +300,7 @@ PackageData::PackageData( const string& name_, const string& description_, const string& dependencies_, const string& url_, - const string& packager_, + const string& optionals_, const string& maintainer_, const string& hasReadme_, const string& hasPreInstall_, @@ -286,7 +312,7 @@ PackageData::PackageData( const string& name_, description( description_ ), depends( dependencies_ ), url( url_ ), - packager( packager_ ), + optionals( optionals_ ), maintainer( maintainer_ ) { diff --git a/src/package.h b/src/package.h index bc3e055..2bcf1e9 100644 --- a/src/package.h +++ b/src/package.h @@ -35,7 +35,7 @@ public: const std::string& description, const std::string& dependencies, const std::string& url, - const std::string& packager, + const std::string& optionals, const std::string& maintainer, const std::string& hasReadme, const std::string& hasPreInstall, @@ -50,7 +50,7 @@ public: const std::string& description() const; const std::string& dependencies() const; const std::string& url() const; - const std::string& packager() const; + const std::string& optionals() const; const std::string& maintainer() const; const bool hasReadme() const; const bool hasPreInstall() const; @@ -59,6 +59,7 @@ public: std::string versionReleaseString() const; void setDependencies( const std::string& dependencies ); + void setOptionals( const std::string& optionals ); private: @@ -82,7 +83,7 @@ struct PackageData const std::string& description_="", const std::string& dependencies_="", const std::string& url_="", - const std::string& packager="", + const std::string& optionals_="", const std::string& maintainer="", const std::string& hasReadme_="", const std::string& hasPreInstall_="", @@ -95,7 +96,7 @@ struct PackageData std::string description; std::string depends; std::string url; - std::string packager; + std::string optionals; std::string maintainer; std::string versionReleaseString; diff --git a/src/prtget.cpp b/src/prtget.cpp index b03515e..84b43f7 100644 --- a/src/prtget.cpp +++ b/src/prtget.cpp @@ -73,6 +73,7 @@ PrtGet::PrtGet( const ArgParser* parser ) readConfig(); m_useRegex = m_config->useRegex() || m_parser->useRegex(); + m_followSoftdeps = m_config->followSoftdeps() || m_parser->followSoftdeps(); } /*! destruct PrtGet object */ @@ -152,6 +153,8 @@ void PrtGet::printUsage() << "depend on 'port'" << endl; cout << " where opt can be:" << endl; + cout << " --softdeps consider optional dependencies too" + << endl; cout << " --all list all dependent packages, not " << "only installed" << endl; cout << " --recursive print recursive listing" << endl; @@ -205,16 +208,12 @@ void PrtGet::printUsage() cout << " sysup [opt] update all outdated ports" << endl; cout << " where opt can be:" << endl; - cout << " --nodeps don't sort by dependencies" + cout << " --nodeps don't sort by dependencies" << endl; - cout << " --test test mode" << endl; - cout << " --log write log file"<< endl; - cout << " --prefer-higher prefer higher installed " - << "versions over lower ones in ports tree" - << endl; - cout << " --strict-diff override prefer higher " - << "configuration setting" + cout << " --softdeps consider optional dependencies when sorting" << endl; + cout << " --test test mode" << endl; + cout << " --log write log file"<< endl; cout << " lock lock current version " << "of packages" @@ -395,16 +394,15 @@ void PrtGet::printInfo() if ( !p->url().empty() ) { cout << "URL: " << p->url() << endl; } - if ( !p->packager().empty() ) { - cout << "Packager: " << p->packager() << endl; - } if ( !p->maintainer().empty() ) { cout << "Maintainer: " << p->maintainer() << endl; } - if ( !p->dependencies().empty() ) { cout << "Dependencies: " << p->dependencies() << endl; } + if ( !p->optionals().empty() ) { + cout << "Optional: " << p->optionals() << endl; + } // TODO: don't hardcode file names string filesString = ""; @@ -765,7 +763,11 @@ void PrtGet::printDepends( bool simpleListing ) } } else { if ( deps.size() > 0 ) { - cout << "-- dependencies ([i] = installed)" << endl; + cout << "-- dependencies ("; + if ( m_followSoftdeps ) { + cout << "including optionals, "; + } + cout << "[i] = installed)" << endl; list::const_iterator it = deps.begin(); bool isAlias; @@ -1268,7 +1270,7 @@ void PrtGet::printf() StringHelper::replaceAll( output, "%r", p->release() ); StringHelper::replaceAll( output, "%d", p->description() ); StringHelper::replaceAll( output, "%e", p->dependencies() ); - StringHelper::replaceAll( output, "%P", p->packager() ); + StringHelper::replaceAll( output, "%P", p->optionals() ); StringHelper::replaceAll( output, "%M", p->maintainer() ); StringHelper::replaceAll( output, "\\t", "\t" ); @@ -1281,7 +1283,7 @@ void PrtGet::printf() StringHelper::replaceAll( sortkey, "%r", p->release() ); StringHelper::replaceAll( sortkey, "%d", p->description() ); StringHelper::replaceAll( sortkey, "%e", p->dependencies() ); - StringHelper::replaceAll( sortkey, "%P", p->packager() ); + StringHelper::replaceAll( sortkey, "%P", p->optionals() ); StringHelper::replaceAll( sortkey, "%M", p->maintainer() ); string isInst = "no"; @@ -1371,6 +1373,7 @@ void PrtGet::printDependent() initRepo(); string arg = *(m_parser->otherArgs().begin()); + vector treeWalk; if (m_parser->printTree()) { cout << arg << endl; @@ -1385,6 +1388,14 @@ void PrtGet::printDependent(const string& dep, int level) map::const_iterator it = m_repo->packages().begin(); static map shownMap; + /* cycle detection --- code duplicated from checkDependencies */ + for ( unsigned int i=0; i != treeWalk.size() ; ++i ) { + if ( treeWalk[i] == dep ) { + return; + } + } + treeWalk.push_back(dep); + set dependent; for ( ; it != m_repo->packages().end(); ++it ) { @@ -1400,6 +1411,17 @@ void PrtGet::printDependent(const string& dep, int level) dependent.insert( p ); } } + if ( p && m_pkgDB->isInstalled(p->name(),false) && m_followSoftdeps + && p->optionals().find( dep ) != string::npos ) { + list tokens; + StringHelper::split( p->optionals(), ',', tokens ); + list::iterator it = find( tokens.begin(), + tokens.end(), + dep ); + if ( it != tokens.end() ) { + dependent.insert( p ); + } + } } // - there are two modes, tree and non-tree recursive mode; in @@ -1446,6 +1468,8 @@ void PrtGet::printDependent(const string& dep, int level) } } } + + treeWalk.pop_back(); } void PrtGet::listOrphans() @@ -1464,6 +1488,15 @@ void PrtGet::listOrphans() for (; lit != tokens.end(); ++lit) { required[*lit] = true; } + if (m_followSoftdeps) { + StringHelper::split( p->optionals(), ',', tokens ); + lit = tokens.begin(); + for (; lit != tokens.end(); ++lit) { + if ( m_pkgDB->isInstalled(*lit,false) ) { + required[*lit] = true; + } + } + } } } @@ -1988,69 +2021,97 @@ void PrtGet::printDependTree() cerr << "Package '" << arg << "' not found" << endl; m_returnValue = PG_GENERAL_ERROR; return; - } + } - if (p->dependencies().length() > 0) { - - cout << "-- dependencies ([i] = installed"; + if ( (p->dependencies().length() > 0) or + (m_followSoftdeps && p->optionals().length() > 0) ) { + cout << "-- dependencies ("; + if ( m_followSoftdeps ) { + cout << "[s] soft, "; + } + cout << "[i] hard, [ ] not installed"; if (!m_parser->all()) { - cout << ", '-->' = seen before"; + cout << ", '-->' already shown"; } cout << ")" << endl; - if ( m_pkgDB->isInstalled( *it ) ) { - cout << "[i] "; - } else { - cout << "[ ] "; - } - cout << p->name() << endl; - printDepsLevel(2, p); + printDepsLevel(2, p, false); } - } -void PrtGet::printDepsLevel(int indent, const Package* package) +void PrtGet::printDepsLevel(int indent, const Package* package, bool greedy) { static map shownMap; + string installStatus; + bool isAlias = false; + string aliasName = ""; + + /* cycle detection -- code duplicated from checkDependencies */ + for (unsigned int i=0; iname()) { + return; + } + } + treeWalk.push_back(package->name()); + + if ( m_pkgDB->isInstalled( package->name(), true, &isAlias, &aliasName ) ) { + installStatus = ( greedy ) ? "[s] " : "[i] "; + cout << installStatus; + } else { + cout << "[ ] "; + } + for (int i = 0; i < indent; ++i) { + cout << " "; + } + cout << package->name(); + if (isAlias) { + cout << " (provided by " << aliasName << ")"; + } + map::iterator shownIt = shownMap.find(package->name()); + if (shownIt != shownMap.end()) { + cout << " -->" << endl; + treeWalk.pop_back(); + return; + } else { + cout << endl; + } list deps; StringHelper::split(package->dependencies(), ',', deps); list::iterator it = deps.begin(); - bool isAlias = false; - string aliasName = ""; for (; it != deps.end(); ++it) { - if ( m_pkgDB->isInstalled( *it, true, &isAlias, &aliasName ) ) { - cout << "[i] "; - } else { - cout << "[ ] "; - } - for (int i = 0; i < indent; ++i) { - cout << " "; - } - cout << *it; - if (isAlias) { - cout << " (provided by " << aliasName << ")"; - } const Package* p = m_repo->getPackage( *it ); if (p) { - if (p->dependencies().length() > 0) { - map::iterator shownIt = shownMap.find(*it); - if (shownIt != shownMap.end()) { - cout << " -->" << endl;; - } else { - cout << endl; - printDepsLevel(indent+2, p); - if (!m_parser->all()) { - shownMap[*it] = true; - } - } - } else { - cout << endl; - } + printDepsLevel(indent+2, p, greedy); + if (!m_parser->all()) { + shownMap[*it] = true; + } } else { cout << " (not found in ports tree)" << endl; - } + } } + + if ( m_followSoftdeps ) { + list softDeps; + StringHelper::split(package->optionals(), ',', softDeps); + list::iterator it = softDeps.begin(); + for (; it != softDeps.end(); ++it) { + if ( m_pkgDB->isInstalled(*it, true) ) { + const Package* p = m_repo->getPackage( *it ); + if (p) { + printDepsLevel(indent+2,p,true); + if (!m_parser->all()) { + shownMap[*it] = true; + } + } else { + cout << " (not found in ports tree)" << endl; + } + } + } + } + + // reset the tree traversal history + treeWalk.pop_back(); } void PrtGet::dumpConfig() diff --git a/src/prtget.h b/src/prtget.h index 8e5ad1f..db3d2ab 100644 --- a/src/prtget.h +++ b/src/prtget.h @@ -97,7 +97,7 @@ public: protected: - void printDepsLevel(int indent, const Package* package); + void printDepsLevel(int indent, const Package* package, bool greedy); void printDependent(const std::string& dep, int level); @@ -138,6 +138,8 @@ protected: int m_returnValue; bool m_useRegex; + bool m_followSoftdeps; + vector treeWalk; /*! Name of default configuration file */ static const string CONF_FILE; diff --git a/src/repository.cpp b/src/repository.cpp index 02562a4..50ccc68 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -264,7 +264,7 @@ Repository::initFromCache( const string& cacheFile ) // FIELDS: // name, path, version, release, // description, dependencies, url, - // packager, maintainer, hasReadme; + // optionals, maintainer, hasReadme; // hasPreInstall, hasPostInstall const int fieldCount = 12; string fields[fieldCount]; @@ -351,7 +351,7 @@ Repository::WriteResult Repository::writeCache( const string& cacheFile ) p->description().c_str(), p->dependencies().c_str(), p->url().c_str(), - p->packager().c_str(), + p->optionals().c_str(), p->maintainer().c_str(), hasReadme, hasPreInstall, hasPostInstall ); }