diff --git a/ChangeLog b/ChangeLog index 7314782..36d4329 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ -* 22.08.2023 John McQuah +* 31.08.2023 John McQuah +- allow prt-get to remove build log when uninstalling a package (feature +requested by samsep10l) + +* 31.03.2023 John McQuah +- respect the user's choice of --install-root when running pre- or +post-install scripts + +* 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' diff --git a/doc/prt-get.conf.5 b/doc/prt-get.conf.5 index bb1327e..017eca0 100644 --- a/doc/prt-get.conf.5 +++ b/doc/prt-get.conf.5 @@ -128,13 +128,35 @@ replaced with the port's path, e.g. for port gcc in core, %p would be and %n would be .B gcc. This allows you to have separate log files per port. +Separate log files for each version and release can be achieved +using the placeholders %v and %r, respectively. But if you want to enable +\fBrmlog_on_uninst\fP, it is best to avoid %p, %v, and %r when specifying +\fBlogfile\fP (as explained below). + +.B rmlog_on_uninst +which can be set to 'yes' or 'no'; when set to yes, uninstalling a +package will also try to delete its build log. Replacements in the template +\fBlogfile\fP will be made using the \fIcurrent values\fP from the database +of installed packages, and from the active repositories. If log files exist +with different values of %p, %v, or %r than what the database and repositories +provide, then the pattern substitutions will fail to match the names of those +logs, and this feature will be a no-op. For example, suppose you specify the +logfile pattern \(dq%p/.buildlogs/%n-%v-%r.log\(dq, and you have a package +installed on your system through many versions, or after it has been +moved from opt to contrib. Uninstalling that package would leave behind all the +build logs except the latest. This pattern is also fragile with respect to +repository purges; if one of your installed ports is dropped from the official +repos, then either \(dq%p\(dq will expand to the path of your personal overlay +(you did make a copy, right?), or it will not expand at all! See the EXAMPLES +section of \fBprt\-get(8)\fP for an alternative way to tidy up your directory +of build logs. .B readme can be set to 'disabled', to suppress the notification after installing a port with a README file; 'compact', to collect all the READMEs into one post-transaction output; or 'verbose', to print separate information about each port with a README file. See -.B prt-get(8) +.B prt\-get(8) and especially the readme command how to read those README files using prt-get. diff --git a/misc/prt-get.conf b/misc/prt-get.conf index 66a1bef..e1d2361 100644 --- a/misc/prt-get.conf +++ b/misc/prt-get.conf @@ -17,10 +17,11 @@ prtdir /usr/ports/opt ### log options: # writelog enabled # (enabled|disabled) # logmode overwrite # (append|overwrite) -# rm_on_success no # (yes|no) +# rmlog_on_success no # (yes|no) +# rmlog_on_uninst no # (yes|no) logfile /var/log/pkgbuild/%n.log - # path, %p=path to port dir, %n=port name - # %v=version, %r=release + # %n=port name, %v=version, %r=release + # %p=path to repository ### print README information: # readme verbose # (verbose|compact|disabled) diff --git a/src/configuration.cpp b/src/configuration.cpp index cecf795..3241c65 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -30,6 +30,7 @@ Configuration::Configuration( const std::string& configFile, m_writeLog( false ), m_appendLog( false ), m_removeLogOnSuccess( false ), + m_removeLogOnUninst( false ), m_readmeMode( VERBOSE_README ), m_runScripts( false ), m_preferHigher( false ), @@ -85,6 +86,11 @@ bool Configuration::removeLogOnSuccess() const return m_removeLogOnSuccess; } +bool Configuration::removeLogOnUninst() const +{ + return m_removeLogOnUninst; +} + string Configuration::logFilePattern() const { return m_logFilePattern; @@ -191,6 +197,13 @@ void Configuration::parseLine(const string& line, bool prepend) } else if ( s == "no" ) { m_removeLogOnSuccess = false; } + } else if ( startsWithNoCase( s, "rmlog_on_uninst" ) ) { + s = stripWhiteSpace( s.replace( 0, 15, "" ) ); + if ( s == "yes" ) { + m_removeLogOnUninst = true; + } else if ( s == "no" ) { + m_removeLogOnUninst = false; + } } else if ( startsWithNoCase( s, "readme" ) ) { s = stripWhiteSpace( s.replace( 0, 6, "" ) ); if ( s == "compact" ) { diff --git a/src/configuration.h b/src/configuration.h index f358b25..d8506cb 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -30,6 +30,7 @@ public: bool writeLog() const; bool appendLog() const; bool removeLogOnSuccess() const; + bool removeLogOnUninst() const; std::string logFilePattern() const; const std::list< std::pair >& rootList() const; @@ -71,6 +72,7 @@ private: bool m_writeLog; bool m_appendLog; bool m_removeLogOnSuccess; + bool m_removeLogOnUninst; ReadmeMode m_readmeMode; diff --git a/src/prtget.cpp b/src/prtget.cpp index dbf568e..7806635 100644 --- a/src/prtget.cpp +++ b/src/prtget.cpp @@ -1927,12 +1927,17 @@ void PrtGet::remove() { assertMinArgCount(1); + bool needRepo = false; list removed; list failed; list notInstalled; if ( m_parser->isTest() ) { cout << "*** " << m_appName << ": test mode" << endl; + } else if ( m_config->removeLogOnUninst() + && m_config->logFilePattern().find("%p") != string::npos ) { + needRepo = true; + initRepo(); } string command = InstallTransaction::PKGRM_DEFAULT_COMMAND; @@ -1944,20 +1949,48 @@ void PrtGet::remove() list::const_iterator it = args.begin(); for ( ; it != args.end(); ++it ) { if (m_pkgDB->isInstalled(*it)) { - // TODO: prettify - string args = ""; + string rm_args = ""; if (m_parser->installRoot() != "") { - args = "-r " + m_parser->installRoot() + " "; + rm_args = "-r " + m_parser->installRoot() + " "; } - args += (m_parser->pkgrmArgs() + " " + *it); + rm_args += (m_parser->pkgrmArgs() + " " + *it); - Process proc(command, args); + Process proc(command, rm_args); if (m_parser->isTest() || proc.executeShell() == 0) { removed.push_back(*it); if (m_locker.isLocked(*it)) { m_locker.unlock(*it); m_locker.store(); } + if (m_config->removeLogOnUninst() && !m_parser->isTest()) { + string rm_logFile = m_config->logFilePattern(); + bool doneSubs=false; + const string pkgname = *it; + StringHelper::replaceAll( rm_logFile, "%n", pkgname ); + const string rm_ver = m_pkgDB->getPackageVersion( pkgname ); + size_t pos = rm_ver.find_last_of('-'); + if (pos != string::npos) { + const string rm_v = rm_ver.substr(0,pos); + const string rm_r = rm_ver.substr(pos+1); + StringHelper::replaceAll( rm_logFile, "%v", rm_v ); + StringHelper::replaceAll( rm_logFile, "%r", rm_r ); + } + if (! needRepo) { + doneSubs=true; + } else if (m_repo->getPackage( pkgname )) { + StringHelper::replaceAll( rm_logFile, "%p", + m_repo->getPackage( pkgname )->path() ); + doneSubs=true; + } else { + cout << "Warning: unable to determine the logfile for " + + pkgname + "; log removal aborted." << endl; + } + struct stat slF; + if ( doneSubs && stat(rm_logFile.c_str(), &slF)==0 + && (slF.st_mode & S_IFMT)==S_IFREG ) { + unlink( rm_logFile.c_str() ); + } + } } else { failed.push_back(*it); }