diff options
Diffstat (limited to 'js/src/config/check-sync-dirs.py')
-rw-r--r-- | js/src/config/check-sync-dirs.py | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/js/src/config/check-sync-dirs.py b/js/src/config/check-sync-dirs.py new file mode 100644 index 0000000..ed2abb3 --- /dev/null +++ b/js/src/config/check-sync-dirs.py @@ -0,0 +1,107 @@ +# check-sync-dirs.py --- check that one directory is an exact subset of another +# +# Usage: python check-sync-dirs.py COPY ORIGINAL +# +# Check that the files present in the directory tree COPY are exact +# copies of their counterparts in the directory tree ORIGINAL. COPY +# need not have all the files in ORIGINAL, but COPY may not have files +# absent from ORIGINAL. +# +# Each directory in COPY may have a file named +# 'check-sync-exceptions', which lists files in COPY that need not be +# the same as the corresponding file in ORIGINAL, or exist at all in +# ORIGINAL. (The 'check-sync-exceptions' file itself is always +# treated as exceptional.) Blank lines and '#' comments in the file +# are ignored. + +import sys +import os +from os.path import join +import filecmp +import textwrap +import fnmatch + +if len(sys.argv) != 3: + print >> sys.stderr, 'TEST-UNEXPECTED-FAIL | check-sync-dirs.py | Usage: %s COPY ORIGINAL' % sys.argv[0] + sys.exit(1) + +copy = os.path.abspath(sys.argv[1]) +original = os.path.abspath(sys.argv[2]) + +# Ignore detritus left lying around by editing tools. +ignored_patterns = ['*~', '.#*', '#*#', '*.orig', '*.rej'] + +# Return the contents of FILENAME, a 'check-sync-exceptions' file, as +# a dictionary whose keys are exactly the list of filenames, along +# with the basename of FILENAME itself. If FILENAME does not exist, +# return the empty dictionary. +def read_exceptions(filename): + if (os.path.exists(filename)): + f = file(filename) + exceptions = {} + for line in f: + line = line.strip() + if line != '' and line[0] != '#': + exceptions[line] = None + exceptions[os.path.basename (filename)] = None + f.close() + return exceptions + else: + return {} + +# Return true if FILENAME matches any pattern in the list of filename +# patterns PATTERNS. +def fnmatch_any(filename, patterns): + for pattern in patterns: + if fnmatch.fnmatch(filename, pattern): + return True + return False + +# Check the contents of the directory tree COPY against ORIGINAL. For each +# file that differs, apply REPORT to COPY, ORIGINAL, and the file's +# relative path. COPY and ORIGINAL should be absolute. Ignore files +# that match patterns given in the list IGNORE. +def check(copy, original, ignore): + os.chdir(copy) + for (dirpath, dirnames, filenames) in os.walk('.'): + exceptions = read_exceptions(join(dirpath, 'check-sync-exceptions')) + for dirname in dirnames: + if (dirname in exceptions): + dirnames.remove(dirname) + break + for filename in filenames: + if (filename in exceptions) or fnmatch_any(filename, ignore): + continue + relative_name = join(dirpath, filename) + original_name = join(original, relative_name) + if (os.path.exists(original_name) + and filecmp.cmp(relative_name, original_name, False)): + continue + report(copy, original, relative_name) + +differences_found = False + +# Print an error message for DIFFERING, which was found to differ +# between COPY and ORIGINAL. Set the global variable differences_found. +def report(copy, original, differing): + global differences_found + if not differences_found: + print >> sys.stderr, 'TEST-UNEXPECTED-FAIL | check-sync-dirs.py | build file copies are not in sync\n' \ + 'TEST-INFO | check-sync-dirs.py | file(s) found in: %s\n' \ + 'TEST-INFO | check-sync-dirs.py | differ from their originals in: %s' \ + % (copy, original) + print >> sys.stderr, 'TEST-INFO | check-sync-dirs.py | differing file: %s' % differing + differences_found = True + +check(copy, original, ignored_patterns) + +if differences_found: + msg = '''In general, the files in '%s' should always be exact copies of +originals in '%s'. A change made to one should also be made to the +other. See 'check-sync-dirs.py' for more details.''' \ + % (copy, original) + print >> sys.stderr, textwrap.fill(msg, 75) + sys.exit(1) + +print >> sys.stderr, 'TEST-PASS | check-sync-dirs.py | %s <= %s' % (copy, original) +sys.exit(0) |