index 5a47e4f92fee57868cc2ad51e916731a8380b163..51becb0880fffc929ee93ee67a914d96392ababa 100644 (file)
--- a/roundup/install_util.py
+++ b/roundup/install_util.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: install_util.py,v 1.1 2001-11-12 22:26:32 jhermann Exp $
+# $Id: install_util.py,v 1.11 2006-01-25 03:11:43 richard Exp $
-import os, sha
+"""Support module to generate and check fingerprints of installed files.
+"""
+__docformat__ = 'restructuredtext'
+import os, shutil
+from roundup.anypy.hashlib_ import sha1
+
+sgml_file_types = [".xml", ".ent", ".html"]
+hash_file_types = [".py", ".sh", ".conf", ".cgi"]
+slast_file_types = [".css"]
+
+digested_file_types = sgml_file_types + hash_file_types + slast_file_types
+
+def extractFingerprint(lines):
+ # get fingerprint from last line
+ if lines[-1].startswith("#SHA: "):
+ # handle .py/.sh comment
+ return lines[-1][6:].strip()
+ elif lines[-1].startswith("<!-- SHA: "):
+ # handle xml/html files
+ fingerprint = lines[-1][10:]
+ fingerprint = fingerprint.replace('-->', '')
+ return fingerprint.strip()
+ elif lines[-1].startswith("/* SHA: "):
+ # handle css files
+ fingerprint = lines[-1][8:]
+ fingerprint = fingerprint.replace('*/', '')
+ return fingerprint.strip()
+ return None
def checkDigest(filename):
"""Read file, check for valid fingerprint, return TRUE if ok"""
lines = inp.readlines()
inp.close()
- # get fingerprint from last line
- if lines[-1][:6] == "#SHA: ":
- # handle .py/.sh comment
- fingerprint = lines[-1][6:].strip()
- elif lines[-1][:10] == "<!-- SHA: ":
- # handle xml files
- fingerprint = lines[-1][10:]
- fingerprint = fingerprint.replace('-->', '')
- fingerprint = fingerprint.strip()
- else:
+ fingerprint = extractFingerprint(lines)
+ if fingerprint is None:
return 0
del lines[-1]
# calculate current digest
- digest = sha.new()
+ digest = sha1()
for line in lines:
digest.update(line)
def __init__(self, filename):
self.filename = filename
- self.digest = sha.new()
+ self.digest = sha1()
self.file = open(self.filename, "w")
def write(self, data):
+ lines = data.splitlines()
+ # if the file is coming from an installed tracker being used as a
+ # template, then we will want to re-calculate the SHA
+ fingerprint = extractFingerprint(lines)
+ if fingerprint is not None:
+ data = '\n'.join(lines[:-1]) + '\n'
self.file.write(data)
self.digest.update(data)
def close(self):
file, ext = os.path.splitext(self.filename)
- if ext in [".xml", ".ent"]:
+ if ext in sgml_file_types:
self.file.write("<!-- SHA: %s -->\n" % (self.digest.hexdigest(),))
- elif ext in [".py", ".sh", ".conf", '']:
+ elif ext in hash_file_types:
self.file.write("#SHA: %s\n" % (self.digest.hexdigest(),))
+ elif ext in slast_file_types:
+ self.file.write("/* SHA: %s */\n" % (self.digest.hexdigest(),))
self.file.close()
+def copyDigestedFile(src, dst, copystat=1):
+ """ Copy data from `src` to `dst`, adding a fingerprint to `dst`.
+ If `copystat` is true, the file status is copied, too
+ (like shutil.copy2).
+ """
+ if os.path.isdir(dst):
+ dst = os.path.join(dst, os.path.basename(src))
+
+ dummy, ext = os.path.splitext(src)
+ if ext not in digested_file_types:
+ if copystat:
+ return shutil.copy2(src, dst)
+ else:
+ return shutil.copyfile(src, dst)
+
+ fsrc = None
+ fdst = None
+ try:
+ fsrc = open(src, 'r')
+ fdst = DigestFile(dst)
+ shutil.copyfileobj(fsrc, fdst)
+ finally:
+ if fdst: fdst.close()
+ if fsrc: fsrc.close()
+
+ if copystat: shutil.copystat(src, dst)
+
+
def test():
import sys
testdata = open(sys.argv[0], 'r').read()
- testfile = "digest_test.py"
- out = DigestFile(testfile)
- out.write(testdata)
- out.close()
+ for ext in digested_file_types:
+ testfile = "__digest_test" + ext
+
+ out = DigestFile(testfile)
+ out.write(testdata)
+ out.close()
- assert checkDigest(testfile), "digest ok w/o modification"
+ assert checkDigest(testfile), "digest ok w/o modification"
- mod = open(testfile, 'r+')
- mod.seek(0)
- mod.write('# changed!')
- mod.close()
+ mod = open(testfile, 'r+')
+ mod.seek(0)
+ mod.write('# changed!')
+ mod.close()
- assert not checkDigest(testfile), "digest fails after modification"
+ assert not checkDigest(testfile), "digest fails after modification"
- os.remove(testfile)
+ os.remove(testfile)
if __name__ == '__main__':
test()
-#
-# $Log: not supported by cvs2svn $
-
+# vim: set filetype=python ts=4 sw=4 et si