[Scons-users] Using a custom Node class

Greg Ward greg at gerg.ca
Thu Jun 28 13:50:55 EDT 2012


Hi all --

I recently figured out how to write a custom Node class to override
the default signature behaviour. (Specifically, hashing Java .jar
files is too sensitive, since the same bytecode can yield different
signatures due to file timestamps changing. So instead I open up the
jar and hash the contents of each file in it. Works pretty well.)

But I'm unclear on the best way to *use* my new class. Currently I'm
just doing this:

jarfile = env.File('$build_dir/java/%s.jar' % name)
jarfile.__class__ = JarNode

Rationale: env.File() is not the constructor, it's a factory method
that does other magic stuff. I don't want to repeat that stuff, I just
want env.File() to do it for me. And then I change the new File object
to a JarNode object. (JarNode is a subclass of SCons.Node.FS.File, so
this seems like a pretty safe transformation.) It's gross, but it
works.

Is there a cleaner way to do this?

Thanks!

Greg

P.S. for posterity, here is my JarNode class:

class JarNode(SCons.Node.FS.File):
'''Custom Node for Java .jar files. Used to override the default
signature computation, which is way too ticklish for jar files. After
recompiling a Java component with no changes, all of the .class files
will be the same as before, but the jar file will be different due to
timestamps and/or filesystem ordering. That's silly. The signature
should just pay attention to the bytes in the .class files, not the
bytes in the .jar file.'''
def get_content_hash(self):
md5 = hashlib.md5()
jarfile = zipfile.ZipFile(self.abspath, 'r')
for name in sorted(jarfile.namelist()):
md5.update(name)
md5.update(jarfile.read(name))
#print('%s: hash = %s' % (self.path, md5.hexdigest()))
return md5.hexdigest()

# Don't bother to override get_contents(): it is called when the file
# is < 64 bytes, meaning we'll go back to the default behaviour of
# hashing the jar itself rather than the files in the jar. I imagine
# jar files this small are exceedingly rare, so I'm simply not going to
# worry about it. If it happens, we'll get spurious downstream
# rebuilds: oh well.


More information about the Scons-users mailing list