From dfa2edaa0c1e34083d721720afcc1d8842f1891a Mon Sep 17 00:00:00 2001 From: bmah Date: Wed, 25 Oct 2000 17:10:20 +0000 Subject: 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. --- usr.sbin/pkg_install/version/pkg_version.1 | 93 +++++++++++++++++------- usr.sbin/pkg_install/version/pkg_version.pl | 107 +++++++++++++++++++++------- 2 files changed, 149 insertions(+), 51 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/pkg_install/version/pkg_version.1 b/usr.sbin/pkg_install/version/pkg_version.1 index 9e21135..1720034 100644 --- a/usr.sbin/pkg_install/version/pkg_version.1 +++ b/usr.sbin/pkg_install/version/pkg_version.1 @@ -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 diff --git a/usr.sbin/pkg_install/version/pkg_version.pl b/usr.sbin/pkg_install/version/pkg_version.pl index b4852c0..9b1c4df 100755 --- a/usr.sbin/pkg_install/version/pkg_version.pl +++ b/usr.sbin/pkg_install/version/pkg_version.pl @@ -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 () { ($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 = ; + 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 = ; + 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'}; - $indexVersion = $indexPackages{$packageName}{'fullversion'}; - $currentVersion = $currentPackages{$packageName}{'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'}; $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 -- cgit v1.1