PyXR

c:\python24\lib \ distutils \ archive_util.py



0001 """distutils.archive_util
0002 
0003 Utility functions for creating archive files (tarballs, zip files,
0004 that sort of thing)."""
0005 
0006 # This module should be kept compatible with Python 1.5.2.
0007 
0008 __revision__ = "$Id: archive_util.py,v 1.16 2004/07/18 06:14:41 tim_one Exp $"
0009 
0010 import os
0011 from distutils.errors import DistutilsExecError
0012 from distutils.spawn import spawn
0013 from distutils.dir_util import mkpath
0014 from distutils import log
0015 
0016 def make_tarball (base_name, base_dir, compress="gzip",
0017                   verbose=0, dry_run=0):
0018     """Create a (possibly compressed) tar file from all the files under
0019     'base_dir'.  'compress' must be "gzip" (the default), "compress",
0020     "bzip2", or None.  Both "tar" and the compression utility named by
0021     'compress' must be on the default program search path, so this is
0022     probably Unix-specific.  The output tar file will be named 'base_dir' +
0023     ".tar", possibly plus the appropriate compression extension (".gz",
0024     ".bz2" or ".Z").  Return the output filename.
0025     """
0026     # XXX GNU tar 1.13 has a nifty option to add a prefix directory.
0027     # It's pretty new, though, so we certainly can't require it --
0028     # but it would be nice to take advantage of it to skip the
0029     # "create a tree of hardlinks" step!  (Would also be nice to
0030     # detect GNU tar to use its 'z' option and save a step.)
0031 
0032     compress_ext = { 'gzip': ".gz",
0033                      'bzip2': '.bz2',
0034                      'compress': ".Z" }
0035 
0036     # flags for compression program, each element of list will be an argument
0037     compress_flags = {'gzip': ["-f9"],
0038                       'compress': ["-f"],
0039                       'bzip2': ['-f9']}
0040 
0041     if compress is not None and compress not in compress_ext.keys():
0042         raise ValueError, \
0043               "bad value for 'compress': must be None, 'gzip', or 'compress'"
0044 
0045     archive_name = base_name + ".tar"
0046     mkpath(os.path.dirname(archive_name), dry_run=dry_run)
0047     cmd = ["tar", "-cf", archive_name, base_dir]
0048     spawn(cmd, dry_run=dry_run)
0049 
0050     if compress:
0051         spawn([compress] + compress_flags[compress] + [archive_name],
0052               dry_run=dry_run)
0053         return archive_name + compress_ext[compress]
0054     else:
0055         return archive_name
0056 
0057 # make_tarball ()
0058 
0059 
0060 def make_zipfile (base_name, base_dir, verbose=0, dry_run=0):
0061     """Create a zip file from all the files under 'base_dir'.  The output
0062     zip file will be named 'base_dir' + ".zip".  Uses either the "zipfile"
0063     Python module (if available) or the InfoZIP "zip" utility (if installed
0064     and found on the default search path).  If neither tool is available,
0065     raises DistutilsExecError.  Returns the name of the output zip file.
0066     """
0067     try:
0068         import zipfile
0069     except ImportError:
0070         zipfile = None
0071 
0072     zip_filename = base_name + ".zip"
0073     mkpath(os.path.dirname(zip_filename), dry_run=dry_run)
0074 
0075     # If zipfile module is not available, try spawning an external
0076     # 'zip' command.
0077     if zipfile is None:
0078         if verbose:
0079             zipoptions = "-r"
0080         else:
0081             zipoptions = "-rq"
0082 
0083         try:
0084             spawn(["zip", zipoptions, zip_filename, base_dir],
0085                   dry_run=dry_run)
0086         except DistutilsExecError:
0087             # XXX really should distinguish between "couldn't find
0088             # external 'zip' command" and "zip failed".
0089             raise DistutilsExecError, \
0090                   ("unable to create zip file '%s': "
0091                    "could neither import the 'zipfile' module nor "
0092                    "find a standalone zip utility") % zip_filename
0093 
0094     else:
0095         log.info("creating '%s' and adding '%s' to it",
0096                  zip_filename, base_dir)
0097 
0098         def visit (z, dirname, names):
0099             for name in names:
0100                 path = os.path.normpath(os.path.join(dirname, name))
0101                 if os.path.isfile(path):
0102                     z.write(path, path)
0103                     log.info("adding '%s'" % path)
0104 
0105         if not dry_run:
0106             z = zipfile.ZipFile(zip_filename, "w",
0107                                 compression=zipfile.ZIP_DEFLATED)
0108 
0109             os.path.walk(base_dir, visit, z)
0110             z.close()
0111 
0112     return zip_filename
0113 
0114 # make_zipfile ()
0115 
0116 
0117 ARCHIVE_FORMATS = {
0118     'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"),
0119     'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"),
0120     'ztar':  (make_tarball, [('compress', 'compress')], "compressed tar file"),
0121     'tar':   (make_tarball, [('compress', None)], "uncompressed tar file"),
0122     'zip':   (make_zipfile, [],"ZIP file")
0123     }
0124 
0125 def check_archive_formats (formats):
0126     for format in formats:
0127         if not ARCHIVE_FORMATS.has_key(format):
0128             return format
0129     else:
0130         return None
0131 
0132 def make_archive (base_name, format,
0133                   root_dir=None, base_dir=None,
0134                   verbose=0, dry_run=0):
0135     """Create an archive file (eg. zip or tar).  'base_name' is the name
0136     of the file to create, minus any format-specific extension; 'format'
0137     is the archive format: one of "zip", "tar", "ztar", or "gztar".
0138     'root_dir' is a directory that will be the root directory of the
0139     archive; ie. we typically chdir into 'root_dir' before creating the
0140     archive.  'base_dir' is the directory where we start archiving from;
0141     ie. 'base_dir' will be the common prefix of all files and
0142     directories in the archive.  'root_dir' and 'base_dir' both default
0143     to the current directory.  Returns the name of the archive file.
0144     """
0145     save_cwd = os.getcwd()
0146     if root_dir is not None:
0147         log.debug("changing into '%s'", root_dir)
0148         base_name = os.path.abspath(base_name)
0149         if not dry_run:
0150             os.chdir(root_dir)
0151 
0152     if base_dir is None:
0153         base_dir = os.curdir
0154 
0155     kwargs = { 'dry_run': dry_run }
0156 
0157     try:
0158         format_info = ARCHIVE_FORMATS[format]
0159     except KeyError:
0160         raise ValueError, "unknown archive format '%s'" % format
0161 
0162     func = format_info[0]
0163     for (arg,val) in format_info[1]:
0164         kwargs[arg] = val
0165     filename = apply(func, (base_name, base_dir), kwargs)
0166 
0167     if root_dir is not None:
0168         log.debug("changing back to '%s'", save_cwd)
0169         os.chdir(save_cwd)
0170 
0171     return filename
0172 
0173 # make_archive ()
0174 

Generated by PyXR 0.9.4
SourceForge.net Logo