#!/usr/local/bin/perl
##--------------------------------------------------------------------------##
##  File:
##	$Id: apply-config,v 1.5 2002/03/07 02:03:31 ehood Exp $
##  Description:
##--------------------------------------------------------------------------##
##  Copyright (C) 2002	Earl Hood <earl@earlhood.com>
##
##  This program is free software; you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation; either version 2 of the License, or
##  (at your option) any later version.
##  
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##  
##  You should have received a copy of the GNU General Public License
##  along with this program; if not, write to the Free Software
##  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
##  02111-1307, USA
##--------------------------------------------------------------------------##

package MHArc::apply_config;

my $Dir;
BEGIN {
  $Dir = `dirname $0`; chomp $Dir;
}
use lib "$Dir/../lib";  # Add relative lib to search path

use MHArc::Config;
my $config = MHArc::Config->load("$Dir/../lib/config.sh");


use Getopt::Long;
use File::Find;
use Pod::Usage;
use MHArc::Util qw(run_prg);

my $clean = 0;
my $distclean = 0;
my $debug = 0;
my $noact = 0;
my $verbose = 0;

GetOptions(
    "clean!"	  => \$clean,
    "distclean!"  => \$distclean,
    "debug!"	  => \$debug,
    "n!"	  => \$noact,
    "verbose!"	  => \$verbose,

    "help"	  => \$help,
    "man"	  => \$man
) || pod2usage(-verbose => 0);
pod2usage(-verbose => 1)  if $help;
pod2usage(-verbose => 2)  if $man;


$verbose = 1  if $debug || $noact;
$clean   = 1  if $distclean;
$MHArc::Util::ECHO_CMDS = 1  if ($verbose);
$MHArc::Util::ECHO_ONLY = 1  if ($noact);

my %done = ( );

if ($debug) {
  $config->dump_config(\*STDERR);
}

sub wanted {
  if ($_ =~ /config\.sh$/ ||
      $_ =~ /config\.sh\.in$/ ||
      $_ =~ /config\.sh\.dist$/ ||
      $_ =~ /config\.sh\.in\.dist$/) {
    print qq/Skipping config file "$File::Find::name"\n/  if $debug;
    return;
  }
  if (-d $_ && ($_ =~ /RCS$/ || $_ =~ /CVS$/ || $_ =~ /SCCS$/)) {
    print qq/Pruning "$File::Find::name"\n/  if $debug;
    $File::Find::prune = 1;
    return;
  }
  if (-d $_ || !/\.in(?:\.dist)?$/o) {
    print qq/Ignoring "$File::Find::name"\n/  if $debug;
    return;
  }
  if ($done{$File::Find::name}) {
    print qq/Skipping "$File::Find::name", already processed.\n/
	if $debug;
    return;
  }

  my $file = $File::Find::name;
  print qq/Checking "$File::Find::name"...\n/  if $debug;
  if ($file =~ s/\.dist$//) {
    if (!$clean) {
      if (! -e $file) {
	run_prg('/bin/cp', $File::Find::name, $file);
	run_prg('/bin/chmod', 'u+w', $file);
      }
    }
    $done{$File::Find::name} = 1;
    $done{$file} = 1;
  }

  my $file_out = $file;
  $file_out =~ s/\.in$//;

  if ($clean) {
    run_prg('/bin/rm', $file_out)  if (-e $file_out);
    run_prg('/bin/rm', $file)	   if ($distclean && (-e $file) &&
				       (-e "$file.dist"));
    return;
  }

  print qq/Processing "$file"\n/  if $verbose;
  if (!$noact) {
    local(*IN, *OUT);
    open(IN, $file) ||
	die qq/ERROR: Unable to open "$file": $!\n/;
    open(OUT, ">$file_out") ||
	die qq/ERROR: Unable to create "$file_out": $!\n/;

    my($line);
    while (defined($line = <IN>)) {
      $line =~ s/\@\@([^@]*)\@\@/$config->{$1}/g;
      print OUT $line;
    }
    close(IN);
    close(OUT);
    if (-x $file) {
      run_prg('/bin/chmod', 'a+x', $file_out);
    }
  }
}

if (!@ARGV) {
  @ARGV = ("$Dir/..");
}
find({ wanted => \&wanted,
       no_chdir => 1 },
     @ARGV);

##--------------------------------------------------------------------------##
__END__

=head1 NAME

apply-config - Process input template files based upon configuration settings.

=head1 SYNOPSIS

  apply-config [options] [dir ...]

=head1 DESCRIPTION

This program processes input template files and expands variables
referenced to values specified in C<$SW_ROOT/lib/config.sh>, where
C<$SW_ROOT> is the root of the software installation (which is
considered to be the parent directory of the directory containing this
program).

Template files are designated by the C<.in> filename extentions.  For a
given file, if C<I<file>.in.dist> exists and C<I<file>.in> does not,
C<I<file>.in.dist> will be copied to C<I<file>.in> before processing.

Variable references in template files are denoted as follows:

  @@VARIABLE_NAME@@

If the specified variable name is defined, the reference will be
replaced with the empty string.

=head1 OPTIONS

Any non-option arguments are treated as directories to recursively
scan for template files.  If no directories are specified, then
C<$SW_ROOT> is used as defined in L<"DESCRIPTION">.

=over

=item -clean

Remove all files that have a C<.in> version.  This option is useful
to clean up all files generated from templates.

=item -distclean

Remove all files that have a C<.in> version and remove all C<.in>
files that have a C<.in.dist> version.  This option is useful to
clean up all files for generating a distribution bundle.

=item -debug

Print out alot of information on what is going on.  This options
prints out more information than C<-debug>.

=item -n

Just echo what would be done, but do not do it.

=item -verbose

Echo out status on any operation that modifies files.

=back

=head1 FILES

=over

=item C<$SW_ROOT/lib/config.sh>

Configuration file defining variables values.

=back

=head1 VERSION

C<$Id: apply-config,v 1.5 2002/03/07 02:03:31 ehood Exp $>

=head1 AUTHOR

Earl Hood, earl@earlhood.com

