#!/usr/bin/perl -w

use strict;
use warnings;

use Getopt::Long;
use RPM::Header;
use File::Path qw(make_path remove_tree);
use Pod::Usage;
use RPM::Source::Transform 0.007;

my ($srpmdir, @hooks, $help);
#my ($packager,$nodefaulthook,$hashertar);
#my ($tag_packager_default,$tag_packager_replace,$opt_tmpdir);
my $verbose=0;
my $changelog='- rebuild (with the help of girar-nmu utility)';
my $outsrpmdir='OUT.SRPMS';
my $outgeardir='OUT.gits';
my $repo='sisyphus';
my $gitbranch='nmu';
my $nextrel='nmu';
my $version_check=1;

my @LOCAL_OPTIONS=(
	"b|branch=s"   => \$repo,
	"c=s"   => \$changelog,
	"d|localbranch=s"   => \$gitbranch,
	"exact-version!"   => \$version_check,
	"h|help"   => \$help,
	"hook=s"   => \@hooks,
	"G|outgear=s"   => \$outgeardir,
	"S|outsrpm=s"   => \$outsrpmdir,
	"srpmdir=s"   => \$srpmdir,
	"nextrel|next-release-policy=s"   => \$nextrel,
	"verbose+"  => \$verbose,
    );

my $options_result = 
    GetOptions (
	@LOCAL_OPTIONS,
	&RPM::Source::Transform::Getopt::PassThrough::passthrough2({@LOCAL_OPTIONS}, @RPM::Source::Transform::LONGOPT, @RPM::Source::Transform::EXT_OPTS),
    );

if ($help or not @ARGV) {
    #exec "pod2usage --exit=0 $0";
    print "Spec Editing Options, passed through to srpmnmu utility:\n";
    &RPM::Source::Transform::longopt_usage();
    pod2usage({ #-message => "the options below are package-specific:" ,
	-exitval => 0  ,
	-verbose => $verbose,
	#-output  => $filehandle
	      } );
}

my $curdir=`pwd`;
chomp $curdir;

my @common_args=&RPM::Source::Transform::Getopt::PassThrough::cat_options();
for (my $iii=0; $iii<$verbose;$iii++) {push @common_args, '--verbose';}
push @common_args, '--changelog', $changelog if $changelog;
push @common_args, '--nextrel', $nextrel if $nextrel;

foreach my $hook (@hooks) {
    push @common_args, '--hook', $hook;
}

my @srpms;

if (!$srpmdir) {
    @srpms=@ARGV;
} else {
    unless (-d $srpmdir) {
	die "not a directory: $srpmdir\n";
    }
    $srpmdir=~s!^\./!!;
    $srpmdir="$curdir/$srpmdir" if $srpmdir!~m!^/!;

    my %name2path;
    open (RPMARGS_FILES, "ls -1 $srpmdir |egrep -x '[^.].*[.]src[.]rpm' |") || die $!;
    my $f;
    while ($f=<RPMARGS_FILES>) {
	chomp $f;
	my $path="$srpmdir/$f";
	next unless -e $path;
	my $rhref = new RPM::Header $path;
	$name2path{$rhref->{NAME}}=$path;
    }
    close RPMARGS_FILES;
    foreach my $name (@ARGV) {
	my $path=$name2path{$name};
	unless ($path) {
	    die "source rpm file is not found in $srpmdir for the name $name.\n";
	}
	push @srpms, $path;
    }
}

foreach my $item (@srpms) {
    unless (-e $item) {
	die "source rpm file $item does not exist. You should use real src.rpms even if they will be uploaded as .gits. If $item is a package name, then please, use --srpmdir /path/to/srpms/ option.\n";
    }
    my $rhref;
    eval {
	$rhref=new RPM::Header $item;
    };
    die "$item is not an rpm file!: $@" if $@;
    die "not a source rpm!" if ! $rhref->is_source();
    my $rpmname=$rhref->{NAME};
    my $method=`girar-get-upload-method -b $repo '$rpmname'`;
    chomp $method;
    if ($method eq 'git') {
	-d $outgeardir || make_path($outgeardir);
	chdir $outgeardir;
	system('girar-clone-build-commit','-f','-b',$repo,'-d',$gitbranch,$rpmname);
	my $gearname=$rpmname;
	chdir $gearname.'.git';
	my $specfile=`gear --command sh -- -c 'printf \%s "\$gear_specfile"'`;
	chomp $specfile;
	if ($version_check) {
	    my $expected_desc=$rpmname.' '.$rhref->{VERSION}.' '.$rhref->{RELEASE};
	    my $description=`gear --describe`;
	    chomp $description;
	    if ($expected_desc ne $description) {
		warn "$rpmname: version mismatch (--no-exact-version will disable this check):\n";
		warn "Expected: $expected_desc\n";
		warn "Git based: $description\n";
		die "ERROR: version mismatch\n";
	    }
	}
	my @args=('srpmnmu', '--spec', $specfile, '--inplace');
	&system_or_die(@args, @common_args);
	&system_or_die('git', 'add', $specfile);
	&system_or_die('gear-commit','--no-edit');
	chdir $curdir;
    } elsif ($method eq 'srpm') {
	my @args=('srpmnmu', '--rpm', $item, '--out', $outsrpmdir.'/'.$rpmname);
	system(@args, @common_args)==0 or die join(' ',@args)." failed.
--------------------------------------------------------------------------------
Perhaps you should install missing required rpm-build-* or rpm-macros-* packages
or use --hashertar option.\n";
    } else {
	die "internal error: $method in girar-get-upload-method $rpmname. Please, report.";
    }
}

sub system_or_die {
    my (@args)=@_;
    system(@args)==0 or die join(' ',@args)." failed";
}

=head1	NAME

girar-nmu-prepare - generate NMU packages according to their upload method.

=head1	SYNOPSIS

B<girar-nmu-prepare>
[B<-h>] 
[B<-b> I<repository>]
[B<-d> I<local branch>]
[B<-e, --exact-version | --no-e, --no-exact-version>]
[B<-G> I<path/to/OUT.gits dir>]
[B<-S> I<path/to/OUT.SRPMS dir>]
[B<-c|--changelog> I<changelog text>]
[B<--hashertar>]
[B<--hook> I<path/to/hook>]
[B<other spec editing options here, see --help>]
B<--srpmdir> I<dir> I<srpmname ...> | I<srpm ...>

=head1	DESCRIPTION

B<girar-nmu-prepare> 
generate NMU packages according to their upload method.
for each package girar-nmu-prepare generate either a git repository with
the NMU commmit or the NMU src.rpm according to the package's upload method.
Each result is stored either as OUT.gits/name.git or OUT.SRPMS/name/*src..rpm.

As an argument girar-nmu-prepare takes either a list of original src.rpms 
or the path to dir with src.rpms in --srpmdir option and a list of names.


=head1	OPTIONS

=over

=item	B<-b> I<repository name>

Name of the repository branch. Values are: sisyphus|5.1|p5|..
Default is sisyphus.

=item	B<-c, --changelog> I<changelog text>

Changelog text. Default is like '- rebuild (with the help of girar-nmu utility)'

=item	B<-d> I<local branch name>

Git repository option.
Name of the local git branch to build from. Default is nmu.

=item	[B<-e, --exact-version>]

Die if version-release of src.rpm and git repository spec file does not match (Default).
Conversely, B<--no-e, --no-exact-version> allows to skip git repository version check.

=item	B<-G> I<dir>

name of output directory with Git repositories.
Default is "OUT.gits".

=item	B<-S> I<dir>

name of output directory for src.rpms.
Default is "OUT.SRPMS".

=item	B<--hashertar>

Generate hasher-ready .tar file instead of src.rpm file.
Some src.rpm require you to install extra rpm-build-* or rpm-macros-* packages
or else rpmbuild -bs --nodeps will fail. On the other hand, generating hasher-ready .tar
file does not require installing rpm-build-* or rpm-macros-* packages, but
this tar file should be first processed in hasher.
Use --hashertar option to avoid polluting your working environment with
unnecessary rpm-build-* or rpm-macros-* packages.


=item	B<--hook> I</path/to/hook>

Path to a perl-RPM-Source-Editor hook program to perform on the input packages.
This option can be repeated to load any number of hooks.

=item	B<-h, --help>

Display this help and exit.

=back

=head1	AUTHOR

Written by Igor Vlasenko <viy@altlinux.org>.

=head1	COPYING

Copyright (c) 2010 Igor Vlasenko, ALT Linux Team.

This 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.

=cut

