| Index: scons-2.0.1/engine/SCons/Tool/packaging/__init__.py
|
| ===================================================================
|
| --- scons-2.0.1/engine/SCons/Tool/packaging/__init__.py (revision 0)
|
| +++ scons-2.0.1/engine/SCons/Tool/packaging/__init__.py (revision 0)
|
| @@ -0,0 +1,312 @@
|
| +"""SCons.Tool.Packaging
|
| +
|
| +SCons Packaging Tool.
|
| +"""
|
| +
|
| +#
|
| +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
|
| +#
|
| +# Permission is hereby granted, free of charge, to any person obtaining
|
| +# a copy of this software and associated documentation files (the
|
| +# "Software"), to deal in the Software without restriction, including
|
| +# without limitation the rights to use, copy, modify, merge, publish,
|
| +# distribute, sublicense, and/or sell copies of the Software, and to
|
| +# permit persons to whom the Software is furnished to do so, subject to
|
| +# the following conditions:
|
| +#
|
| +# The above copyright notice and this permission notice shall be included
|
| +# in all copies or substantial portions of the Software.
|
| +#
|
| +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
| +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
| +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
| +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
| +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
| +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| +
|
| +__revision__ = "src/engine/SCons/Tool/packaging/__init__.py 5134 2010/08/16 23:02:40 bdeegan"
|
| +
|
| +import SCons.Environment
|
| +from SCons.Variables import *
|
| +from SCons.Errors import *
|
| +from SCons.Util import is_List, make_path_relative
|
| +from SCons.Warnings import warn, Warning
|
| +
|
| +import os, imp
|
| +import SCons.Defaults
|
| +
|
| +__all__ = [ 'src_targz', 'src_tarbz2', 'src_zip', 'tarbz2', 'targz', 'zip', 'rpm', 'msi', 'ipk' ]
|
| +
|
| +#
|
| +# Utility and Builder function
|
| +#
|
| +def Tag(env, target, source, *more_tags, **kw_tags):
|
| + """ Tag a file with the given arguments, just sets the accordingly named
|
| + attribute on the file object.
|
| +
|
| + TODO: FIXME
|
| + """
|
| + if not target:
|
| + target=source
|
| + first_tag=None
|
| + else:
|
| + first_tag=source
|
| +
|
| + if first_tag:
|
| + kw_tags[first_tag[0]] = ''
|
| +
|
| + if len(kw_tags) == 0 and len(more_tags) == 0:
|
| + raise UserError("No tags given.")
|
| +
|
| + # XXX: sanity checks
|
| + for x in more_tags:
|
| + kw_tags[x] = ''
|
| +
|
| + if not SCons.Util.is_List(target):
|
| + target=[target]
|
| + else:
|
| + # hmm, sometimes the target list, is a list of a list
|
| + # make sure it is flattened prior to processing.
|
| + # TODO: perhaps some bug ?!?
|
| + target=env.Flatten(target)
|
| +
|
| + for t in target:
|
| + for (k,v) in kw_tags.items():
|
| + # all file tags have to start with PACKAGING_, so we can later
|
| + # differentiate between "normal" object attributes and the
|
| + # packaging attributes. As the user should not be bothered with
|
| + # that, the prefix will be added here if missing.
|
| + #if not k.startswith('PACKAGING_'):
|
| + if k[:10] != 'PACKAGING_':
|
| + k='PACKAGING_'+k
|
| + setattr(t, k, v)
|
| +
|
| +def Package(env, target=None, source=None, **kw):
|
| + """ Entry point for the package tool.
|
| + """
|
| + # check if we need to find the source files ourself
|
| + if not source:
|
| + source = env.FindInstalledFiles()
|
| +
|
| + if len(source)==0:
|
| + raise UserError("No source for Package() given")
|
| +
|
| + # decide which types of packages shall be built. Can be defined through
|
| + # four mechanisms: command line argument, keyword argument,
|
| + # environment argument and default selection( zip or tar.gz ) in that
|
| + # order.
|
| + try: kw['PACKAGETYPE']=env['PACKAGETYPE']
|
| + except KeyError: pass
|
| +
|
| + if not kw.get('PACKAGETYPE'):
|
| + from SCons.Script import GetOption
|
| + kw['PACKAGETYPE'] = GetOption('package_type')
|
| +
|
| + if kw['PACKAGETYPE'] == None:
|
| + if 'Tar' in env['BUILDERS']:
|
| + kw['PACKAGETYPE']='targz'
|
| + elif 'Zip' in env['BUILDERS']:
|
| + kw['PACKAGETYPE']='zip'
|
| + else:
|
| + raise UserError("No type for Package() given")
|
| +
|
| + PACKAGETYPE=kw['PACKAGETYPE']
|
| + if not is_List(PACKAGETYPE):
|
| + PACKAGETYPE=PACKAGETYPE.split(',')
|
| +
|
| + # load the needed packagers.
|
| + def load_packager(type):
|
| + try:
|
| + file,path,desc=imp.find_module(type, __path__)
|
| + return imp.load_module(type, file, path, desc)
|
| + except ImportError, e:
|
| + raise EnvironmentError("packager %s not available: %s"%(type,str(e)))
|
| +
|
| + packagers=list(map(load_packager, PACKAGETYPE))
|
| +
|
| + # set up targets and the PACKAGEROOT
|
| + try:
|
| + # fill up the target list with a default target name until the PACKAGETYPE
|
| + # list is of the same size as the target list.
|
| + if not target: target = []
|
| +
|
| + size_diff = len(PACKAGETYPE)-len(target)
|
| + default_name = "%(NAME)s-%(VERSION)s"
|
| +
|
| + if size_diff>0:
|
| + default_target = default_name%kw
|
| + target.extend( [default_target]*size_diff )
|
| +
|
| + if 'PACKAGEROOT' not in kw:
|
| + kw['PACKAGEROOT'] = default_name%kw
|
| +
|
| + except KeyError, e:
|
| + raise SCons.Errors.UserError( "Missing Packagetag '%s'"%e.args[0] )
|
| +
|
| + # setup the source files
|
| + source=env.arg2nodes(source, env.fs.Entry)
|
| +
|
| + # call the packager to setup the dependencies.
|
| + targets=[]
|
| + try:
|
| + for packager in packagers:
|
| + t=[target.pop(0)]
|
| + t=packager.package(env,t,source, **kw)
|
| + targets.extend(t)
|
| +
|
| + assert( len(target) == 0 )
|
| +
|
| + except KeyError, e:
|
| + raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\
|
| + % (e.args[0],packager.__name__) )
|
| + except TypeError, e:
|
| + # this exception means that a needed argument for the packager is
|
| + # missing. As our packagers get their "tags" as named function
|
| + # arguments we need to find out which one is missing.
|
| + from inspect import getargspec
|
| + args,varargs,varkw,defaults=getargspec(packager.package)
|
| + if defaults!=None:
|
| + args=args[:-len(defaults)] # throw away arguments with default values
|
| + args.remove('env')
|
| + args.remove('target')
|
| + args.remove('source')
|
| + # now remove any args for which we have a value in kw.
|
| + args=[x for x in args if x not in kw]
|
| +
|
| + if len(args)==0:
|
| + raise # must be a different error, so reraise
|
| + elif len(args)==1:
|
| + raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\
|
| + % (args[0],packager.__name__) )
|
| + else:
|
| + raise SCons.Errors.UserError( "Missing Packagetags '%s' for %s packager"\
|
| + % (", ".join(args),packager.__name__) )
|
| +
|
| + target=env.arg2nodes(target, env.fs.Entry)
|
| + targets.extend(env.Alias( 'package', targets ))
|
| + return targets
|
| +
|
| +#
|
| +# SCons tool initialization functions
|
| +#
|
| +
|
| +added = None
|
| +
|
| +def generate(env):
|
| + from SCons.Script import AddOption
|
| + global added
|
| + if not added:
|
| + added = 1
|
| + AddOption('--package-type',
|
| + dest='package_type',
|
| + default=None,
|
| + type="string",
|
| + action="store",
|
| + help='The type of package to create.')
|
| +
|
| + try:
|
| + env['BUILDERS']['Package']
|
| + env['BUILDERS']['Tag']
|
| + except KeyError:
|
| + env['BUILDERS']['Package'] = Package
|
| + env['BUILDERS']['Tag'] = Tag
|
| +
|
| +def exists(env):
|
| + return 1
|
| +
|
| +# XXX
|
| +def options(opts):
|
| + opts.AddVariables(
|
| + EnumVariable( 'PACKAGETYPE',
|
| + 'the type of package to create.',
|
| + None, allowed_values=list(map( str, __all__ )),
|
| + ignorecase=2
|
| + )
|
| + )
|
| +
|
| +#
|
| +# Internal utility functions
|
| +#
|
| +
|
| +def copy_attr(f1, f2):
|
| + """ copies the special packaging file attributes from f1 to f2.
|
| + """
|
| + #pattrs = [x for x in dir(f1) if not hasattr(f2, x) and\
|
| + # x.startswith('PACKAGING_')]
|
| + copyit = lambda x: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
|
| + pattrs = list(filter(copyit, dir(f1)))
|
| + for attr in pattrs:
|
| + setattr(f2, attr, getattr(f1, attr))
|
| +def putintopackageroot(target, source, env, pkgroot, honor_install_location=1):
|
| + """ Uses the CopyAs builder to copy all source files to the directory given
|
| + in pkgroot.
|
| +
|
| + If honor_install_location is set and the copied source file has an
|
| + PACKAGING_INSTALL_LOCATION attribute, the PACKAGING_INSTALL_LOCATION is
|
| + used as the new name of the source file under pkgroot.
|
| +
|
| + The source file will not be copied if it is already under the the pkgroot
|
| + directory.
|
| +
|
| + All attributes of the source file will be copied to the new file.
|
| + """
|
| + # make sure the packageroot is a Dir object.
|
| + if SCons.Util.is_String(pkgroot): pkgroot=env.Dir(pkgroot)
|
| + if not SCons.Util.is_List(source): source=[source]
|
| +
|
| + new_source = []
|
| + for file in source:
|
| + if SCons.Util.is_String(file): file = env.File(file)
|
| +
|
| + if file.is_under(pkgroot):
|
| + new_source.append(file)
|
| + else:
|
| + if hasattr(file, 'PACKAGING_INSTALL_LOCATION') and\
|
| + honor_install_location:
|
| + new_name=make_path_relative(file.PACKAGING_INSTALL_LOCATION)
|
| + else:
|
| + new_name=make_path_relative(file.get_path())
|
| +
|
| + new_file=pkgroot.File(new_name)
|
| + new_file=env.CopyAs(new_file, file)[0]
|
| + copy_attr(file, new_file)
|
| + new_source.append(new_file)
|
| +
|
| + return (target, new_source)
|
| +
|
| +def stripinstallbuilder(target, source, env):
|
| + """ strips the install builder action from the source list and stores
|
| + the final installation location as the "PACKAGING_INSTALL_LOCATION" of
|
| + the source of the source file. This effectively removes the final installed
|
| + files from the source list while remembering the installation location.
|
| +
|
| + It also warns about files which have no install builder attached.
|
| + """
|
| + def has_no_install_location(file):
|
| + return not (file.has_builder() and\
|
| + hasattr(file.builder, 'name') and\
|
| + (file.builder.name=="InstallBuilder" or\
|
| + file.builder.name=="InstallAsBuilder"))
|
| +
|
| + if len(list(filter(has_no_install_location, source))):
|
| + warn(Warning, "there are files to package which have no\
|
| + InstallBuilder attached, this might lead to irreproducible packages")
|
| +
|
| + n_source=[]
|
| + for s in source:
|
| + if has_no_install_location(s):
|
| + n_source.append(s)
|
| + else:
|
| + for ss in s.sources:
|
| + n_source.append(ss)
|
| + copy_attr(s, ss)
|
| + setattr(ss, 'PACKAGING_INSTALL_LOCATION', s.get_path())
|
| +
|
| + return (target, n_source)
|
| +
|
| +# Local Variables:
|
| +# tab-width:4
|
| +# indent-tabs-mode:nil
|
| +# End:
|
| +# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
|
| Property changes on: scons-2.0.1/engine/SCons/Tool/packaging/__init__.py
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|