1#!/usr/bin/env python3
2# Copyright 2020 the V8 project authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""
6Compare two folders and print any differences between files to both a
7results file and stderr.
8
9Specifically we use this to compare the output of Torque generator for
10both x86 and x64 (-m32) toolchains.
11"""
12
13import difflib
14import filecmp
15import itertools
16import os
17import sys
18
19assert len(sys.argv) > 3
20
21folder1 = sys.argv[1]
22folder2 = sys.argv[2]
23results_file_name = sys.argv[3]
24
25with open(results_file_name, "w") as results_file:
26  def write(line):
27    # Print line to both results file and stderr
28    sys.stderr.write(line)
29    results_file.write(line)
30
31  def has_one_sided_diff(dcmp, side, side_list):
32    # Check that we do not have files only on one side of the comparison
33    if side_list:
34      write("Some files exist only in %s\n" % side)
35      for fl in side_list:
36        write(fl)
37    return side_list
38
39  def has_content_diff(dcmp):
40    # Check that we do not have content differences in the common files
41    _, diffs, _ = filecmp.cmpfiles(
42          dcmp.left, dcmp.right,
43          dcmp.common_files, shallow=False)
44    if diffs:
45      write("Found content differences between %s and %s\n" %
46        (dcmp.left, dcmp.right))
47      for name in diffs:
48        write("File diff %s\n" % name)
49        left_file = os.path.join(dcmp.left, name)
50        right_file = os.path.join(dcmp.right, name)
51        with open(left_file) as f1, open(right_file) as f2:
52          diff = difflib.unified_diff(
53              f1.readlines(), f2.readlines(),
54              dcmp.left, dcmp.right)
55          for l in itertools.islice(diff, 100):
56            write(l)
57        write("\n\n")
58    return diffs
59
60  dcmp = filecmp.dircmp(folder1, folder2)
61  has_diffs = has_one_sided_diff(dcmp, dcmp.left, dcmp.left_only) \
62    or has_one_sided_diff(dcmp, dcmp.right, dcmp.right_only) \
63    or has_content_diff(dcmp)
64
65if has_diffs:
66  sys.exit(1)
67