#!perl -w

# starversion - report version number of a Starlink package

# History:
#   2000 May 30 (TIMJ)
#     First version

use strict;

use Starlink::Versions qw/ starversion starversion_string starversion_cmp/;
use Starlink::Config;
use File::Spec;
use Getopt::Long;
use Pod::Usage;

# Globals
use vars qw/ $VERSION /;

$VERSION = '0.05';

# Parse options
my %options = ();
GetOptions(\%options,
	   'help|?', 'man', 'version', 'compare=s',
	   'major', 'minor', 'patchlevel', 'all',
	   ) or pod2usage(2);

pod2usage(1) if $options{'help'};
pod2usage(-verbose => 2) if $options{'man'};

if ($options{'version'}) {
  print "starversion v$VERSION\n";
  exit;
}

# Array to hold the package names
my @list;

# if we have set -all then we need to determine the list ourselves
if ($options{'all'}) {
  my $dir = File::Spec->catdir($StarConfig{'Star'}, 'dates');
  opendir(DATES, $dir) or die "Failed to open directory $dir with -all: $!\n";
  # Loop over all the files, storing the valid ones
  foreach (sort readdir(DATES)) {
    if (/_datestamp$/) {
      s/_datestamp$//;
      push(@list, $_);
    }
  }

} else {
  @list = @ARGV;
}


# If there are some arguments, assume they are package names
if (@list) {

  # Loop over all the supplied arguments
  foreach my $app (@list) {
  
    # Get the version information
    my ($major, $minor, $patchlevel) = starversion($app);
    my $string = starversion_string($app);

    # Print the application name if we have more than one argument
    printf "%-15s", uc($app).':' if @list > 1;

    # If we are doing a comparison we do that now
    if ($options{'compare'}) {

      # This can return undef - add some -w protection
      my $cmp = starversion_cmp($app, $options{'compare'});
      print $cmp if defined $cmp;

    } else {
      # simply want the version number reported.

      # First check for major and minor specified
      # then check for major, minor or patchlevel
      if ($options{'major'} && $options{'minor'}) {
	print (defined $major ? "$major.$minor" : 'UNKNOWN');
      } elsif ($options{'major'}) {
	print (defined $major ? $major : 'UNKNOWN');
      } elsif ($options{'minor'}) {
	print (defined $minor ? $minor : 'UNKNOWN');
      } elsif ($options{'patchlevel'}) {
	print (defined $patchlevel ? $patchlevel : 'UNKNOWN');
      } else {
	print (defined $string ? $string : 'UNKNOWN');
      }
    }

    # Print the newline
    print "\n";

  }

} else {
  # Try  to open /star/admin/status
  my $status = File::Spec->catfile( $StarConfig{'Star'}, 'admin', 'status');

  # Open it if we can, else forget it
  open(STATUS, "< $status") or die "Could not open file $status\n";

  my @lines = <STATUS>;
  close(STATUS);
  print $lines[$#lines];

}




__END__

=head1 NAME

starversion - report version number of a Starlink package

=head1 SYNOPSIS

 starversion kappa
 starversion -major kappa figaro
 starversion -all

 starversion -compare V0.15-5 kappa

 starversion
 starversion -h

=head1 DESCRIPTION

This program can be used to determine the version number
of a Starlink package (application or library). It can return
the 3 parts of the version number (major version, minor version
and patchlevel) separately or as a string of the form "Vm.n-p".

If a single package is given as argument the version number
is printed to the screen with no other information allowing the
output to be used in scripts.

 % starversion kappa
 V0.15-2

 % starversion -major kappa
 0

 % starversion -minor kappa
 15

 %starversion -major -minor kappa
 0.15

If more than one Starlink package is listed, version information
is printed for each along with the name of the application.

 % starversion kappa figaro
 KAPPA:  V0.15-2
 FIGARO: V5.5-1

 % starversion -minor kappa figaro
 KAPPA:  15
 FIGARO: 5

If a version number can not be determined, it is returned as C<unknown>

 % starversion kappa blah
 KAPPA: V0.15-5
 BLAH:  UNKNOWN

Additionally, the program can be used to compare the version of 
an installed package with a supplied version number via the
C<-compare> flag.

 % starversion -compare V0.15-2 kappa
 1

When comparing, C<starversion> returns 0 if the version numbers match,
1 if the supplied version number is less than that of the installed
package and -1 if the supplied version number is greater than the
installed package.


If no application is specified, the program prints the current status
of the Starlink installation as stored in the C</star/admin/status>.
This contains the last time the system was updated.



=head1 ARGUMENTS

The following arguments are supported.

=over 4

=item B<-major>

Print the major version number only. Can be used in conjunction with
B<-minor> in order to print the first part of the version number.
Overrides the use of B<-patchlevel>.

=item B<-minor>

Return the minor version number only. Can be used in conjunction
with B<-major> in order to print the first part of the version number.
Overrides the use of B<-patchlevel>.

=item B<-patchlevel>

Return the patchlevel only. Can not be used in conjunction with
B<-major> or B<-minor>.

=item B<-all>

List version numbers for all packages listed in C<$STARLINK/dates>.
This overrides any list of packages supplied on the command-line.

=item B<-compare>

Compare the supplied version string with that of a package.

 % starversion -compare V1.2-3 figaro

When comparing, C<starversion> returns 0 if the version numbers match,
1 if the supplied version number is less than that of the installed
package and -1 if the supplied version number is greater than the
installed package.

The version string format can be one of:

 V1.2-3
 V1.2.3
 1.2-3

The 'V' can be upper or lower case.

=item B<-help>

Print a help message.

=item B<-man>

This documentation.

=item B<-version>

Version number of C<starversion>.

=back

=head1 AUTHOR

Tim Jenness. Copyright (C) 2000 Particle Physics and Astronomy
Research Council. All Rights Reserved.

=cut


