def calculate_hash_of_files(files, root):
    """Return a hash of all of the given files at the given root.

    Adapted from stacker.hooks.aws_lambda; used according to its license:
    https://github.com/cloudtools/stacker/blob/1.4.0/LICENSE

    Args:
        files (list[str]): file names to include in the hash calculation,
            relative to ``root``.
        root (str): base directory to analyze files in.
    Returns:
        str: A hash of the hashes of the given files.

    """
    file_hash = hashlib.md5()
    for fname in sorted(files):
        fileobj = os.path.join(root, fname)
        file_hash.update((fname + "\0").encode())
        with open(fileobj, "rb") as filedes:
            for chunk in iter(lambda: filedes.read(4096), ""):  # noqa pylint: disable=cell-var-from-loop
                if not chunk:
                    break
                file_hash.update(chunk)
            file_hash.update("\0".encode())

    return file_hash.hexdigest()
def calculate_hash_of_files ( files , root ) : file_hash = hashlib . md5 ( ) for fname in sorted ( files ) : fileobj = os . path . join ( root , fname ) file_hash . update ( ( fname + "\0" ) . encode ( ) ) with open ( fileobj , "rb" ) as filedes : for chunk in iter ( lambda : filedes . read ( 4096 ) , "" ) : if not chunk : break file_hash . update ( chunk ) file_hash . update ( "\0" . encode ( ) ) return file_hash . hexdigest ( )
Return a hash of all of the given files at the given root.

    Adapted from stacker.hooks.aws_lambda; used according to its license:
    https://github.com/cloudtools/stacker/blob/1.4.0/LICENSE

    Args:
        files (list[str]): file names to include in the hash calculation,
            relative to ``root``.
        root (str): base directory to analyze files in.
    Returns:
        str: A hash of the hashes of the given files.