Aug 16

Applying patches using SCons

A project has third-party dependencies that need to be patched before being used. I’m new to SCons, but here is my go at applying patches using the build tool.

site_scons/site_init.py

import os

def TOOL_VENDOR(env):
    def patch_generator(source, target, env, for_signature):
        """Generate a patched version of source in target (both being
        directories). If a patch is missing, do nothing.
        """
        target = target[0]
        source = source[0]
        patch_path = '%s.patch' % source.path
        cmds = []
        if len(Glob(patch_path)):
            cmds += [
                Delete(target),
                Copy(target, source),
                "cd %s && patch -p1 < %s" % (target.path, os.path.abspath(patch_path)),
                ]
        return cmds
    env.Append(BUILDERS = {'VendorPatch': Builder(generator=patch_generator)})

SConstruct

env = Environment(tools=['default', TOOL_VENDOR])
SConscript([
        'vendor/SConscript',
        ], exports='env')

vendor/ is a directory with third-party libraries. The vendor/SConscript file will

  1. find directories such as vendor/acme-parser/repo and create a patched version of it in vendor/acme-parser/patched, if vendor/acme-parser/repo.patch exists, and
  2. run any existing library SConscript files.

vendor/SConscript

Import('env')
import os

for repo in Glob('*/repo'):
    env.VendorPatch(Dir(os.path.join(repo.dir.name, 'patched')), repo)

SConscript(Glob('*/SConscript'), exports='env')


Simon Pantzare
Simon Pantzare, also available on
Facebook,
Twitter,
Google+,
Reddit,
Github (dev blog).
Ask me anything.