]> granicus.if.org Git - python/commitdiff
Added 'make_tarball()' and 'make_zipfile()' functions in preparation
authorGreg Ward <gward@python.net>
Wed, 29 Mar 2000 02:48:40 +0000 (02:48 +0000)
committerGreg Ward <gward@python.net>
Wed, 29 Mar 2000 02:48:40 +0000 (02:48 +0000)
for the 'bdist_dumb' command.  Adapted, with tweakage, from the 'sdist'
command.

Lib/distutils/util.py

index caf9906281f8c6c0a7ae3621c29f41b48e64c27b..b40373c4866344d3ffeb54a699ee7849d7c0183e 100644 (file)
@@ -13,7 +13,7 @@ __revision__ = "$Id$"
 
 import sys, os, string, re, shutil
 from distutils.errors import *
-
+from distutils.spawn import spawn
 
 # cache for by mkpath() -- in addition to cheapening redundant calls,
 # eliminates redundant "creating /foo/bar/baz" messages in dry-run mode
@@ -316,7 +316,6 @@ def copy_tree (src, dst,
                verbose=0,
                dry_run=0):
 
-
     """Copy an entire directory tree 'src' to a new location 'dst'.  Both
        'src' and 'dst' must be directory names.  If 'src' is not a
        directory, raise DistutilsFileError.  If 'dst' does not exist, it
@@ -556,3 +555,92 @@ def subst_vars (str, local_vars):
     return re.sub (r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, str)
 
 # subst_vars ()
+
+
+def make_tarball (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", 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" 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",
+                     'compress': ".Z" }
+
+    if compress is not None and compress not in ('gzip', 'compress'):
+        raise ValueError, \
+              "bad value for 'compress': must be None, 'gzip', or 'compress'"
+
+    archive_name = base_dir + ".tar"
+    cmd = ["tar", "-cf", archive_name, base_dir]
+    spawn (cmd, verbose=verbose, dry_run=dry_run)
+
+    if compress:
+        spawn ([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_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_dir + ".zip"
+    try:
+        spawn (["zip", "-r", 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.join (dirname, name)
+                if os.path.isfile (path):
+                    z.write (path, path)
+
+        if not dry_run:
+            z = zipfile.ZipFile (zip_filename, "wb",
+                                 compression=zipfile.ZIP_DEFLATED)
+
+            os.path.walk (base_dir, visit, z)
+            z.close()
+
+    return zip_filename
+
+# make_zipfile ()