#!/usr/bin/env python

# $Id: mkdist,v 1.10 2004/01/09 20:29:28 type2 Exp $

#  
#  Prospect: a developer's system profiler.
#  Binary file distribution generator.
#
#  COPYRIGHT (C) 2001-2004 Hewlett-Packard Company
# 
#  Author: Alex Tsariounov, HP
#
#  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.
#

#
# mkdist - make distribution script
#
# Automates the making of the distribution tar file. 
#

import sys, os, re, shutil, getopt, glob
from string import split, atof, atoi
    
verbose = 0

def main():
    global verbose
    # process options
    try: 
        opts, args = getopt.getopt(sys.argv[1:], "v")
    except getopt.error, msg:
        print msg
        print "usage:", sys.argv[0], "[-v] [binary|source]"
        sys.exit(2)
    for o, a in opts:
        if o == "-v":
            verbose = verbose + 1

    if verbose: print "Executing mkdist"

    if len(args) == 0:
        type = 'binary'
    else:
        if len(args) > 1:
            print "Too many args: ",  args
            sys.exit(1)
        if  args[0] == 'source':
            type = 'source'
        elif args[0] == 'binary':
            type = 'binary'
        else:
            print "Error, arg [" + args[0] + "] not understood"
            sys.exit(1)

    if verbose: print "Build type: " + type

    #
    # Lousy way to find out if this is IPF
    #
    if sys.maxint > 2147483647:
        platform = 'ia64'
        if verbose: print "Detected 64-bit host architecture"
    else:
        platform = 'i386'

    #
    # Figure out the release platform and number
    # First make sure we're in the main project dir
    #
    if verbose: print "Checking for prospect directories..."
    files = os.listdir(os.curdir)
    if "docs" not in files and "prospect" not in files:
        if verbose: 
            print "Dirs docs/ and prospect/ not found, trying parent dir..."
        files = os.listdir(os.pardir)
        if "docs" in files and "prospect" in files:
            # we're in a child dir, cd up and continue
            os.chdir(os.pardir)
            if verbose: print "Parent dir is good, chdir .."
        else:
            print "Error: I can't find the prospect project directory."
            sys.exit(1) 

    # check for sudo
    if verbose: print "Checking for su utils... ",
    if not os.path.exists("/usr/bin/sudo") and \
       not os.path.exists("/usr/local/bin/sudo"):
        print "Error: I can't find /usr/local/bin/sudo on this linux platform."
        sys.exit(1)
    if verbose: print "Ok"

    # read the version file 
    if verbose: print "Reading in version file prospect/version.h..."
    try:
        vfile = open("prospect/version.h")
    except:
        print "Error: Can't read file prospect/version.h"
        sys.exit(1)

    # look for the version define
    while 1:
        line = vfile.readline()
        if re.match("^#define cREV", line): break
    else:
        # end of file - loop ran to completion, weird way
        print "Error: Didn't find definition of cREV in prospect/version.h"

    if verbose: print "Found version definition: ", line[:-1]
    version = re.search(r'".+"', line)
    if not version: 
        print "Error: Couldn't find revision text in define line %s" % line
        sys.exit(1)
    vstring = version.group(0)[1:-1]  # remove quotes too
    if verbose: print "Extracted: ", vstring

    vstring = re.sub(" ", "_", vstring)
    if verbose: print "Produces version tag: ", vstring

    # and make the dir name
    distname = "prospect" "-" + vstring 
    if type == "binary":
        distname += "-" + platform
    if verbose: print "Which means a directory name of: ", distname

    #
    # Create subdir for dist and massage
    #
    if os.path.exists("%s.tar.gz"%distname):
        print "Error: %s.tar.gz exists already."%distname
        sys.exit(1)
    try:
        os.mkdir(distname)
    except:
        print "Error: %s exists." % distname
        sys.exit(1)

    if type == "binary":
        make_binary(distname)
    else:
        make_source(distname)

    # 
    # tar it up and we're done
    # 
    if verbose: print "Making the tar ball..."
    os.system( "tar cfz %s.tar.gz %s" % (distname, distname) )

    # and remove the original directory
    os.system("sudo rm -rf %s" % distname)

    if verbose: print "Done, bundle is: %s.tar.gz" % distname
    
def make_binary(distname):
    if verbose: print "Making binary bundle"
    try:
        shutil.copy("prospect/prospect", distname)
        shutil.copy("README", distname)
        shutil.copy("README.INSTALL", distname)
        shutil.copy("README.ia64", distname)
        shutil.copy("NEWS", distname)
        shutil.copy("DISCLAIMER", distname)
        shutil.copy("COPYING", distname)
        shutil.copy("AUTHORS", distname)
        shutil.copy("docs/prospect.1", distname)
        # copy every file in kern_supp into distribution
        if verbose: print "Copying kern_supp/"
        shutil.copytree("kern_supp", distname+"/kernel_support")
    except (IOError, os.error), why:
        print "Caught file copy error, distribution may be incomplete."
        print "\tError is: %s" % str(why)
        sys.exit(1)

    if verbose: 
        print "Made directory and copied files."
        print "Changing ownerships..."

    os.system("sudo chown -R root:sys %s" % distname)

    if verbose: print "Making prospect/prospect suid..."
    os.system("sudo chmod 4555 %s/prospect" % distname)

    cmd = "sudo find %s -name CVS | sudo xargs rm -rf " % distname
    if verbose: print "Removing any CVS dirs %s" % distname
    else: cmd += " >/dev/null 2>/dev/null"
    os.system(cmd)

def make_source(distname):
    if verbose: print "Making source bundle"
    cmd = "cp .* %s" % distname
    if not verbose: cmd += " 2>/dev/null"
    os.system(cmd)

    items = glob.glob('*')
    files = ""
    for item in items:
        if item == distname: continue
        if item == "CVS": continue
        files += item + " ";

    cmd = "cp -R %s %s" % (files, distname)
    if verbose: print "Copying source files..."
    else: cmd += " 2>/dev/null"
    os.system(cmd)

    os.chdir(distname)
    cmd = "find . -name CVS | xargs rm -rf "
    if verbose: print "Removing CVS dirs ..."
    else: cmd += " 2>/dev/null"
    os.system(cmd)
    cmd = "make distclean"
    if verbose: "Making distclean..."
    else: cmd += " >/dev/null 2>&1"
    os.system(cmd)
    os.chdir("..")

if __name__ == "__main__":
    main()

