1"""tarball
2
3Tool-specific initialization for tarball.
4
5"""
6
7## Commands to tackle a command based implementation:
8##to unpack on the fly...
9##gunzip < FILE.tar.gz | tar xvf -
10##to pack on the fly...
11##tar cvf - FILE-LIST | gzip -c > FILE.tar.gz
12
13import os.path
14
15import SCons.Builder
16import SCons.Node.FS
17import SCons.Util
18
19try:
20    import gzip
21    import tarfile
22    internal_targz = 1
23except ImportError:
24    internal_targz = 0
25
26TARGZ_DEFAULT_COMPRESSION_LEVEL = 9
27
28if internal_targz:
29    def targz(target, source, env):
30        def archive_name( path ):
31            path = os.path.normpath( os.path.abspath( path ) )
32            common_path = os.path.commonprefix( (base_dir, path) )
33            archive_name = path[len(common_path):]
34            return archive_name
35
36        def visit(tar, dirname, names):
37            for name in names:
38                path = os.path.join(dirname, name)
39                if os.path.isfile(path):
40                    tar.add(path, archive_name(path) )
41        compression = env.get('TARGZ_COMPRESSION_LEVEL',TARGZ_DEFAULT_COMPRESSION_LEVEL)
42        base_dir = os.path.normpath( env.get('TARGZ_BASEDIR', env.Dir('.')).abspath )
43        target_path = str(target[0])
44        fileobj = gzip.GzipFile( target_path, 'wb', compression )
45        tar = tarfile.TarFile(os.path.splitext(target_path)[0], 'w', fileobj)
46        for source in source:
47            source_path = str(source)
48            if source.isdir():
49                os.path.walk(source_path, visit, tar)
50            else:
51                tar.add(source_path, archive_name(source_path) )      # filename, arcname
52        tar.close()
53
54    targzAction = SCons.Action.Action(targz, varlist=['TARGZ_COMPRESSION_LEVEL','TARGZ_BASEDIR'])
55
56    def makeBuilder( emitter = None ):
57        return SCons.Builder.Builder(action = SCons.Action.Action('$TARGZ_COM', '$TARGZ_COMSTR'),
58                                     source_factory = SCons.Node.FS.Entry,
59                                     source_scanner = SCons.Defaults.DirScanner,
60                                     suffix = '$TARGZ_SUFFIX',
61                                     multi = 1)
62    TarGzBuilder = makeBuilder()
63
64    def generate(env):
65        """Add Builders and construction variables for zip to an Environment.
66           The following environnement variables may be set:
67           TARGZ_COMPRESSION_LEVEL: integer, [0-9]. 0: no compression, 9: best compression (same as gzip compression level).
68           TARGZ_BASEDIR: base-directory used to determine archive name (this allow archive name to be relative
69                          to something other than top-dir).
70        """
71        env['BUILDERS']['TarGz'] = TarGzBuilder
72        env['TARGZ_COM'] = targzAction
73        env['TARGZ_COMPRESSION_LEVEL'] = TARGZ_DEFAULT_COMPRESSION_LEVEL # range 0-9
74        env['TARGZ_SUFFIX']  = '.tar.gz'
75        env['TARGZ_BASEDIR'] = env.Dir('.')     # Sources archive name are made relative to that directory.
76else:
77    def generate(env):
78        pass
79
80
81def exists(env):
82    return internal_targz
83