Please note:The SCons wiki is in read-only mode due to ongoing spam/DoS issues. Also, new account creation is currently disabled. We are looking into alternative wiki hosts.

DistZip Builder

   1 # DistZipBuilder: tool to generate zip files using SCons
   2 #
   3 # Copyright (C) 2005, 2006  Matthew A. Nicholson
   4 # Copyright (C) 2006  John Pye
   5 #
   6 # This file is free software; you can redistribute it and/or
   7 # modify it under the terms of the GNU Lesser General Public
   8 # License version 2.1 as published by the Free Software Foundation.
   9 #
  10 # This file is distributed in the hope that it will be useful,
  11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 # Lesser General Public License for more details.
  14 #
  15 # You should have received a copy of the GNU Lesser General Public
  16 # License along with this library; if not, write to the Free Software
  17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19 import os,sys
  20 from SCons.Script import *
  21 import SCons.Builder
  22 
  23 def DistZipEmitter(target,source,env):
  24 
  25    source,origsource = [], source
  26 
  27    excludeexts = env.Dictionary().get('DISTZIP_EXCLUDEEXTS',[])
  28    excludedirs = env.Dictionary().get('DISTZIP_EXCLUDEDIRS',[])
  29 
  30    # assume the sources are directories... need to check that
  31    for item in origsource:
  32       if os.path.isdir(str(item)):
  33          for root, dirs, files in os.walk(str(item)):
  34 
  35             # don't make directory dependences as that triggers full build
  36             # of that directory
  37             if root in source:
  38                #print "Removing directory %s" % root
  39                source.remove(root)
  40 
  41             # loop through files in a directory
  42             for name in files:
  43                ext = os.path.splitext(name)
  44                if not ext[1] in excludeexts:
  45                   relpath = os.path.join(root,name)
  46                   source.append(relpath)
  47             for d in excludedirs:
  48                if d in dirs:
  49                   dirs.remove(d)  # don't visit CVS directories etc
  50       else:
  51          ext = os.path.splitext(str(item))
  52          if not ext[1] in excludeexts:
  53             source.append(str(item))
  54 
  55    return target, source
  56 
  57 def DistZipString(target, source, env):
  58    """
  59    This is what gets printed on the console. We'll strip out the list or source
  60    files, since it tends to get very long. If you want to see the contents, the
  61    easiest way is to uncomment the line 'Adding to ZIP file' below.
  62    """
  63    return 'DistZip(%s,...)' % str(target[0])
  64 
  65 def DistZip(target, source, env):
  66    """zip archive builder"""
  67 
  68    import zipfile
  69 
  70    env_dict = env.Dictionary()
  71 
  72    # split the target directory, filename, and stuffix
  73    base_name = str(target[0]).split('.zip')[0]
  74    (target_dir, dir_name) = os.path.split(base_name)
  75 
  76    # create the target directory if it does not exist
  77    if target_dir and not os.path.exists(target_dir):
  78       os.makedirs(target_dir)
  79 
  80    # open our zip file for writing
  81    sys.stderr.write("DistZip: Writing " + str(target[0]))
  82    the_zip = zipfile.ZipFile(str(target[0]), "w")
  83 
  84    # write sources to our zip file
  85    for item in source:
  86       item = str(item)
  87       sys.stderr.write(".")
  88       #print "Adding to ZIP file: %s/%s" % (dir_name,item)
  89       the_zip.write(item, '%s/%s' % (dir_name,item), zipfile.ZIP_DEFLATED)
  90 
  91    # all done
  92    sys.stderr.write("\n") #print "Closing ZIP file"
  93    the_zip.close()
  94 
  95 def DistZipSuffix(env, sources):
  96     """zip archive suffix generator"""
  97     return ".zip"
  98 
  99 def generate(env):
 100    """
 101    Add builders and construction variables for the DistZip builder.
 102    """
 103 
 104    env.Append(BUILDERS = {
 105       'DistZip': env.Builder(
 106          action = SCons.Action.Action(DistZip, DistZipString),
 107          suffix = DistZipSuffix,
 108          emitter = DistZipEmitter,
 109          target_factory = env.fs.Entry,
 110       ),
 111    })
 112 
 113 
 114 def exists(env):
 115    """
 116    Make sure this tool exists.
 117    """
 118    try:
 119       import os
 120       import zipfile
 121    except ImportError:
 122       return False
 123    else:
 124       return True

Save the above listing as DistZip.py. DistZip example usage:

   1 env.Append(tools = ["DistZip"])
   2 
   3 env.Append(
   4     DISTZIP_EXCLUDEEXTS = ['.o','.os','.so','.a','.dll','.cache','.pyc','.cvsignore','.dblite','.log','.gz','.bz2','.zip'],
   5     DISTZIP_EXCLUDEDIRS = ['CVS','.svn','.sconf_temp', 'dist']
   6 )
   7 
   8 PACKAGE_NAME = "example"
   9 PACKAGE_VERSION = "1.0.0"
  10 
  11 # Only create the zip file when the target "zip" is explicitly specified on the scons command line.
  12 # Be sure to do a scons -c (clean) before scons zip, it keeps any built items out of the zip file.
  13 if 'zip' in COMMAND_LINE_TARGETS:
  14     zip = env.DistZip(PACKAGE_NAME + "-" + PACKAGE_VERSION + ".zip", [env.Dir('.')])
  15     env.Alias("zip", zip)

DistZipBuilder (last edited 2008-03-12 02:47:13 by localhost)