#!/usr/bin/perl
# debbuild script
# Shamlessly steals intreface from rpm's "rpmbuild" to create
# Debian packages.  Please note that such packages are highly
# unlikely to conform to "Debian Policy".
###
# SVN revision info
# $Date: 2005-10-28 22:04:31 +0000 (Fri, 28 Oct 2005) $
# SVN revision $Rev: 5 $
# Last update by $Author: kdeugau $
###

use strict;

# Program flow:
# -> Parse/execute "system" config/macros (if any - should be rare)
# -> Parse/execute "user" config/macros (if any - *my* requirement is %_topdir)
# -> Parse command line for options, spec file/tarball/.src.deb (NB - also accept .src.rpm)

# User's prefs for dirs, environment, etc,etc,etc.
# config file ~/.debmacros
# Default ordered search paths for config/macros:
# /usr/lib/rpm/rpmrc  /usr/lib/rpm/redhat/rpmrc  /etc/rpmrc      ~/.rpmrc
# /usr/lib/rpm/macros /usr/lib/rpm/redhat/macros /etc/rpm/macros ~/.rpmmacros
# **NOTE:  May be possible to (ab)use bits of debhelper

# Build tree
# default is /usr/src/debian/{BUILD,SOURCES,SPECS,DEBS,SDEBS}

# Globals
my $specfile;
my $tarball;
my $srcpkg;
my $verbosity = 0;
my %cmdopts = (type => '',
		stage => 'a',
		short => 'n'
	);
my %targets = ('p' => 'Prep',
		'c' => 'Compile',
		'i' => 'Install',
		'l' => 'Verify %files',
		'a' => 'Build binary and source',
		'b' => 'Build binary',
		's' => 'Build source'
	);
my $topdir = "/usr/src/debian";

# Package data
# This is the form of $pkgdata{pkgname}{meta}
# meta includes Summary, Name, Version, Release, Group, Copyright,
#	Source, URL, Packager, BuildRoot, Description
my %pkgdata;

# Functions
sub prep;
sub parse_spec;

die "Not enough arguments\n" if #$argv == 0;

load_userconfig();
parse_cmd();

# Hokay.  Need to:
# Execute prep if *not* --short-circuit
prep() if ($cmdopts{short} ne 'y');

if ($cmdopts{stage} =~ /ciab/) {
  # Execute build if bc
  # Execute build if bi, ba, bb and NOT --short-circuit
  build() if ( ($cmdopts{stage} eq 'c') ||
	(($cmdopts{stage} =~ /iab/) && ($cmdopts{short} ne 'y'))
	);

  # -> Execute 
  install() if ($cmdopts{short} ne 'y');
  binpackage();
}

srcpackage();



# Just in case.
exit 0;


## load_userconfig()
# Loads user configuration (if any)
# Currently only handles .debmacros
# Needs to handle "other files"
sub load_userconfig {
  my (undef,undef,undef,undef,undef,undef,undef,$homedir,undef) = getpwuid($<);
  if (-e "$homedir/.debmacros") {
    open USERMACROS,"<$homedir/.debmacros";
    while (<USERMACROS>) {
      # And we also only handle the %_topdir macro at the moment.
      if (/^\%_topdir/) {
	my (undef,$tmp) = split /\s+/, $_;
	$topdir = $tmp;
      }
    }
  }
} # end load_userconfig()


## parse_cmd()
# Parses command line into global hash %cmdopts, other globals
# Options based on rpmbuild's options
sub parse_cmd {
  # Don't feel like coding my own option parser...
  #use Getopt::Long;
  # ... but I may have to:  (OTOH, rpm uses popt, so maybe we can too.)
  #use Getopt::Popt qw(:all);
  # Or not.  >:(  Stupid Debian lack of findable Perl module names in packages.

  # Stuff it.
  my $prevopt = '';
  foreach (@ARGV) {
    chomp;
    $prevopt = $_;
    # Is it an option?
    if (/^-/) {
      # Is it a long option?
      if (/^--/) {
	if (/^--short-circuit/) {
	  $cmdopts{short} = 'y';
	} elsif (/^--rebuild/) {
	  $cmdopts{type} = 's';
	} else {
	  print "Long opt $_\n";
	}
      } else {
	if (/^-[bt]/) {
	  if ($cmdopts{stage} eq 's') {
	    # Mutually exclusive options.
	    die "Can't use $_ with --rebuild\n";
	  } else {
	    ($cmdopts{stage}) = (/^-[bt]([pcilabs])/);
	    ($cmdopts{type}) = (/^-([bt])[pcilabs]/);
	  }
	} elsif (/^-v/) {
	  # bump verbosity.  Not sure what I'll actually do here...
	} else {
	  die "Bad option $_\n";
	}
      }
    } else {
      # --buildroot is the only option that takes an argument
      # Therefore, any *other* bare arguments are the spec file,
      # tarball, or source package we're operating on - depending
      # on which one we meet.
      if ($prevopt eq '--buildroot') {
	# Set buildroot
      } else {
	if ($cmdopts{type} eq 's') {
	  # Source package
	  if (!/\.src\.(deb|rpm)$/) {
	    die "Can't --rebuild with $_\n";
	  }
	} elsif ($cmdopts{type} eq 'b') {
	  $specfile = $_;
	  # Spec file
	} else {
	  # Tarball
	}
      }
    }
  }

  # Some cross-checks.  rpmbuild limits --short-circuit to just
  # the "compile" and "install" targets - with good reason IMO.
  # NB - this is NOT fatal, just ignored!
  if ($cmdopts{short} eq 'y') {
    warn "Can't use --short-circuit for $targets{$cmdopts{stage}} stage.  Ignoring.\n";
    $cmdopts{short} = 'n';
  }
  # Valid options, with example arguments (if any):
# Build from .spec file; mutually exclusive:
  # -bp
  # -bc         
  # -bi         
  # -bl
  # -ba
  # -bb
  # -bs
# Build from tarball; mutually exclusive:
  # -tp
  # -tc
  # -ti
  # -ta
  # -tb
  # -ts
# Build from .src.(deb|rpm)
  # --rebuild
  # --recompile

# General options
  # --buildroot=DIRECTORY
  # --clean
  # --nobuild
  # --nodeps
  # --nodirtokens
  # --rmsource
  # --rmspec
  # --short-circuit
  # --target=CPU-VENDOR-OS

  #my $popt = new Getopt::Popt(argv => \@ARGV, options => \@optionsTable);

} # end parse_cmd()


## prep()
# Unpacks the tarball from the SOURCES directory to the BUILD directory.
# Speaks gzip and bzip2.
# Finishes by applying patches in %prep section of spec file
sub prep {
  if ($cmdopts{type} eq 'b') {
    # Need to read the spec file to find the tarball
    parse_spec();

    # Need to find the filename part of the tarball.  In theory, we
    # could go out to the URL and retrieve it, but that's Messy.
# want to make this local
    $pkgdata{main}{source} =~ s|.+/([^/]+)$|$1|;

    if ($pkgdata{main}{source} =~ /(.+)\.tar\.gz$/) {
      -e "$topdir/BUILD/$1" && system "rm -rf $topdir/BUILD/$1";
      system "cd $topdir/BUILD;tar -zxvf $topdir/SOURCES/$pkgdata{main}{source}";
    } elsif ($pkgdata{main}{source} =~ /(.+)\.tar\.bz2$/) {
      -e "$topdir/BUILD/$1" && system "rm -rf $topdir/BUILD/$1";
      system "cd $topdir/BUILD;tar -jxvf $topdir/SOURCES/$pkgdata{main}{source}";
    } else {
      die "Unknown source tarball format\n";
    }
    # And now for patches.  (not)
  }
} # end prep()


## parse_spec()
# Parse the .spec file once we've.... uh....
sub parse_spec {
  open SPECFILE,"<$specfile";

  while (<SPECFILE>) {
    next if /^#/;
    next if /^\s+$/;
    if (/^\%/) {
      # A macro that needs further processing.
      if (/^\%build/) {
	# %build.  This is pretty much just a shell script.
      }
    } else {
      if (/^summary:\s+(.+)/i) {
	$pkgdata{main}{summary} = $1;
      } elsif (/^name:\s+(.+)/i) {
	$pkgdata{main}{name} = $1;
      } elsif (/^version:\s+(.+)/i) {
	$pkgdata{main}{version} = $1;
      } elsif (/^release:\s+(.+)/i) {
	$pkgdata{main}{release} = $1;
      } elsif (/^group:\s+(.+)/i) {
	$pkgdata{main}{group} = $1;
      } elsif (/^copyright:\s+(.+)/i) {
	$pkgdata{main}{copyright} = $1;
      } elsif (/^url:\s+(.+)/i) {
	$pkgdata{main}{url} = $1;
      } elsif (/^packager:\s+(.+)/i) {
	$pkgdata{main}{packager} = $1;
      } elsif (/^source:\s+(.+)/i) {
	$pkgdata{main}{source} = $1;
      }
#Name: suwrap
#Version: 0.04
#Release: 3
#Group: Applications/System
#Copyright: WebHart internal ONLY.  :(
#BuildArchitectures: i386
#BuildRoot: /tmp/%{name}-%{version}
#Url: http://virtual.webhart.net
#Packager: Kris Deugau <kdeugau@deepnet.cx>
#Source: ftp://virtual.webhart.net/%{name}-%{version}.tar.gz

    }
  }
  # Parse and replace macros in $pkgdata{}{}
  # Start with the ones I use
  $pkgdata{main}{source} =~ s/\%\{name\}/$pkgdata{main}{name}/;
  $pkgdata{main}{source} =~ s/\%\{version\}/$pkgdata{main}{version}/;
} # end parse_spec()


## build()
# Execute commands provided as a shell script.  It may prove simpler
# to do as rpm does and actually create a little shell script.
sub build {
} # end build()


sub install {}
sub binpackage {}
sub srcpackage {}
