Source code for dkfileutils.changed
# -*- coding: utf-8 -*-
"""Check if contents of directory has changed.
"""
import argparse
import os
import hashlib
from .listfiles import list_files
from .path import Path
[docs]def digest(dirname, glob=None):
"""Returns the md5 digest of all interesting files (or glob) in `dirname`.
"""
md5 = hashlib.md5()
if glob is None:
fnames = [fname for _, fname in list_files(Path(dirname))]
for fname in sorted(fnames):
fname = os.path.join(dirname, fname)
md5.update(open(fname, 'rb').read())
else:
fnames = Path(dirname).glob(glob)
for fname in sorted(fnames):
md5.update(fname.open('rb').read())
return md5.hexdigest()
[docs]def changed(dirname, filename='.md5', args=None, glob=None):
"""Has `glob` changed in `dirname`
Args:
dirname: directory to measure
filename: filename to store checksum
"""
root = Path(dirname)
if not root.exists():
# if dirname doesn't exist it is changed (by definition)
return True
cachefile = root / filename
current_digest = cachefile.open().read() if cachefile.exists() else ""
_digest = digest(dirname, glob=glob)
if args and args.verbose: # pragma: nocover
print "md5:", _digest
has_changed = current_digest != _digest
if has_changed:
with open(os.path.join(dirname, filename), 'w') as fp:
fp.write(_digest)
return has_changed
[docs]class Directory(Path):
"""A path that is a directory.
"""
[docs] def changed(self, filename='.md5', glob=None):
"""Are any of the files matched by ``glob`` changed?
"""
if glob is not None:
filename += '.glob-' + ''.join(ch.lower()
for ch in glob if ch.isalpha())
return changed(self, filename, glob=glob)
[docs]def main(): # pragma: nocover
"""Return exit code of zero iff directory is not changed.
"""
p = argparse.ArgumentParser()
p.add_argument(
'directory',
help="Directory to check"
)
p.add_argument(
'--verbose', '-v', action='store_true',
help="increase verbosity"
)
args = p.parse_args()
import sys
_changed = changed(sys.argv[1], args=args)
sys.exit(_changed)
if __name__ == "__main__": # pragma: nocover
main()