Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Aug 1999 13:14:50 +0200
From:      Neil Blakey-Milner <nbm@mithrandr.moria.org>
To:        ports@FreeBSD.org
Subject:   relative versioning algorithm?
Message-ID:  <19990811131450.A5833@rucus.ru.ac.za>

next in thread | raw e-mail | index | archive | help
Hi,

I'm quite sure many people use pkg_version to give an indication as
to what packages installed are up-to-date with regards to the current
INDEX.

One problem at the moment is that it can't handle multiple packages
(either installed, or in the index).

I'd like to know whether people agree with my method of resolving the case
where you have a package installed, and there are multiple versions of that
package in the INDEX. (for example, gtk, glib, ssh, bash).

Here is the relative bits of my idea:

# @iv - array of versions in the index
# @cv - array of versions installed
    @iv = split /,/, $indexVersion;
    @cv = split /,/, $currentVersion;

    $b = -1;
    while (++$b < $currentRefcount) {

# quick check to see if the installed version is the same as a version
# found in the index.  If we find one, say so, and go on to the next
# installed package.
	for ($a = 0; $a < $indexRefcount; $a++) {
	    $rc = &CompareVersions(@cv[$b], @iv[$a]);
	    last if $rc == 0;
	}
	if ($rc == 0) {
	    print "=";
	    if ($VerboseFlag) {
		print " up-to-date";
	    }
	    next;
	}

# check if there are multiple versions of the package in the INDEX, and
# if so, find the one which most matches the installed version
	if ($indexRefcount > 1) {
	    for ($a = 0; $a < $indexRefcount; $a++) {
		$pos = 1;
		$mys = $iv[$a];
		$r = 0;
		while ($r == 0) {
		    $ss = substr($cv[$b], 0, $pos);
		    $r = index($mys, $ss, 0);
		    $pos++;
		}
		$pos{$iv[$a]} = $pos;
	    }
	    @sorted = sort {$pos{$b} cmp $pos{$a} } @iv;
	    $best = @sorted[0];
	    $secondbest = @sorted[1];
	}

# otherwise, the only version in the INDEX is the most matched.
	else {
	    $best = $indexVersion;
	    $pos{$best} = 1;
	}

	$rc = &CompareVersions(@cv[$b], $best);

# it's possible the versions don't match at all (installed 2.9.9, and
# INDEX has 3.0.1), but this check only passes if there are more than
# one version in the INDEX.  Then go to next installed package.
	if ($pos{$best} == 0) {
	    print "?";
	    if ($VerboseFlag) {
		print " ambiguous choice ($indexVersion)";
	    }
	    next;
	}

# if there are more than one version in the INDEX, and the top two
# matches to the installed version are equally matched, scream that the
# user has to choose from two equally likely versions
	if (($indexRefcount > 1) && ($pos{$best} eq $pos{$secondbest})) {
	    print "?";
	    if ($VerboseFlag) {
		print " ambiguous choice ($indexVersion)";
	    }
	} elsif ($rc < 0) {
	    print "<";
	    if ($VerboseFlag) {
		printf " needs updating (index has %s)", "$best";
	    }
	} else {
	    print ">";
	    if ($VerboseFlag) {
		printf " succeeds index (index has %s)",
		    "$best";
	    }
	}
    }

So, basically, the algorithm checks if there exists a version in the INDEX
the exact same as the one installed, and says "up-to-date" if this is true.

If not, find the version in the INDEX that is most like the installed
version.

For example, for ssh 1.2.26, 1.2.27 matches 5 characters, whilst 2.0.12
matches 0 characters, and for gtk 1.2.1, gtk 1.2.3 matches 4 characters
whilst gtk 1.1.13 matches just 2 characters.

Then give a rating relative to the best match.  If two options match
equally well, give an "ambiguous" return.

As an example, here's an edited result of current pkg_version:

bash-2.03            ? multiple versions (index has 1.14.7,2.03)
docbook-241,3.0,3.1,1.0 ? multiple versions (index has 1.0,241,3.0,3.1)
ncftp-3.0b16         ? multiple versions (index has 1.9.5,2.4.3,3.0b19)
ssh-1.2.26           ? multiple versions (index has 1.2.27,2.0.13)
tcl-8.0.4            ? multiple versions (index has 7.5.1,7.6,8.0.5,8.1)

The same result using my patches:

bash-2.03                           = up-to-date
docbook-241                         = up-to-date
docbook-3.0                         = up-to-date
docbook-3.1                         = up-to-date
docbook-1.0                         = up-to-date
ncftp-3.0b16                        < needs updating (index has 3.0b19)
ssh-1.2.26                          < needs updating (index has 1.2.27)
tcl-8.0.4                           < needs updating (index has 8.0.5)

As you can see, this also seems to solve the case of having multiple
packages installed at different versions, which can survive together at
the same time (gtk, glib, ssh, docbook, and so forth as examples).

My question, really, is whether this sort of algorithm is well behaved,
and whether it would always give useful results?  I think it could be
a step towards "automated" ports/package updating, as we get questions
about once in a while. (ie, it determines you have tcl-8.0.4, and finds
out tcl-8.0.5 is out, and goes out and tries to install it, failing
dismally due to it being required by tk80)

(and yes, I'm sending patches to the pkg_version person)

Neil
-- 
Neil Blakey-Milner
nbm@rucus.ru.ac.za


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990811131450.A5833>