def _directory_checksum(resources_dir):

    # The input to the SHA1 contains entries of the form (whitespace
    # only included here for readability):
    #
    # / \0 MODE \0 MTIME \0
    # /foo \0 MODE \0 MTIME \0
    # ...
    #
    # where there is one entry for each directory or file (order is
    # specified below), followed by a numeric representation of the
    # mode, and the mtime in milliseconds since the epoch.

    output_sha1 = hashlib.sha1()

    for dirname, subdirs, files in os.walk(resources_dir):
        if not dirname.startswith(resources_dir):
            raise AssertionError('Expected %r to start with root directory %r' % (dirname, resources_dir))

        # Add an entry for the directory itself
        relative_dirname = dirname[len(resources_dir):]
        dir_stat = os.lstat(dirname)
        if not relative_dirname.startswith('/'):
            relative_dirname = '/' + relative_dirname
        fields = [relative_dirname, str(dir_stat.st_mode), str(int(dir_stat.st_mtime * 1000))]
        output_sha1.update(b''.join(s.encode('utf-8') + b'\0' for s in fields))

        # Canonicalize the order of files so that we compute the
        # checksum in a consistent order
        for filename in sorted(files):
            relative_filename = os.path.join(relative_dirname, filename)
            true_filename = os.path.join(dirname, filename)

            file_stat = os.lstat(true_filename)
            fields = [relative_filename, str(file_stat.st_mode), str(int(file_stat.st_mtime * 1000))]
            output_sha1.update(b''.join(s.encode('utf-8') + b'\0' for s in fields))

        # Canonicalize the order of subdirectories; this is the order in
        # which they will be visited by os.walk
        subdirs.sort()

    return output_sha1.hexdigest()
Returns a hash of the contents of resources_dir.
dataset/ETHPy150Open dnanexus/dx-toolkit/src/python/dxpy/app_builder.py/_directory_checksum