1# Copyright 2010 Baptiste Lepilleur and The JsonCpp Authors 2# Distributed under MIT license, or public domain if desired and 3# recognized in your jurisdiction. 4# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 6from contextlib import closing 7import os 8import tarfile 9 10TARGZ_DEFAULT_COMPRESSION_LEVEL = 9 11 12def make_tarball(tarball_path, sources, base_dir, prefix_dir=''): 13 """Parameters: 14 tarball_path: output path of the .tar.gz file 15 sources: list of sources to include in the tarball, relative to the current directory 16 base_dir: if a source file is in a sub-directory of base_dir, then base_dir is stripped 17 from path in the tarball. 18 prefix_dir: all files stored in the tarball be sub-directory of prefix_dir. Set to '' 19 to make them child of root. 20 """ 21 base_dir = os.path.normpath(os.path.abspath(base_dir)) 22 def archive_name(path): 23 """Makes path relative to base_dir.""" 24 path = os.path.normpath(os.path.abspath(path)) 25 common_path = os.path.commonprefix((base_dir, path)) 26 archive_name = path[len(common_path):] 27 if os.path.isabs(archive_name): 28 archive_name = archive_name[1:] 29 return os.path.join(prefix_dir, archive_name) 30 def visit(tar, dirname, names): 31 for name in names: 32 path = os.path.join(dirname, name) 33 if os.path.isfile(path): 34 path_in_tar = archive_name(path) 35 tar.add(path, path_in_tar) 36 compression = TARGZ_DEFAULT_COMPRESSION_LEVEL 37 with closing(tarfile.TarFile.open(tarball_path, 'w:gz', 38 compresslevel=compression)) as tar: 39 for source in sources: 40 source_path = source 41 if os.path.isdir(source): 42 for dirpath, dirnames, filenames in os.walk(source_path): 43 visit(tar, dirpath, filenames) 44 else: 45 path_in_tar = archive_name(source_path) 46 tar.add(source_path, path_in_tar) # filename, arcname 47 48def decompress(tarball_path, base_dir): 49 """Decompress the gzipped tarball into directory base_dir. 50 """ 51 with closing(tarfile.TarFile.open(tarball_path)) as tar: 52 tar.extractall(base_dir) 53