#
# HgRemoteScript: object for writing a script file and executing it on another
#                 machine using ssh.
#
# DO NOT EDIT the /cluster/bin/scripts copy of this file --
# edit ~/kent/src/hg/utils/automation/HgRemoteScript.pm instead.

# $Id: HgRemoteScript.pm,v 1.2 2009/06/08 18:40:49 hiram Exp $
package HgRemoteScript;

use warnings;
use strict;
use FindBin qw($Bin);
use lib "$Bin";
use HgAutomate;
use Carp;
use vars qw(@ISA @EXPORT_OK);
use Exporter;

@ISA = qw(Exporter);
@EXPORT_OK = qw( new newBash add execute );

sub new {
  # Create and return an HgRemoteScript object.  $configFile is optional.
  my ($class, $scriptFile, $runHost, $runDir, $purpose, $configFile) = @_;
  confess "Must have 5 or 6 arguments" if (scalar(@_) < 5 || scalar(@_) > 6);
  confess "undef input" if (! defined $class || ! defined $scriptFile ||
			    ! defined $runHost || ! defined $runDir ||
			    ! defined $purpose);
  my $this = {};
  $this->{'fileName'} = $scriptFile;
  $this->{'runHost'} = $runHost;
  $this->{'fh'} = &HgAutomate::mustOpen(">$scriptFile");
  $this->{'hasBeenExecuted'} = 0;
  my $fh = $this->{'fh'};
  print $fh <<_EOF_
#!/bin/csh -efx
# This script was automatically generated by $0
_EOF_
  ;
  if ($configFile) {
    print $fh "# from $configFile\n";
  }
  $purpose =~ s/^([^#])/# $1/;
  $purpose =~ s/\n([^#])/\n# $1/g;
  $purpose =~ s/\n$//;
  print $fh <<_EOF_
# It is to be executed on $runHost in $runDir .
$purpose
# This script will fail if any of its commands fail.

cd $runDir

_EOF_
  ;
  bless $this, $class;
}

sub newBash {
  # Create and return an HgRemoteScript object.  $configFile is optional.
  my ($class, $scriptFile, $runHost, $runDir, $purpose, $configFile) = @_;
  confess "Must have 5 or 6 arguments" if (scalar(@_) < 5 || scalar(@_) > 6);
  confess "undef input" if (! defined $class || ! defined $scriptFile ||
			    ! defined $runHost || ! defined $runDir ||
			    ! defined $purpose);
  my $this = {};
  $this->{'fileName'} = $scriptFile;
  $this->{'runHost'} = $runHost;
  $this->{'fh'} = &HgAutomate::mustOpen(">$scriptFile");
  $this->{'hasBeenExecuted'} = 0;
  my $fh = $this->{'fh'};
  print $fh <<_EOF_
#!/bin/bash
# This script was automatically generated by $0
_EOF_
  ;
  if ($configFile) {
    print $fh "# from $configFile\n";
  }
  $purpose =~ s/^([^#])/# $1/;
  $purpose =~ s/\n([^#])/\n# $1/g;
  $purpose =~ s/\n$//;
  print $fh <<_EOF_
# It is to be executed on $runHost in $runDir .
$purpose
# This script will fail if any of its commands fail.
# fail on any error:
set -xbeEu -o pipefail

cd $runDir

_EOF_
  ;
  bless $this, $class;
}

sub add {
  # Add text to the script (must not be called after execute).
  my $this = shift;
  confess "Must have at least one argument" if (scalar(@_) < 1);
  confess "undef input" if (! defined $_[0]);
  if ($this->{'hasBeenExecuted'}) {
    confess "Cannot be called after execute.";
  }
  my $fh = $this->{'fh'};
  print $fh @_;
}

sub execute {
  # Close the script file, chmod, and run it on the intended host.
  my $this = shift;
  confess "Must have no arguments" if (scalar(@_) > 0);
  $this->{'hasBeenExecuted'} = 1;
  close($this->{'fh'});
  &HgAutomate::run("chmod a+x $this->{fileName}");
  &HgAutomate::nfsNoodge("$this->{fileName}");
  &HgAutomate::run("$HgAutomate::runSSH $this->{runHost} nice $this->{fileName}");
}

# perl packages need to end by returning a positive value:
1;
