From f9b6fc51269dd6141de3f30847fbc1ee69b56a90 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 10 Oct 2019 17:40:12 +0000 Subject: [PATCH] [lit] Extend internal diff to support -U When using lit's internal shell, RUN lines like the following accidentally execute an external `diff` instead of lit's internal `diff`: ``` # RUN: program | diff -U1 file - ``` Such cases exist now, in `clang/test/Analysis` for example. We are preparing patches to ensure lit's internal `diff` is called in such cases, which will then fail because lit's internal `diff` doesn't recognize `-U` as a command-line option. This patch adds `-U` support. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D68668 llvm-svn: 374392 --- utils/lit/lit/builtin_commands/diff.py | 24 +++++- .../Inputs/shtest-shell/diff-unified.txt | 38 +++++++++ utils/lit/tests/max-failures.py | 2 +- utils/lit/tests/shtest-shell.py | 78 ++++++++++++++++++- 4 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 utils/lit/tests/Inputs/shtest-shell/diff-unified.txt diff --git a/utils/lit/lit/builtin_commands/diff.py b/utils/lit/lit/builtin_commands/diff.py index 0e912d150fe..6340eacdf01 100644 --- a/utils/lit/lit/builtin_commands/diff.py +++ b/utils/lit/lit/builtin_commands/diff.py @@ -10,6 +10,7 @@ class DiffFlags(): self.ignore_all_space = False self.ignore_space_change = False self.unified_diff = False + self.num_context_lines = 3 self.recursive_diff = False self.strip_trailing_cr = False @@ -48,7 +49,10 @@ def compareTwoBinaryFiles(flags, filepaths, filelines): exitCode = 0 if hasattr(difflib, 'diff_bytes'): # python 3.5 or newer - diffs = difflib.diff_bytes(difflib.unified_diff, filelines[0], filelines[1], filepaths[0].encode(), filepaths[1].encode()) + diffs = difflib.diff_bytes(difflib.unified_diff, filelines[0], + filelines[1], filepaths[0].encode(), + filepaths[1].encode(), + n = flags.num_context_lines) diffs = [diff.decode(errors="backslashreplace") for diff in diffs] else: # python 2.7 @@ -56,7 +60,8 @@ def compareTwoBinaryFiles(flags, filepaths, filelines): func = difflib.unified_diff else: func = difflib.context_diff - diffs = func(filelines[0], filelines[1], filepaths[0], filepaths[1]) + diffs = func(filelines[0], filelines[1], filepaths[0], filepaths[1], + n = flags.num_context_lines) for diff in diffs: sys.stdout.write(diff) @@ -88,7 +93,8 @@ def compareTwoTextFiles(flags, filepaths, filelines_bin, encoding): filelines[idx]= [f(line) for line in lines] func = difflib.unified_diff if flags.unified_diff else difflib.context_diff - for diff in func(filelines[0], filelines[1], filepaths[0], filepaths[1]): + for diff in func(filelines[0], filelines[1], filepaths[0], filepaths[1], + n = flags.num_context_lines): sys.stdout.write(diff) exitCode = 1 return exitCode @@ -171,7 +177,7 @@ def compareDirTrees(flags, dir_trees, base_paths=["", ""]): def main(argv): args = argv[1:] try: - opts, args = getopt.gnu_getopt(args, "wbur", ["strip-trailing-cr"]) + opts, args = getopt.gnu_getopt(args, "wbuU:r", ["strip-trailing-cr"]) except getopt.GetoptError as err: sys.stderr.write("Unsupported: 'diff': %s\n" % str(err)) sys.exit(1) @@ -185,6 +191,16 @@ def main(argv): flags.ignore_space_change = True elif o == "-u": flags.unified_diff = True + elif o.startswith("-U"): + flags.unified_diff = True + try: + flags.num_context_lines = int(a) + if flags.num_context_lines < 0: + raise ValueException + except: + sys.stderr.write("Error: invalid '-U' argument: {}\n" + .format(a)) + sys.exit(1) elif o == "-r": flags.recursive_diff = True elif o == "--strip-trailing-cr": diff --git a/utils/lit/tests/Inputs/shtest-shell/diff-unified.txt b/utils/lit/tests/Inputs/shtest-shell/diff-unified.txt new file mode 100644 index 00000000000..e977c193247 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/diff-unified.txt @@ -0,0 +1,38 @@ +# RUN: echo 1 > %t.foo +# RUN: echo 2 >> %t.foo +# RUN: echo 3 >> %t.foo +# RUN: echo 4 >> %t.foo +# RUN: echo 5 >> %t.foo +# RUN: echo 6 foo >> %t.foo +# RUN: echo 7 >> %t.foo +# RUN: echo 8 >> %t.foo +# RUN: echo 9 >> %t.foo +# RUN: echo 10 >> %t.foo +# RUN: echo 11 >> %t.foo + +# RUN: echo 1 > %t.bar +# RUN: echo 2 >> %t.bar +# RUN: echo 3 >> %t.bar +# RUN: echo 4 >> %t.bar +# RUN: echo 5 >> %t.bar +# RUN: echo 6 bar >> %t.bar +# RUN: echo 7 >> %t.bar +# RUN: echo 8 >> %t.bar +# RUN: echo 9 >> %t.bar +# RUN: echo 10 >> %t.bar +# RUN: echo 11 >> %t.bar + +# Default is 3 lines of context. +# RUN: diff -u %t.foo %t.bar && false || true + +# Override default of 3 lines of context. +# RUN: diff -U 2 %t.foo %t.bar && false || true +# RUN: diff -U4 %t.foo %t.bar && false || true +# RUN: diff -U0 %t.foo %t.bar && false || true + +# Check bad -U argument. +# RUN: diff -U 30.1 %t.foo %t.foo && false || true +# RUN: diff -U-1 %t.foo %t.foo && false || true + +# Fail so lit will print output. +# RUN: false diff --git a/utils/lit/tests/max-failures.py b/utils/lit/tests/max-failures.py index 67f21caa1bb..a1c337fd605 100644 --- a/utils/lit/tests/max-failures.py +++ b/utils/lit/tests/max-failures.py @@ -8,7 +8,7 @@ # # END. -# CHECK: Failing Tests (30) +# CHECK: Failing Tests (31) # CHECK: Failing Tests (1) # CHECK: Failing Tests (2) # CHECK: error: Option '--max-failures' requires positive integer diff --git a/utils/lit/tests/shtest-shell.py b/utils/lit/tests/shtest-shell.py index db57c3af1f1..c7e05d6bc42 100644 --- a/utils/lit/tests/shtest-shell.py +++ b/utils/lit/tests/shtest-shell.py @@ -331,6 +331,82 @@ # CHECK: PASS: shtest-shell :: diff-r.txt + +# CHECK: FAIL: shtest-shell :: diff-unified.txt + +# CHECK: *** TEST 'shtest-shell :: diff-unified.txt' FAILED *** + +# CHECK: $ "diff" "-u" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: 3 +# CHECK-NEXT: 4 +# CHECK-NEXT: 5 +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-NEXT: 7 +# CHECK-NEXT: 8 +# CHECK-NEXT: 9 +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U" "2" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: 4 +# CHECK-NEXT: 5 +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-NEXT: 7 +# CHECK-NEXT: 8 +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U4" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: 2 +# CHECK-NEXT: 3 +# CHECK-NEXT: 4 +# CHECK-NEXT: 5 +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-NEXT: 7 +# CHECK-NEXT: 8 +# CHECK-NEXT: 9 +# CHECK-NEXT: 10 +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U0" "{{[^"]*}}.foo" "{{[^"]*}}.bar" +# CHECK: # command output: +# CHECK: @@ {{.*}} @@ +# CHECK-NEXT: -6 foo +# CHECK-NEXT: +6 bar +# CHECK-EMPTY: +# CHECK-NEXT: error: command failed with exit status: 1 +# CHECK-NEXT: $ "true" + +# CHECK: $ "diff" "-U" "30.1" "{{[^"]*}}" "{{[^"]*}}" +# CHECK: # command stderr: +# CHECK: Error: invalid '-U' argument: 30.1 +# CHECK: error: command failed with exit status: 1 +# CHECK: $ "true" + +# CHECK: $ "diff" "-U-1" "{{[^"]*}}" "{{[^"]*}}" +# CHECK: # command stderr: +# CHECK: Error: invalid '-U' argument: -1 +# CHECK: error: command failed with exit status: 1 +# CHECK: $ "true" + +# CHECK: $ "false" + +# CHECK: *** + + # CHECK: FAIL: shtest-shell :: error-0.txt # CHECK: *** TEST 'shtest-shell :: error-0.txt' FAILED *** # CHECK: $ "not-a-real-command" @@ -410,4 +486,4 @@ # CHECK: PASS: shtest-shell :: sequencing-0.txt # CHECK: XFAIL: shtest-shell :: sequencing-1.txt # CHECK: PASS: shtest-shell :: valid-shell.txt -# CHECK: Failing Tests (30) +# CHECK: Failing Tests (31)