author Mike Hommey <>
Tue, 01 Jul 2014 14:24:43 +0900
changeset 20414 82fdf36eab593bdb093e33ae461ce94bd62a1313
parent 19307 e698d16798075ccedfbfdf4efed2ba7351196d70
child 29843 f8693edcab2bc4f629521f6b6d093701eaf942e7
permissions -rw-r--r--
Bug 1031291 - Prepare comm-central to m-c changes from bug 762358 on a CLOSED TREE. r=jcranmer

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at

# --- check that one directory is an exact subset of another
# Usage: python 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 | | Usage: %s COPY ORIGINAL' % sys.argv[0]

copy = os.path.abspath(sys.argv[1])
original = os.path.abspath(sys.argv[2])

# 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
        return exceptions
        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):
    for (dirpath, dirnames, filenames) in os.walk('.'):
        exceptions = read_exceptions(join(dirpath, 'check-sync-exceptions'))
        for dirname in dirnames:
            if fnmatch_any(dirname, exceptions):
        for filename in filenames:
            if fnmatch_any(filename, exceptions):
            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)):
            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 | | build file copies are not in sync\n' \
                             'TEST-INFO | | file(s) found in:               %s\n' \
                             'TEST-INFO | | differ from their originals in: %s' \
                             % (copy, original)
    print >> sys.stderr, 'TEST-INFO | | differing file:                 %s' % differing
    differences_found = True

check(copy, original)

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 '' for more details.''' \
         % (copy, original)
    print >> sys.stderr, textwrap.fill(msg, 75)

print >> sys.stderr, 'TEST-PASS | | %s <= %s' % (copy, original)