Skip to content

Instantly share code, notes, and snippets.

@AndrewWalker
Last active August 29, 2015 14:21
Show Gist options
  • Save AndrewWalker/d9d74f5f46651c6607b4 to your computer and use it in GitHub Desktop.
Save AndrewWalker/d9d74f5f46651c6607b4 to your computer and use it in GitHub Desktop.
Stupid things to do with SCons
import inspect
import re
class MethodRewriter(object):
def __init__(self, method):
self._method = method
def update_code(self, lines):
return lines
def indent_level(self, line):
return len(re.match('^(\s*)', line).group(1))
def dedent(self, lines):
indentSize = self.indent_level(lines[0])
lines = [line[indentSize:] for line in lines]
return lines
def temporary_name(self, original):
return '___' + original
def rewrite(self):
lines, _ = inspect.getsourcelines(self._method)
# dedent method to function
lines = self.dedent(lines)
# rewrite function name
old = self._method.im_func.__name__
tmp = self.temporary_name(old)
lines[0] = lines[0].replace(old, tmp)
# generic rewriting
lines = self.update_code(lines)
src = ''.join(lines)
# exec code
d = self._method.im_func.func_globals
assert(tmp not in d)
exec(src, d)
# lift method back onto class
cls = d[self._method.im_class.__name__]
setattr(cls, old, d[tmp])
del d[tmp]
class MyRewriter(MethodRewriter):
def __init__(self, *args):
super(MyRewriter, self).__init__(*args)
def update_code(self, lines):
lines.insert(-1, ' self._validate_sconscript(files)\n')
return lines
def sconscript_validator(cls):
rw = MyRewriter(getattr(cls, 'SConscript'))
rw.rewrite()
def _validate_sconscript(self, files):
import os
path = files[0]
if not os.path.exists(path):
abspath = os.path.normpath(path)
raise Exception('invalid SConscript at ' + abspath)
setattr(cls, '_validate_sconscript', _validate_sconscript)
import scommon
scommon.sconscript_validator(Environment)
menv = Environment()
menv.SConscript('SConscript', exports=['menv'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment