Welcome to CRUX bug tracking.

FS#1930 - 'prt-get diff ' sticks together long name of port and version

Attached to Project: CRUX
Opened by Feodor Petrov (teodor) - Friday, 24 March 2023, 11:31 GMT
Task Type Bug Report
Category tools → prt-get
Status New
Assigned To No-one
Operating System CRUX
Severity Low
Priority Normal
Reported Version 3.7
Due in Version Undecided
Due Date Undecided
Percent Complete 0%
Votes 0
Private No


# prt-get diff
Differences between installed packages and ports tree:

Port Installed Available in the ports tree

gobject-introspection1.74.0-1 1.76.1-1
grep 3.9-1 3.10-1
tzdata 2022g-1 2023a-1

There should be at least one space after 'gobject-introspection' for normal parsing.
This task depends upon

Comment by John McQuah (farkuhar) - Saturday, 25 March 2023, 01:24 GMT
in retrospect the decision to hard-code a field width at 20 characters has not held up well. Inevitably there would be port names exceeding the hard-coded width, leading to the spacing issues teodor observed.

One solution is to patch the responsible function (printFormattedDiffLine in prtget.cpp) by choosing a larger arbitrary field width, but then in another few years we might see a port whose name exceeds that character count too. A more robust solution is to count the characters in the first argument (const string& name) and pad with one space if it exceeds the hard-coded field width (20 chars should still be good enough for the majority of ports).

In my recent fork, I generalized the "prt-get current" command to accept more than one argument, so a temporary workaround if you want machine-parseable output would use two prt-get processes and one comm:
comm -3 <(prt-get printf "%n: version %v-%r\n" | grep -E '^(gobject-introspection|grep|tzdata)') <(prt-get current gobject-introspection grep tzdata)

Using official versions of the tools, the latter process substitution would fail, so you can do it this way:
comm -3 <(prt-get printf "%n %v-%r\n" | grep -E '^(gobject-introspection|grep|tzdata)') <(pkginfo -i | grep -E '^(gobject-introspection|grep|tzdata)')

Anyway, I think it's an easy and worthwhile fix to perform the character count inside printFormattedDiffLine, so I'll work on a patch and push it to my forked repo.
Comment by John McQuah (farkuhar) - Saturday, 25 March 2023, 02:25 GMT
Another machine-parseable workaround, if you don't already know which ports are out of date:
comm -3 <(prt-get printf "%i:%n %v-%r\n" | grep -E -v '^no' | cut -d: -f2 | sort) <(pkginfo -i | sort)
Left-justified output from this command shows the version in the repositories, while indented lines show the version installed. The flag -3 suppresses all the identical lines returned by the two processes, leaving only the differences.

As for the patch to printFormattedDiffLine, here's what I threw together just now. I haven't tested it on an out-of-date system yet, but will do so before pushing the change to my repo.

void PrtGet::printFormattedDiffLine(const string& name,
const string& versionInstalled,
const string& versionPortsTree,
bool isLocked)
+ unsigned int minWidth=20;
cout.setf( ios::left, ios::adjustfield );
- cout.width( 20 );
+ cout.width( minWidth );
cout.fill( ' ' );
- cout << name;
+ ( name.size() < minWidth ) ? cout << name : cout << name + " ";

- cout.width( 20 );
+ cout.width( minWidth );
cout.fill( ' ' );
- cout << versionInstalled;
+ ( versionInstalled.size() < minWidth ) ? cout << versionInstalled
+ : cout << versionInstalled + " ";

string locked = "";
if ( isLocked ) {
locked = "locked";
- cout.width( 20 );
+ cout.width( minWidth );
cout.fill( ' ' );
cout << versionPortsTree << locked << endl;