"""distutils.archive_util

Utility functions for creating archive files (tarballs, zip files,
that sort of thing)."""

# created 2000/04/03, Greg Ward (extracted from util.py)

__revision__ = "$Id$"

import os
from distutils.errors import DistutilsExecError
from distutils.spawn import spawn
from distutils.dir_util import mkpath

def make_tarball (base_name, base_dir, compress="gzip",
                  verbose=0, dry_run=0):
    """Create a (possibly compressed) tar file from all the files under
    'base_dir'.  'compress' must be "gzip" (the default), "compress",
    "bzip2", or None.  Both "tar" and the compression utility named by
    'compress' must be on the default program search path, so this is
    probably Unix-specific.  The output tar file will be named 'base_dir' +
    ".tar", possibly plus the appropriate compression extension (".gz",
    ".bz2" or ".Z").  Return the output filename.
    """
    # XXX GNU tar 1.13 has a nifty option to add a prefix directory.
    # It's pretty new, though, so we certainly can't require it --
    # but it would be nice to take advantage of it to skip the
    # "create a tree of hardlinks" step!  (Would also be nice to
    # detect GNU tar to use its 'z' option and save a step.)

    compress_ext = { 'gzip': ".gz",
                     'bzip2': '.bz2',
                     'compress': ".Z" }

    # flags for compression program, each element of list will be an argument
    compress_flags = {'gzip': ["-f9"],
                      'compress': ["-f"],
                      'bzip2': ['-f9']}

    if compress is not None and compress not in compress_ext.keys():
        raise ValueError, \
              "bad value for 'compress': must be None, 'gzip', or 'compress'"

    archive_name = base_name + ".tar"
    mkpath(os.path.dirname(archive_name), verbose=verbose, dry_run=dry_run)
    cmd = ["tar", "-cf", archive_name, base_dir]
    spawn(cmd, verbose=verbose, dry_run=dry_run)

    if compress:
        spawn([compress] + compress_flags[compress] + [archive_name],
              verbose=verbose, dry_run=dry_run)
        return archive_name + compress_ext[compress]
    else:
        return archive_name

# make_tarball ()


def make_zipfile (base_name, base_dir, verbose=0, dry_run=0):
    """Create a zip file from all the files under 'base_dir'.  The output
    zip file will be named 'base_dir' + ".zip".  Uses either the InfoZIP
    "zip" utility (if installed and found on the default search path) or
    the "zipfile" Python module (if available).  If neither tool is
    available, raises DistutilsExecError.  Returns the name of the output
    zip file.
    """
    # This initially assumed the Unix 'zip' utility -- but
    # apparently InfoZIP's zip.exe works the same under Windows, so
    # no changes needed!

    zip_filename = base_name + ".zip"
    mkpath(os.path.dirname(zip_filename), verbose=verbose, dry_run=dry_run)
    try:
        spawn(["zip", "-rq", zip_filename, base_dir],
              verbose=verbose, dry_run=dry_run)
    except DistutilsExecError:

        # XXX really should distinguish between "couldn't find
        # external 'zip' command" and "zip failed" -- shouldn't try
        # again in the latter case.  (I think fixing this will
        # require some cooperation from the spawn module -- perhaps
        # a utility function to search the path, so we can fallback
        # on zipfile.py without the failed spawn.)
        try:
            import zipfile
        except ImportError:
            raise DistutilsExecError, \
                  ("unable to create zip file '%s': " +
                   "could neither find a standalone zip utility nor " +
                   "import the 'zipfile' module") % zip_filename

        if verbose:
            print "creating '%s' and adding '%s' to it" % \
                  (zip_filename, base_dir)

        def visit (z, dirname, names):
            for name in names:
                path = os.path.normpath(os.path.join(dirname, name))
                if os.path.isfile(path):
                    z.write(path, path)

        if not dry_run:
            z = zipfile.ZipFile(zip_filename, "w",
                                compression=zipfile.ZIP_DEFLATED)

            os.path.walk(base_dir, visit, z)
            z.close()

    return zip_filename

# make_zipfile ()


ARCHIVE_FORMATS = {
    'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
    'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
    'ztar':  (make_tarball, [('compress', 'compress')], "compressed tar file"),
    'tar':   (make_tarball, [('compress', None)], "uncompressed tar file"),
    'zip':   (make_zipfile, [],"ZIP file")
    }

def check_archive_formats (formats):
    for format in formats:
        if not ARCHIVE_FORMATS.has_key(format):
            return format
    else:
        return None

def make_archive (base_name, format,
                  root_dir=None, base_dir=None,
                  verbose=0, dry_run=0):
    """Create an archive file (eg. zip or tar).  'base_name' is the name
    of the file to create, minus any format-specific extension; 'format'
    is the archive format: one of "zip", "tar", "ztar", or "gztar".
    'root_dir' is a directory that will be the root directory of the
    archive; ie. we typically chdir into 'root_dir' before creating the
    archive.  'base_dir' is the directory where we start archiving from;
    ie. 'base_dir' will be the common prefix of all files and
    directories in the archive.  'root_dir' and 'base_dir' both default
    to the current directory.  Returns the name of the archive file.
    """
    save_cwd = os.getcwd()
    if root_dir is not None:
        if verbose:
            print "changing into '%s'" % root_dir
        base_name = os.path.abspath(base_name)
        if not dry_run:
            os.chdir(root_dir)

    if base_dir is None:
        base_dir = os.curdir

    kwargs = { 'verbose': verbose,
               'dry_run': dry_run }

    try:
        format_info = ARCHIVE_FORMATS[format]
    except KeyError:
        raise ValueError, "unknown archive format '%s'" % format

    func = format_info[0]
    for (arg,val) in format_info[1]:
        kwargs[arg] = val
    filename = apply(func, (base_name, base_dir), kwargs)

    if root_dir is not None:
        if verbose:
            print "changing back to '%s'" % save_cwd
        os.chdir(save_cwd)

    return filename

# make_archive ()
