Index: Lib/distutils/archive_util.py =================================================================== --- Lib/distutils/archive_util.py (revision 67926) +++ Lib/distutils/archive_util.py (working copy) @@ -15,45 +15,67 @@ 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' + + """Create a tar file (optionally compressed) containing 'base_dir' + with files. 'compress' must be "gzip" (the default), "compress", + "bzip2", or None. For "compress" mode or if tarfile module is not + available, "tar" and the compression utility named by 'compress' + param must be on the default program search path. + + 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']} + # flags for tar compression program, each element of list will be an argument + compress_flags = { None : '-cf', + 'gzip': '-czf', + 'compress': '-cZf', + 'bzip2': '-cjf'} if compress is not None and compress not in compress_ext.keys(): raise ValueError, \ - "bad value for 'compress': must be None, 'gzip', or 'compress'" + "bad value for 'compress': must be None, 'gzip', 'bzip2' or 'compress'" + try: + import tarfile + # guard against CompressionError exceptions in case these are absent + if compress == 'gzip': + import gzip + elif compress == 'bzip2': + import bz2 + except ImportError: + tarfile = None + archive_name = base_name + ".tar" mkpath(os.path.dirname(archive_name), dry_run=dry_run) - cmd = ["tar", "-cf", archive_name, base_dir] - spawn(cmd, dry_run=dry_run) + if not tarfile or compress == 'compress': + if compress: + archive_name = archive_name + compress_ext[compress] + cmd = ["tar", compress_flags[compress], archive_name, base_dir] + spawn(cmd, dry_run=dry_run) - if compress: - spawn([compress] + compress_flags[compress] + [archive_name], - dry_run=dry_run) - return archive_name + compress_ext[compress] - else: - return archive_name + elif not dry_run: + if not compress: + tf = tarfile.open(archive_name, "w:") + else: + archive_name = archive_name + compress_ext[compress] + mode = {'gzip':'gz', 'bzip2':'bz2'}[compress] + # hack with chdir is needed until issue4750 is fixed + savepath = os.getcwdu() + tdir, tname = os.path.split(archive_name) + os.chdir(tdir) + tf = tarfile.open(tname, "w:%s" % mode) + os.chdir(savepath) + + tf.add(base_dir) + tf.close() + + return archive_name + # make_tarball ()