Utilize the "-o" (origin) option recently added to pkg_create(1)

and pkg_info(1), for more accurate determination of the
"up-to-date-ness" of installed packages.
This commit is contained in:
Bruce A. Mah 2000-10-25 17:10:20 +00:00
parent dcafb17498
commit 131291ba1c
2 changed files with 149 additions and 51 deletions

View File

@ -42,27 +42,55 @@ The
command is used to produce a report of non-base software packages
installed using the
.Xr pkg_add 1
command. Version numbers are compared against an
index file, to see which packages might need updating.
command.
.Pp
Each package's version number is checked against one of two sources to
see if that package may require updating. If the package contains
information about its origin in the
.Fx
ports tree, and a version number can be determined from the port's
.Pa Makefile ,
then the version number from the
.Pa Makefile
will be used to determine whether the installed package is up-to-date
or requires updating.
.Pp
If no origin for a package can be found, or if the port's
.Pa Makefile
cannot be located,
.Nm
will search for the package in the ports collection index file
(typically
.Pa /usr/ports/INDEX ).
Any matching version number(s) there will be used to determine whether
the installed package is up-to-date or requires updating.
.Pp
Generally, using the version number from a port's
.Pa Makefile
will provide a more accurate result, since, unlike the index file, it
provides an unambiguous current version number, even when multiple
versions of a port exist in the ports collection.
Moreover, the ports collection index file is only updated at
intervals, meaning that it may not completely reflect the version
numbers of the software contained in the ports collection.
.Pp
Each package name is printed, along with a one-character status flag:
.Bl -tag -width indent
.It Li =
The installed version of the package matches the index.
The installed version of the package is current.
.It Li <
The installed version of the package is older than the version listed
in the index.
The installed version of the package is older than the current version.
.It Li >
The installed version of the package is newer than listed in the
index.
The installed version of the package is newer than the current version.
This situation can arise with an out-of-date index file, or when
testing new ports.
.It Li ?
The installed package does not appear in the index.
This could be due to an out of date index or a package taken from a PR
that has not yet been committed.
.It Li *
There are multiple versions of a particular software package
installed or there are multiple versions of a package listed in
the index file.
listed in the index file.
Examples from the
.Fx
ports collection are the Tcl toolkit or the
@ -81,14 +109,26 @@ supports several command-line arguments:
Enable commands output. Commands output includes the commands you should
type to update your installed packages to the latest versions in the ports
system.
This feature does
.Bf Em
not
.Ef
constitute an automated packages updating system.
The output of this command
.Bf Em
must
.Ef
be edited, in order to avoid destroying dependencies between installed
packages.
.It Fl d
Enable debugging output.
.It Fl h
Print help message.
.It Fl l
Limit the output to those packages whose status flag matches
Limit the output to those packages whose status flag matches the
character(s) in
.Ar limchar .
You may specify more than one character to match in
More than one character can be specified in
.Ar limchar .
Note that because some of the status flag characters are also special
to the shell, it is best to quote
@ -145,13 +185,16 @@ the version numbers in the on-line ports collection:
.Pp
The command below generates a file of commands to run to update the installed
files.
It is
These commands must
.Bf Em
not
.Ef
suggested that you run these commands automatically.
Always review the
suggestions, and then cut-and-paste (or retype) the commands you want to run.
be run without suitable editing.
They should be treated as suggestions, and may need to be reordered
to account for dependencies between installed packages, or may need to
be disregarded if multiple versions of an installed package can coexist.
Blindly running the output of this command may leave a system in an
unusable state.
.Pp
.Dl % pkg_version -c > do_update
.Sh AUTHOR
@ -162,22 +205,18 @@ suggestions, and then cut-and-paste (or retype) the commands you want to run.
.An Mark Ovens Aq marko@FreeBSD.org ,
.An Doug Barton Aq DougB@gorean.org
.Sh BUGS
There should be a better way of dealing with packages that
can have more than one installed version.
.Pp
Patch levels aren't handled
very well (i.e. version numbers of the form 1.2p3 or 1.2pl3).
.Pp
Updates to packages
that don't change the version number (e.g. small delta bugfixes in the
package/port itself) aren't detected.
.Pp
Commands output doesn't know about dependencies between packages.
For
example, you might have two versions of Tcl installed because two other
packages require the different versions.
.Nm
will suggest removing the out-of-date version.
The commands output feature is
.Bf Em
not
.Ef
an automated ports/packages updating system.
It does not even attempt to handle dependencies between installed
packages correctly, and can produce incorrect results if multiple
versions of a package can coexist on a system.
.Pp
Commands output assumes you install new software using the ports system,
rather than using

View File

@ -31,6 +31,7 @@
# $FreeBSD$
#
use Cwd;
use Getopt::Std;
#
@ -40,8 +41,11 @@ $Version = '0.1';
$CurrentPackagesCommand = '/usr/sbin/pkg_info -aI';
$CatProgram = "cat ";
$FetchProgram = "fetch -o - ";
$OriginCommand = '/usr/sbin/pkg_info -qo';
$GetPortVersionCommand = 'make -V PORTVERSION';
#$IndexFile = "ftp://ftp.freebsd.org/pub/FreeBSD/branches/-current/ports/INDEX";
$PortsDirectory = '/usr/ports';
$IndexFile = '/usr/ports/INDEX';
$ShowCommandsFlag = 0;
$DebugFlag = 0;
@ -198,7 +202,7 @@ Usage: pkg_version [-c] [-d debug] [-h] [-v] [index]
-d debug Debugging output (debug controls level of output)
-h Help (this message)
-l limchar Limit output to status flags that match
-L limchar Limit output to status flags that DON'T match
-L limchar Limit output to status flags that DON\'T match
-v Verbose output
index URL or filename of index file
(Default is $IndexFile)
@ -243,7 +247,7 @@ else {
}
#
# Slurp in files
# Get the current list of installed packages
#
if ($DebugFlag) {
print STDERR "$CurrentPackagesCommand\n";
@ -254,17 +258,48 @@ while (<CURRENT>) {
($packageString, $rest) = split;
($packageName, $packageFullversion) = &GetNameAndVersion($packageString);
$currentPackages{$packageName}{'name'} = $packageName;
if (defined $currentPackages{$packageName}{'fullversion'}) {
$currentPackages{$packageName}{'fullversion'} .= "|" . $packageFullversion;
}
else {
$currentPackages{$packageName}{'fullversion'} = $packageFullversion;
}
$currentPackages{$packageName}{'refcount'}++;
$currentPackages{$packageString}{'name'} = $packageName;
$currentPackages{$packageString}{'fullversion'} = $packageFullversion;
}
close CURRENT;
#
# Iterate over installed packages, get origin directory (if it
# exists) and PORTVERSION
#
$dir = cwd();
foreach $packageString (sort keys %currentPackages) {
open ORIGIN, "$OriginCommand $packageString|";
$origin = <ORIGIN>;
close ORIGIN;
# If there is an origin variable for this package, then store it.
if ($origin ne "") {
chomp $origin;
# Try to get the version out of the makefile.
# The chdir needs to be successful or our make -V invocation
# will fail.
chdir "$PortsDirectory/$origin" or next;
open VERSION, "$GetPortVersionCommand|";
$portversion = <VERSION>;
close VERSION;
if ($portversion ne "") {
chomp $portversion;
$currentPackages{$packageString}{'origin'} = $origin;
$currentPackages{$packageString}{'portversion'} = $portversion;
}
}
}
chdir "$dir";
#
# Slurp in the index file
#
if ($DebugFlag) {
print STDERR "$IndexPackagesCommand\n";
}
@ -296,24 +331,49 @@ close INDEX;
# to commas before we output anything so the reports look the
# same as they did before.
#
foreach $packageName (sort keys %currentPackages) {
foreach $packageString (sort keys %currentPackages) {
$~ = "STDOUT_VERBOSE" if $VerboseFlag;
$~ = "STDOUT_COMMANDS" if $ShowCommandsFlag;
$packageNameVer = "$packageName-$currentPackages{$packageName}{'fullversion'}";
$packageNameVer =~ s/\|/,/g;
$packageNameVer = $packageString;
$packageName = $currentPackages{$packageString}{'name'};
if (defined $indexPackages{$packageName}{'fullversion'}) {
$currentVersion = $currentPackages{$packageString}{'fullversion'};
if (defined $currentPackages{$packageString}{'portversion'}) {
$portVersion = $currentPackages{$packageString}{'portversion'};
$portPath = "$PortsDirectory/$currentPackages{$packageString}{'origin'}";
# Do the comparison
$rc = &CompareVersions($currentVersion, $portVersion);
if ($rc == 0) {
$versionCode = "=";
$Comment = "up-to-date with port";
}
elsif ($rc < 0) {
$versionCode = "<";
$Comment = "needs updating (port has $portVersion)";
}
elsif ($rc > 0) {
$versionCode = ">";
$Comment = "succeeds port (port has $portVersion)";
}
else {
$versionCode = "!";
$Comment = "Comparison failed";
}
}
elsif (defined $indexPackages{$packageName}{'fullversion'}) {
$indexVersion = $indexPackages{$packageName}{'fullversion'};
$currentVersion = $currentPackages{$packageName}{'fullversion'};
$indexRefcount = $indexPackages{$packageName}{'refcount'};
$currentRefcount = $currentPackages{$packageName}{'refcount'};
$packagePath = $indexPackages{$packageName}{'path'};
if (($indexRefcount > 1) || ($currentRefcount > 1)) {
$portPath = $indexPackages{$packageName}{'path'};
if ($indexRefcount > 1) {
$versionCode = "*";
$Comment = "multiple versions (index has $indexVersion)";
$Comment =~ s/\|/,/g;
@ -322,12 +382,11 @@ foreach $packageName (sort keys %currentPackages) {
# Do the comparison
$rc =
&CompareVersions($currentPackages{$packageName}{'fullversion'},
$indexPackages{$packageName}{'fullversion'});
&CompareVersions($currentVersion, $indexVersion);
if ($rc == 0) {
$versionCode = "=";
$Comment = "up-to-date";
$Comment = "up-to-date with index";
}
elsif ($rc < 0) {
$versionCode = "<";
@ -400,7 +459,7 @@ $CommentChar, $Comment
@<
$CommentChar
cd @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$packagePath
$portPath
make && pkg_delete -f @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$packageNameVer
make install