Home | History | Annotate | Download | only in scons-tools
      1 """tarball
      2 
      3 Tool-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 
     13 import os.path
     14 
     15 import SCons.Builder
     16 import SCons.Node.FS
     17 import SCons.Util
     18 
     19 try:
     20     import gzip
     21     import tarfile
     22     internal_targz = 1
     23 except ImportError:
     24     internal_targz = 0
     25 
     26 TARGZ_DEFAULT_COMPRESSION_LEVEL = 9
     27 
     28 if 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.
     76 else:
     77     def generate(env):
     78         pass
     79 
     80 
     81 def exists(env):
     82     return internal_targz
     83