From f7be351e22ba8adb4657953eef891db01b0e74ef Mon Sep 17 00:00:00 2001 From: John McQuah Date: Sun, 3 Sep 2023 16:18:09 -0400 Subject: [PATCH] add support for rmlog_on_uninst --- doc/prt-get.conf.5 | 22 +++++++++++++++++++++- misc/prt-get.conf | 7 ++++--- src/configuration.cpp | 13 +++++++++++++ src/configuration.h | 2 ++ src/prtget.cpp | 43 ++++++++++++++++++++++++++++++++++++++----- 5 files changed, 78 insertions(+), 9 deletions(-) diff --git a/doc/prt-get.conf.5 b/doc/prt-get.conf.5 index bb1327e..0b707d7 100644 --- a/doc/prt-get.conf.5 +++ b/doc/prt-get.conf.5 @@ -128,13 +128,33 @@ 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 use the +feature of deleting a build log when the package is removed, 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 (e.g., you ran \fBpkgmk(8),pkgadd(8)\fP manually and hence updated the +database without using \fBprt\-get(8)\fP, or you kept a package installed +after it had been dropped from the repositories), then those logs will not be +deleted. +With a template like \(dq%p/.buildlogs/%n-%v-%r.log\(dq, uninstalling a package +after having it on your system through many versions, or after it has been +moved from opt to contrib, might leave behind all the build logs except the +latest. See the EXAMPLES section of \fBprt\-get(8)\fP for alternative ways 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); }