#! /usr/bin/env python
#  -*- Python -*-

"""%(program)s - script to create the latex source distribution

usage:
     %(program)s [-t|--tools] release [tag]

with -t|--tools:  doesn't include the documents, only the framework

without [tag]:  generate from the current version that's checked in
     	   (*NOT* what's in the current directory!)

with [tag]:  generate from the named tag
"""
#* should be modified to get the Python version number automatically
#  from the Makefile or someplace.

import getopt
import glob
import os
import re
import shutil
import sys
import tempfile

import cvsinfo

try:
    __file__
except NameError:
    __file__ = sys.argv[0]

tools = os.path.dirname(os.path.abspath(__file__))
Doc = os.path.dirname(tools)
patchlevel_tex = os.path.join(Doc, "commontex", "patchlevel.tex")

quiet = 0
rx = re.compile(r":ext:(?:[a-zA-Z0-9]+@)?cvs\.([a-zA-Z0-9]+).sourceforge.net:"
                r"/cvsroot/\1")


def main():
     global quiet
     anonymous = False
     try:
          opts, args = getopt.getopt(sys.argv[1:], "Aabgtzq",
                                     ["all", "bzip2", "gzip", "tools", "zip",
                                      "quiet", "anonymous"])
     except getopt.error, e:
          usage(warning=str(e))
          sys.exit(2)
     if len(args) not in (1, 2):
          usage(warning="wrong number of parameters")
          sys.exit(2)
     tools = 0
     formats = {}
     for opt, arg in opts:
          if opt in ("-t", "--tools"):
               tools = 1
          elif opt in ("-q", "--quiet"):
               quiet = quiet + 1
          elif opt in ("-b", "--bzip2"):
               formats["bzip2"] = 1
          elif opt in ("-g", "--gzip"):
               formats["gzip"] = 1
          elif opt in ("-z", "--zip"):
               formats["zip"] = 1
          elif opt in ("-a", "--all"):
               formats["bzip2"] = 1
               formats["gzip"] = 1
               formats["zip"] = 1
          elif opt in ("-A", "--anonymous"):
               anonymous = True
     if formats:
          # make order human-predictable
          formats = formats.keys()
          formats.sort()
     else:
          formats = ["gzip"]
     release = args[0]
     cvstag = None
     if len(args) > 1:
          cvstag = args[1]
     tempdir = tempfile.mktemp()
     os.mkdir(tempdir)
     pkgdir = os.path.join(tempdir, "Python-Docs-" + release)
     os.mkdir(pkgdir)
     pwd = os.getcwd()
     mydir = os.path.abspath(os.path.dirname(sys.argv[0]))
     info = cvsinfo.RepositoryInfo(mydir)
     cvsroot = info.get_cvsroot()
     m = rx.match(cvsroot)
     if m and anonymous:
          # If this is an authenticated SourceForge repository, convert to
          # anonymous usage for the export/checkout, since that avoids the
          # SSH overhead.
          group = m.group(1)
          cvsroot = ":pserver:anonymous@cvs.%s.sourceforge.net:/cvsroot/%s" \
                    % (group, group)
          # For some reason, SourceForge/CVS doesn't seem to care that we
          # might not have done a "cvs login" to the anonymous server.
          # That avoids a lot of painful gunk here.
     os.chdir(tempdir)
     if not quiet:
          print "--- current directory is:", pkgdir
     if cvstag:
          run("cvs -d%s export -r %s -d Python-Docs-%s python/dist/src/Doc"
              % (cvsroot, cvstag, release))
     else:
          run("cvs -Q -d%s checkout -d Python-Docs-%s python/dist/src/Doc"
              % (cvsroot, release))
          # remove CVS directories
          for p in ('*/CVS', '*/*/CVS', '*/*/*/CVS'):
               map(shutil.rmtree, glob.glob(p))
     for f in ('.cvsignore', '*/.cvsignore'):
          map(os.unlink, glob.glob(f))

     # Copy in the version informtation, if we're not just going to
     # rip it back out:
     if not tools:
          if not os.path.exists(patchlevel_tex):
               run(os.path.join(here, "getversioninfo"))
          dest = os.path.join("Python-Docs-" + release, "commontex",
                              "patchlevel.tex")
          shutil.copyfile(patchlevel_tex, dest)

     # Copy in the license file:
     LICENSE = os.path.normpath(
          os.path.join(mydir, os.pardir, os.pardir, "LICENSE"))
     shutil.copyfile(LICENSE, "LICENSE")
     if tools:
          archive = "doctools-" + release
          # we don't want the actual documents in this case:
          for d in ("api", "dist", "doc", "ext", "inst",
                    "lib", "mac", "ref", "tut", "commontex"):
               shutil.rmtree(os.path.join(pkgdir, d))
     else:
          archive = "latex-" + release

     # XXX should also remove the .cvsignore files at this point

     os.chdir(tempdir)
     archive = os.path.join(pwd, archive)
     for format in formats:
          if format == "bzip2":
               run("tar cf - Python-Docs-%s | bzip2 -9 >%s.tar.bz2"
                   % (release, archive))
          elif format == "gzip":
               run("tar cf - Python-Docs-%s | gzip -9 >%s.tgz"
                   % (release, archive))
          elif format == "zip":
               if os.path.exists(archive + ".zip"):
                    os.unlink(archive + ".zip")
               run("zip -q -r9 %s.zip Python-Docs-%s"
                   % (archive, release))

     # clean up the work area:
     os.chdir(pwd)
     shutil.rmtree(tempdir)


def run(cmd):
     if quiet < 2:
          print "+++", cmd
     if quiet:
          cmd = "%s >/dev/null" % cmd
     rc = os.system(cmd)
     if rc:
          sys.exit(rc)


def usage(warning=None):
     stdout = sys.stdout
     sys.stdout = sys.stderr
     program = os.path.basename(sys.argv[0])
     try:
          if warning:
               print "%s: %s\n" % (program, warning)
          print __doc__ % {"program": program}
     finally:
          sys.stdout = stdout


if __name__ == "__main__":
     main()
