# -*-perl-*-

# $Id: copyrpms.plm,v 1.9 2006/01/25 14:44:42 thomas Exp $

# Copy a bunch of RPMs from one location to another

# $Log: copyrpms.plm,v $
# Revision 1.9  2006/01/25 14:44:42  thomas
# Remove undefined error on corrupt RPMs
#
# Revision 1.8  2005/09/21 14:08:00  thomas
# Make this work when multiple rpm sources have the same 'install' attribute
#
# Revision 1.7  2005/02/21 20:56:31  thomas
# Help out the stinking pile known as help
#
# Revision 1.6  2004/07/22 19:12:10  thomas
# use global help function
#
# Revision 1.5  2004/04/06 21:19:51  thomas
# bug fix on include
#
# Revision 1.4  2004/03/05 15:14:38  thomas
# cconf->what
#
# Revision 1.3  2004/02/10 16:40:11  thomas
# pre-0.1.5 fork
#
# Revision 1.2  2003/12/15 16:28:34  thomas
# check-in for 0.1.1
#
# Revision 1.1.1.1  2003/12/02 14:47:34  thomas
# Initial version before export to 0.1.1
#

=head1 NAME

What::Command::copyrpms -- copy rpms for mkrpms

=head1 SYNOPSIS

what copyrpms I<config-file>

=head1 DESCRIPTION

Given the same config file used by mkrpms, copy rpms and source rpms
from the original repositories into an rpm cache as directed by the
config.

=cut

package What::Command::copyrpms;

use strict;
use Getopt::Long;

use base qw(What::Command);
use What::mkrpms;

our $helpmsg = "copy rpms for mkrpms";

###############################################################################

sub main {
  my $self = shift;
  my $what = shift;
  local (@ARGV) = @_;

  my ($res, $help, $root) = (0,0);
  my (%dirs, $dir, $rpmfile, $configfile, $key,
      $rpmlist, $rname, $vname, $attrs, $versions,
      $basename, $master, $to, $from, $file,
      $source, $srcname, $srcto, $srcfrom, $this, $dirnode, $rpmdir);

  my $section = $what->find_section ('default', 1);

  Getopt::Long::Configure ("bundling");
  if (!($res = GetOptions (
                           'help|h',   \$help,
                          ))) {
    $what->err ("Bad option passed to apply command!\n");
    return 0;
  }

  $help and return $self->help();

  $configfile = shift @ARGV;

  # Get the master Rpm config file
  $master = What::mkrpms::readconfig ($configfile);

  # Build a hash of all the directories that involve copying
  foreach $key (keys %{$master->{dir}}) {
    $dir = $master->{dir}->{$key};
    defined ($dir->{install}) and
      $dirs{$key} = {
				source => $dir->{source},
				dest => $dir->{dest},
				install => $dir->{install},
			       };
  }
  What::mkrpms::setup ($master);

  # For each rpm file on the command line, look for files that don't exist,
  # and reverse-hack where they might have come from.  Then copy them.
  foreach $rpmfile (keys (%{$master->{work}})) {
    $section->include ($what, {}, -1, {}, "$master->{outdir}/$rpmfile.rpms.xml");
    my $rpms = $section->find_node ($section, '/Rpms/rpms');
    defined $rpms or return 0;
    $rpmlist = $rpms->getchildren ($section);
    foreach $rname (sort keys %$rpmlist) {
      # if ($name eq 'perl') {
      #   print STDERR "Wow!\n";
      # }
      $versions = $rpmlist->{$rname}->getchildren ($section);
      foreach $vname (sort keys %$versions) {
	$attrs = $versions->{$vname}->getattrs ($section);
	die "No dir attribute for rpm $rname-$vname!" unless defined $attrs->{dir};

	# $rpmdir is the 'dir' attr from the /Rpms/rpms/foo/1.0 node
	$rpmdir = $attrs->{dir};
	next unless exists $dirs{$rpmdir};

	# This RPM is part of a copied group.

	# Get the dir node for this rpm node
	# $dir is the name of the directory
	$dirnode = $section->find_node ($section, "/Rpms/dirs/$rpmdir");

	# $dir is the 'dir' attr from the /Rpms/dirs/foodir node
	$dir = $dirnode->getattrs ($section, attr => 'dir');
	defined ($dir) or die "Can't parse $file!\n";

	$basename = "$rname-$vname.rpm";
	exists ($attrs->{basename}) and
	  $basename = $attrs->{basename};

	# Does it already exist in the dest area?
	if (! -e "$dirs{$rpmdir}->{dest}/$basename") {
	  $source = undef;
	  foreach $source (@{$dirs{$rpmdir}->{source}}) {
	    if (-e "$source/$basename") {
	      $from = $source;
	      last;
	    }
	  }
	  defined ($from) or die "Can't find a source dir for $file!\n";
	  print "cp $from/$basename $dirs{$rpmdir}->{dest}/$basename\n";
	  system ('cp', "$from/$basename", "$dirs{$rpmdir}->{dest}/$basename");
	}

	# $dirs{$rpmdir}->{dest}/$basename should now exists.
	# Check for a source RPM and copy it if possible
	if (-e "$dirs{$rpmdir}->{dest}/$basename") {
	  $srcname = getsrcname ("$dirs{$rpmdir}->{dest}/$basename");
	  if (defined ($srcname)) {
	    # Strip off last component of to and from and change to 'SRPMS'
	    ($srcto) = $dirs{$rpmdir}->{dest} =~ m:^(.*)/[^/]+$:;
	    $srcto .= "/SRPMS";
	    if (-d $srcto && ! -e "$srcto/$srcname") {
	      $source = undef;
	      foreach $source (@{$dirs{$rpmdir}->{source}}) {
		if (-e "$source/$basename") {
		  $from = $source;
		  last;
		}
	      }
	      if (defined ($from)) {
		($srcfrom) = $from =~ m:^(.*)/[^/]+$:;
		$srcfrom .= "/SRPMS";
		if (-e "$srcfrom/$srcname") {
		  print "cp $srcfrom/$srcname $srcto/$srcname\n";
		  system ('cp', "$srcfrom/$srcname", "$srcto/$srcname");
		}
	      }
	    }
	  }
	}
      }
    }
    $section->un_link ('/Rpms');
  }
  return 1;
}

###############################################################################
# Read the source RPM name out of the RPM

sub getsrcname {
  my $rpm = shift;

  my $fh = new FileHandle "/s/what-0.1.31/depend/rpm -q --queryformat '%{SOURCERPM}' -p $rpm |";
  defined $fh or die "Can't query rpm $rpm for source rpm!\n";
  my $srcrpm = <$fh>;
  chomp ($srcrpm) if defined $srcrpm;
  return $srcrpm;
}


###############################################################################

1;
