From d9ec1c1e98b475604fa4e299dbe77348885bf6a9 Mon Sep 17 00:00:00 2001 From: John McQuah Date: Mon, 4 Sep 2023 15:58:51 -0400 Subject: [PATCH] add support for rmlog_on_uninst --- ChangeLog | 8 ++++++++ doc/prt-get.8 | 21 ++++++++++++++++---- doc/prt-get.conf.5 | 22 +++++++++++++++++++++ misc/prt-get.conf | 3 ++- src/configuration.cpp | 13 +++++++++++++ src/configuration.h | 2 ++ src/prtget.cpp | 45 ++++++++++++++++++++++++++++++++++++------- 7 files changed, 102 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index d6567f7..36d4329 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +* 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 diff --git a/doc/prt-get.8 b/doc/prt-get.8 index 9e8272e..c66681d 100644 --- a/doc/prt-get.8 +++ b/doc/prt-get.8 @@ -777,6 +777,16 @@ reasonably up-to-date system, the two processes in the above command will return many identical lines; these are suppressed by the -3 flag to \fBcomm(1)\fP. +.TP +.B for L in /var/log/pkgbuild/*.log; do P=${L%__*}; P=${P##*/}; VR=${L##*__}; VR=${VR%.log}; if ! prt\-get isinst $P >/dev/null; then mv $L /var/log/uninstalled/; elif [ \(dq$(prt\-get current $P)\(dq != \(dq$VR\(dq ]; then mv $L /var/log/oldbuild/; fi; done +(based on a feature request by samsep10l) a command you can put into a script +called by root's crontab, in order to mimic Slackware's tidy directory listings +(the main logdir only contains build logs of the latest installed packages; +other logs are moved to a separate directory). This particular command relies +on declaring \(dqlogfile /var/log/pkgbuild/%n__%v-%r.log\(dq and \(dqwritelog +enabled\(dq in \fBprt\-get.conf(5)\fP. Logs saved with a different filename +pattern will require slight adjustments to the command. + .TP .B prt\-get printf \(dq%p\et%u\en\(dq | awk '($1 ~ /\e/myrepo$/) { print $2 }' Print the upstream URL for each port in the collection \(dqmyrepo\(dq, perhaps @@ -786,10 +796,13 @@ as the first step in keeping your personal overlay up to date. .B prt\-get printf \(dq%M\et%n\en\(dq | grep \-c ^Tim Count how many ports our most-overworked core team member claims responsibility for. -.TP -.B comm \-13 <(prt\-get depends firefox\-bin |tail \-n +2 |sort) <(prt\-get depends firefox |tail \-n +2 |sort) -Find the build-time dependencies of firefox. Runtime dependencies would also appear in the list generated by -the first process substitution, and \fBcomm -13\fP will suppress what the two lists have in common. +.TP +.B for u in $(prt\-get printf \(dq%M:%p/%n\en\(dq | grep \-i ^unmaintained | cut \-d: \-f2); do cd ${u%/*}; printf \(dq||%s ||\(dq ${u##*/}; git log ${u##*/} | head \-n 5 | awk '/^Date/ { $0=gensub(/^Date:\es+/,"","g"); printf(\(dq %s ||\en\(dq,$0); }'; cd \- >/dev/null; done +Generate a table of unmaintained ports and the dates of their most recent +commit, in PmWiki syntax (left-justified port names, centered dates). +Requires that your repositories are synchronized using the \fBgit(1)\fP driver. +Subsequent sorting by date may be done using \fBsort(1)\fP with the flags +-k, -M, and -n (the appropriate key defs will depend on your locale). .TP .B prt\-get listinst \-\-depsort | xargs prt\-get install \-\-install\-root=/mnt diff --git a/doc/prt-get.conf.5 b/doc/prt-get.conf.5 index bb1327e..07fc8b0 100644 --- a/doc/prt-get.conf.5 +++ b/doc/prt-get.conf.5 @@ -128,6 +128,28 @@ 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 diff --git a/misc/prt-get.conf b/misc/prt-get.conf index 66a1bef..054936f 100644 --- a/misc/prt-get.conf +++ b/misc/prt-get.conf @@ -17,7 +17,8 @@ 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 diff --git a/src/configuration.cpp b/src/configuration.cpp index 6cd1e7a..04c4006 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 ), @@ -84,6 +85,11 @@ bool Configuration::removeLogOnSuccess() const return m_removeLogOnSuccess; } +bool Configuration::removeLogOnUninst() const +{ + return m_removeLogOnUninst; +} + string Configuration::logFilePattern() const { return m_logFilePattern; @@ -171,6 +177,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 3b69ff6..20052be 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; @@ -67,6 +68,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 6a8be63..a11a639 100644 --- a/src/prtget.cpp +++ b/src/prtget.cpp @@ -1921,12 +1921,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; @@ -1938,20 +1943,46 @@ void PrtGet::remove() list::const_iterator it = args.begin(); for ( ; it != args.end(); ++it ) { if (m_pkgDB->isInstalled(*it)) { - // TODO: prettify - string args = ""; - if (m_parser->installRoot() != "") { - args = "-r " + m_parser->installRoot() + " "; - } - args += (m_parser->pkgrmArgs() + " " + *it); + string rm_args = (m_parser->installRoot() == "") ? "" : + "-r " + m_parser->installRoot() + " "; + 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); }