| Index: site_scons/site_tools/seven_zip.py
|
| ===================================================================
|
| --- site_scons/site_tools/seven_zip.py (revision 0)
|
| +++ site_scons/site_tools/seven_zip.py (revision 0)
|
| @@ -0,0 +1,145 @@
|
| +#!/usr/bin/python2.4
|
| +# Copyright 2008, Google Inc.
|
| +# All rights reserved.
|
| +#
|
| +# Redistribution and use in source and binary forms, with or without
|
| +# modification, are permitted provided that the following conditions are
|
| +# met:
|
| +#
|
| +# * Redistributions of source code must retain the above copyright
|
| +# notice, this list of conditions and the following disclaimer.
|
| +# * Redistributions in binary form must reproduce the above
|
| +# copyright notice, this list of conditions and the following disclaimer
|
| +# in the documentation and/or other materials provided with the
|
| +# distribution.
|
| +# * Neither the name of Google Inc. nor the names of its
|
| +# contributors may be used to endorse or promote products derived from
|
| +# this software without specific prior written permission.
|
| +#
|
| +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| +
|
| +
|
| +"""SCons tool for 7zip."""
|
| +
|
| +
|
| +import os
|
| +import shutil
|
| +import subprocess
|
| +import tempfile
|
| +import SCons.Script
|
| +
|
| +
|
| +def SevenZipGetFiles(env, source):
|
| + """SCons emitter for 7zip extract.
|
| +
|
| + Examines the source 7z archive to determine the list of files which will be
|
| + created by extract/unzip operation.
|
| + Args:
|
| + env: The SCons environment to get the 7zip command line from.
|
| + source: The 7zip archive to examine.
|
| + Returns:
|
| + The list of filenames in the archive.
|
| + """
|
| + # Expand the command to list archive contents.
|
| + cmd = env.subst('$SEVEN_ZIP l "%s"' % source)
|
| + # Run it and capture output.
|
| + output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
|
| + # Strip off 7-line header and 3-line trailer from 7zip output.
|
| + lines = output.split('\r\n')[7:-3]
|
| + # Trim out just the files and their names.
|
| + files = [i[53:] for i in lines if i[20] != 'D']
|
| + return files
|
| +
|
| +
|
| +def SevenZipEmitter(target, source, env):
|
| + """An emitter that decides what nodes are vented from a 7zip archive.
|
| +
|
| + Args:
|
| + target: The target directory node.
|
| + source: The source archive node.
|
| + env: The environment in which the emit takes place.
|
| + Returns:
|
| + The pair (target, source) which lists the emitted targets and sources.
|
| + """
|
| + # Remember out dir for later.
|
| + env['SEVEN_ZIP_OUT_DIR'] = target[0].dir
|
| + # Get out contents
|
| + files = SevenZipGetFiles(env, env.subst('$SOURCE', source=source))
|
| + # Extract a layer deeper if there is only one, and it extension is 7z.
|
| + if env.get('SEVEN_ZIP_PEEL_LAYERS', False):
|
| + assert len(files) == 1 and os.path.splitext(files[0])[1] == '.7z'
|
| + # Create a temporary directory.
|
| + tmp_dir = tempfile.mkdtemp()
|
| + # Expand the command to extract the archive to a temporary location.
|
| + cmd = env.subst('$SEVEN_ZIP x $SOURCE -o"%s"' % tmp_dir, source=source[0])
|
| + # Run it and swallow output.
|
| + subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
|
| + # Get contents.
|
| + inner_files = SevenZipGetFiles(env, os.path.join(tmp_dir, files[0]))
|
| + # Make into file nodes.
|
| + inner_files = [target[0].dir.File(i) for i in inner_files]
|
| + # Delete temp_dir.
|
| + shutil.rmtree(tmp_dir)
|
| + # Decide where to extra working file to.
|
| + working_file = env.Dir(target[0].dir.abspath +
|
| + '.7zip_extract').File(files[0])
|
| + # Combine everything.
|
| + files = [working_file] + inner_files
|
| + else:
|
| + # Make into file nodes.
|
| + files = [target[0].dir.File(i) for i in files]
|
| + # Return files as actual target.
|
| + return (files, source)
|
| +
|
| +
|
| +def SevenZipGenerator(source, target, env, for_signature):
|
| + """The generator function which decides how to extract a file."""
|
| +
|
| + # Silence lint.
|
| + source = source
|
| + target = target
|
| + for_signature = for_signature
|
| +
|
| + if env.get('SEVEN_ZIP_PEEL_LAYERS', False):
|
| + return [SCons.Script.Delete('$SEVEN_ZIP_OUT_DIR'),
|
| + '$SEVEN_ZIP x $SOURCE -o"${TARGET.dir}"',
|
| + '$SEVEN_ZIP x $TARGET -o"$SEVEN_ZIP_OUT_DIR"']
|
| + else:
|
| + return [SCons.Script.Delete('$SEVEN_ZIP_OUT_DIR'),
|
| + '$SEVEN_ZIP x $SOURCE -o"$SEVEN_ZIP_OUT_DIR"']
|
| +
|
| +
|
| +def generate(env):
|
| + # NOTE: SCons requires the use of this name, which fails gpylint.
|
| + """SCons entry point for this tool."""
|
| +
|
| + env.Replace(
|
| + SEVEN_ZIP='$SEVEN_ZIP_DIR/7za.exe',
|
| + SEVEN_ZIP_ARCHIVE_OPTIONS = ['-t7z', '-mx0'],
|
| + SEVEN_ZIP_COMPRESS_OPTIONS = ['-t7z', '-mx9'],
|
| + )
|
| +
|
| + b = SCons.Script.Builder(generator=SevenZipGenerator,
|
| + emitter=SevenZipEmitter)
|
| + env['BUILDERS']['Extract7zip'] = b
|
| +
|
| + b = SCons.Script.Builder(
|
| + action=('cd $SOURCE && '
|
| + '$SEVEN_ZIP a $SEVEN_ZIP_ARCHIVE_OPTIONS ${TARGET.abspath} ./'))
|
| + env['BUILDERS']['Archive7zip'] = b
|
| +
|
| + b = SCons.Script.Builder(
|
| + action=('cd ${SOURCE.dir} && '
|
| + '$SEVEN_ZIP a $SEVEN_ZIP_COMPRESS_OPTIONS '
|
| + '${TARGET.abspath} ${SOURCE.file}'))
|
| + env['BUILDERS']['Compress7zip'] = b
|
|
|