#!/usr/bin/perl
# (c) Eduard Bloch <blade@debian.org>, 2003
# License: GPL
# Version: $Id: svn-uupdate 415 2003-10-05 10:08:03Z inet $

use Getopt::Long qw(:config no_ignore_case bundling);
use File::Basename;
use Cwd;
use Cwd 'abs_path';
#use diagnostics;

$startdir=getcwd;

sub help {
print "
Usage: svn-uupdate newtarball [ OPTIONS... ]
Upgrade a source code package from an upstream revision. The source code
repository must be in the format created by svn-inject.

  -V, --upstreamversion   STRING    Forces a different upstream version string
  -v, --verbose             More verbose program output

Tarballs must be compressed with gzip or bzip2.
"; exit 1;
}

my $opt_help;
my $version;
my $verbose;
my $keep_removed;
my $quiet="-q";

%options = (
   "h|help"                => \$opt_help,
   "V|upstreamversion=s"   => \$version,
   "v|verbose"             => \$verbose,
);

&help unless ( GetOptions(%options));
&help if ($opt_help);
&help if $#ARGV < 0;
$tarball=$ARGV[0];
&help if(! -f $tarball);
shift(@ARGV);

$tarball=$startdir."/".$tarball if(! $tarball=~/^\//);

basename($tarball) =~/(.*)-(\d.*)\.(tar|tgz|tbz)/i;

$package = $1 if(!defined($package));
$version = $2 if(!defined($version));

die "Unrecognized upstream version, use -V\n" if(!length($version));

$quiet="" if ($verbose);

use SD;
SD::configure;
#$tagVersion=$SD::tagVersion;
$upVersion=$SD::upVersion;
$package  =$SD::package;
needs_tagsUrl;
needs_upsTagUrl;
needs_upsCurrentUrl;
$c=\%SD::c;

# my private copy
if($$c{"origDir"}){$origdir=$$c{"origDir"}}else{chomp($origdir=`mktemp -d`)};

chomp($tmpdir=`mktemp -d`);
#print "D: ".$$c{"upsTagUrl"}.join(",", values(%c));
$upsOldVersUrl=$$c{"upsTagUrl"}."/$upVersion";
#print $upsOldVersUrl ; exit 1;
mkdir $tmpdir;

$filestr = `file $tarball`;
if($filestr =~ /symbolic link/) {
   $filestr = `cat $tarball | file -`;
   $justcopy = 0;
}

if ($filestr =~ /gzip/){
   $cat = "zcat ";
   $justcopy=1 if ($filestr =~ /max compression/ && !defined($justcopy));
}
elsif ($filestr =~ /bzip/){
   $cat = "bzcat ";
}
elsif ($filestr =~ /tar archive/){
   $cat = "cat ";
}
else {
   die "Unknown compression method!\n";
}

$neworig="$origdir/".$package."_".$version.".orig.tar.gz";

# repack the new source file to tarballs/...orig.tar.gz
if(! -f $neworig) {
   if($justcopy) {
      link($tarball,$neworig) || withecho("cp $tarball $neworig");
   }
   else {
      withecho("$cat $tarball | gzip -9 > $neworig");
   };
}

withecho("svn $quiet add $neworig") if(defined $SD::c{"origUrl"});

if(`svn proplist debian` =~ /mergeWithUpstream/i) {
   print "I: Upstream source not maintained in the repository.\n";
   print "I: Assuming that it will be merged at build time.\n";
}
else
{
   if(! insvn($upsOldVersUrl)) {
         die "
         Could not find the unmodified upstream version in
         $upsOldVersUrl!
         If you think that $$c{\"upsCurrentUrl\"} is the upstream source
         which $$c{\"trunkUrl\"} is based on, run:

         svn copy $$c{\"upsCurrentUrl\"} $upsOldVersUrl

         Otherwise, please fix the headline of debian/changelog.\n";
   }
}

withecho("tar zxf $neworig -C $tmpdir");

$baseURL = url(".");

if(`svn proplist debian` =~ /mergeWithUpstream/i) {
   chdir $startdir;
   open($dl, "find -type f | grep -v \"\\.svn\" |");
   while(<$dl>) {
      push(@difflist, $1) if(/^[^\/]+\/(.+)\n/);
   }
   close($dl);
}

chdir $tmpdir;
system "rm -f *.gz";
if(@difflist) {
   withecho "mv * $version-tmp; mkdir $version";
   withecho "cd $version-tmp; tar c ".join(" ", @difflist)." 2>/dev/null | tar x -C ../$version";
}
else {
   withecho "mv * $version";
}

# now we have the new upstream source we need in $tmpdir/$version
withecho("svn_load_dirs", $$c{"upsCurrentUrl"}, ".", "$tmpdir/$version");
withecho("svn", "copy", "-m", "Tagging new upstream version as $version", $$c{"upsCurrentUrl"},  $$c{"upsTagUrl"}."/$version");
chdir $$c{"trunkDir"};
withecho("svn","merge", $upsOldVersUrl, $$c{"upsCurrentUrl"}, ".");
withecho "svn up";

open($svn, "svn status|");
@conflicts = grep(/^C/, <$svn>);
map {s/^..//} @conflicts;
if ($#conflicts != -1) {
   print "Files in conflict state: $#conflicts\n\n @conflicts\n";
   print "Resolve them manually and run \"svn resolve\" on each file\n";
}
withecho "rm -rf $tmpdir" if(length($tmpdir));

withecho "debchange -v \"$version-1\" \"(NOT RELEASED YET) New upstream release\"";
print "Done! Last commit pending, please execute manually.\n";
