summaryrefslogtreecommitdiffstats
path: root/Lib/distutils/util.py
diff options
context:
space:
mode:
authorGreg Ward <gward@python.net>2000-03-29 02:48:40 (GMT)
committerGreg Ward <gward@python.net>2000-03-29 02:48:40 (GMT)
commit7c1a6d477771955e3773849ef636fceda81bb3d5 (patch)
treec3c06a812a1d934ddfb59484b961bc8fe33b3222 /Lib/distutils/util.py
parent03d1ae1f0152ef5a6fe4f8a21302387979bd04c9 (diff)
downloadcpython-7c1a6d477771955e3773849ef636fceda81bb3d5.zip
cpython-7c1a6d477771955e3773849ef636fceda81bb3d5.tar.gz
cpython-7c1a6d477771955e3773849ef636fceda81bb3d5.tar.bz2
Added 'make_tarball()' and 'make_zipfile()' functions in preparation
for the 'bdist_dumb' command. Adapted, with tweakage, from the 'sdist' command.
Diffstat (limited to 'Lib/distutils/util.py')
-rw-r--r--Lib/distutils/util.py92
1 files changed, 90 insertions, 2 deletions
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index caf9906..b40373c 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -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 ()