jasonc has asked for the wisdom of the Perl Monks concerning the following question:

Hello everybody :)

I've been trying to write some scripts to compare versions of packages, mainly RPM package names. I wrote something that can compare two versions together, but it's quite sloppy and doesn't work if there are letters involved in a package name. I was wondering if there is anybody else out there that has done something similar?

I'd be looking to compare something like mozilla-1.4.2-3.0.2 and mozilla-1.4-3.0.18 or something like mozilla-1.4.2r-3.0.2 and mozilla-1.4g-3.0.18. I'm sure you get the idea. Thanks.

Replies are listed 'Best First'.
Re: Version checking
by tachyon (Chancellor) on Sep 30, 2004 at 04:32 UTC

    The basic approach to this sort of problem is to normalize the strings so you can just do a simple alphabetic sort on them. This means padding out the data so that the sort will work correctly. I am not sure exactly how the letters are supposed to sort but something like this will get you on track.

    @data = qw( mozilla-1.4.2-3.0.2 mozilla-1.40-3.0.18 mozilla-1.4.2r-3.0 +.2 mozilla-1.4g-3.0.18 mozilla-1.4.1-3.0.2 mozilla-1.4-3.0.7 mozilla-1.4g-3.1.18 mozilla-1.4-3.0.1 mozilla-1.4-3.0.71 mozilla-1.4.2s-3.0.2 mozilla-1.4-3.0.18 mozilla-1.4a-3.0.1 +8 ); @data = map{[ normalize($_), $_]}@data; @data = sort { $a->[0] cmp $b->[0] } @data; printf "%s\t%s\n", $_->[0], $_->[1] for @data; sub normalize { my $str = shift; $str =~ s/(\-\w+\.\w+)\-/$1.0-/; #return join '', map{ sprintf "%3s", $_ }split m/[\-\.]/, $str; return join '', map{ s/^(\d+)(\w*)$/sprintf "%3s%1s", $1, $2?$2:' +'/e; $_ }split m/[\-\.]/, $str; } __DATA__ mozilla 1 4 0 3 0 1 mozilla-1.4-3.0.1 mozilla 1 4 0 3 0 7 mozilla-1.4-3.0.7 mozilla 1 4 0 3 0 18 mozilla-1.4-3.0.18 mozilla 1 4 0 3 0 71 mozilla-1.4-3.0.71 mozilla 1 4 1 3 0 2 mozilla-1.4.1-3.0.2 mozilla 1 4 2 3 0 2 mozilla-1.4.2-3.0.2 mozilla 1 4 2r 3 0 2 mozilla-1.4.2r-3.0.2 mozilla 1 4 2s 3 0 2 mozilla-1.4.2s-3.0.2 mozilla 1 4a 0 3 0 18 mozilla-1.4a-3.0.18 mozilla 1 4g 0 3 0 18 mozilla-1.4g-3.0.18 mozilla 1 4g 0 3 1 18 mozilla-1.4g-3.1.18 mozilla 1 40 0 3 0 18 mozilla-1.40-3.0.18

    cheers

    tachyon

Re: Version checking
by dragonchild (Archbishop) on Sep 29, 2004 at 19:53 UTC
    Why? Redhat already has this code written. Look at the RPM manager(s) that come with Fedora Core. You might have to read some Python, but you might get lucky - Inline::Python can help you out.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      Mainly because I'll need to test other things other than just Red Hat systems, I'll also need to test versions on AIX, Solaris, and other Linux systems.
        The fact that RedHat (and most other vendors) wrote this code has no bearing on what systems the code will run. I meant to say that you should sourcedive the RPM manager and lift the version-checking code from it. (Or apt-get, if you're Debian-inclined.)

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: Version checking
by Anonymous Monk on Sep 30, 2004 at 06:07 UTC