-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: case insensitive diff_test and fix manifest bug #527
base: main
Are you sure you want to change the base?
Changes from all commits
ed33b44
374f04c
64b9e2f
ab187cd
6b7d66e
88173c9
d909db4
63c2bc4
601b767
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# symlinks required on windows by copy_directory | ||
startup --windows_enable_symlinks |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,17 +26,39 @@ def _runfiles_path(f): | |
else: | ||
return f.path # source file | ||
|
||
def _ignore_line_endings(ctx): | ||
ignore_line_endings = "0" | ||
if ctx.attr.ignore_line_endings: | ||
ignore_line_endings = "1" | ||
return ignore_line_endings | ||
|
||
def _diff_test_impl(ctx): | ||
if ctx.attr.is_windows: | ||
bash_bin = ctx.toolchains["@bazel_tools//tools/sh:toolchain_type"].path | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that we require bash, I wonder if the maintenance of this rule would be simpler, to use the same bash script on windows (and maybe fallback to fc or just use diff)? |
||
test_bin = ctx.actions.declare_file(ctx.label.name + "-test.bat") | ||
ctx.actions.write( | ||
output = test_bin, | ||
content = """@rem Generated by diff_test.bzl, do not edit. | ||
@echo off | ||
SETLOCAL ENABLEEXTENSIONS | ||
SETLOCAL ENABLEDELAYEDEXPANSION | ||
set MF=%RUNFILES_MANIFEST_FILE:/=\\% | ||
set PATH=%SYSTEMROOT%\\system32 | ||
if defined RUNFILES_MANIFEST_FILE ( | ||
set MF=%RUNFILES_MANIFEST_FILE:/=\\% | ||
) else ( | ||
if exist MANIFEST ( | ||
set MF=MANIFEST | ||
) else ( | ||
if exist ..\\MANIFEST ( | ||
set MF=..\\MANIFEST | ||
) | ||
) | ||
) | ||
if not exist %MF% ( | ||
echo Manifest file %MF% not found | ||
exit /b 1 | ||
) | ||
echo using %MF% | ||
set F1={file1} | ||
set F2={file2} | ||
if "!F1:~0,9!" equ "external/" (set F1=!F1:~9!) else (set F1=!TEST_WORKSPACE!/!F1!) | ||
|
@@ -79,10 +101,36 @@ if "!RF2!" equ "" ( | |
exit /b 1 | ||
) | ||
) | ||
rem use tr command from msys64 package, msys64 is a bazel recommendation | ||
rem todo: in future better to pull in diff.exe to align with non-windows path | ||
if "{ignore_line_endings}"=="1" ( | ||
if exist {bash_bin} ( | ||
for %%f in ({bash_bin}) do set "TR=%%~dpf\\tr.exe" | ||
) else ( | ||
rem match bazel's algorithm to find unix tools | ||
set "TR=C:\\msys64\\usr\\bin\\tr.exe" | ||
) | ||
if not exist !TR! ( | ||
echo>&2 WARNING: ignore_line_endings set but !TR! not found; line endings will be compared | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bazel team is quite opinionated about warnings. This should be an error. |
||
) else ( | ||
for %%f in (!RF1!) do set RF1_TEMP=%TEST_TMPDIR%\\%%~nxf_lf1 | ||
for %%f in (!RF2!) do set RF2_TEMP=%TEST_TMPDIR%\\%%~nxf_lf2 | ||
type "!RF1!" | !TR! -d "\\r" > "!RF1_TEMP!" | ||
type "!RF2!" | !TR! -d "\\r" > "!RF2_TEMP!" | ||
set "RF1=!RF1_TEMP!" | ||
set "RF2=!RF2_TEMP!" | ||
rem echo original file !RF1! replaced by !RF1_TEMP! | ||
rem echo original file !RF2! replaced by !RF2_TEMP! | ||
) | ||
) | ||
fc.exe 2>NUL 1>NUL /B "!RF1!" "!RF2!" | ||
if %ERRORLEVEL% neq 0 ( | ||
if %ERRORLEVEL% equ 1 ( | ||
echo>&2 FAIL: files "{file1}" and "{file2}" differ. {fail_msg} | ||
set "FAIL_MSG={fail_msg}" | ||
if "!FAIL_MSG!"=="" ( | ||
set "FAIL_MSG=why? diff ^"!RF1!^" ^"!RF2!^" ^| cat -v" | ||
) | ||
echo>&2 FAIL: files "{file1}" and "{file2}" differ. !FAIL_MSG! | ||
exit /b 1 | ||
) else ( | ||
fc.exe /B "!RF1!" "!RF2!" | ||
|
@@ -94,6 +142,8 @@ if %ERRORLEVEL% neq 0 ( | |
fail_msg = ctx.attr.failure_message, | ||
file1 = _runfiles_path(ctx.file.file1), | ||
file2 = _runfiles_path(ctx.file.file2), | ||
ignore_line_endings = _ignore_line_endings(ctx), | ||
bash_bin = bash_bin, | ||
), | ||
is_executable = True, | ||
) | ||
|
@@ -120,14 +170,19 @@ else | |
echo >&2 "ERROR: could not find \"{file1}\" and \"{file2}\"" | ||
exit 1 | ||
fi | ||
if ! diff "$RF1" "$RF2"; then | ||
echo >&2 "FAIL: files \"{file1}\" and \"{file2}\" differ. "{fail_msg} | ||
if ! diff {strip_trailing_cr}"$RF1" "$RF2"; then | ||
MSG={fail_msg} | ||
if [[ "${{MSG}}" == "" ]]; then | ||
MSG="why? diff {strip_trailing_cr}"${{RF1}}" "${{RF2}}" | cat -v" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this message so different from the message before? Also use of RF1 is inconsistend with use of {file1} below. |
||
fi | ||
echo >&2 "FAIL: files \"{file1}\" and \"{file2}\" differ. ${{MSG}}" | ||
exit 1 | ||
fi | ||
""".format( | ||
fail_msg = shell.quote(ctx.attr.failure_message), | ||
file1 = _runfiles_path(ctx.file.file1), | ||
file2 = _runfiles_path(ctx.file.file2), | ||
strip_trailing_cr = "--strip-trailing-cr " if ctx.attr.ignore_line_endings else "", | ||
), | ||
is_executable = True, | ||
) | ||
|
@@ -148,13 +203,19 @@ _diff_test = rule( | |
allow_single_file = True, | ||
mandatory = True, | ||
), | ||
"ignore_line_endings": attr.bool( | ||
default = True, | ||
), | ||
"is_windows": attr.bool(mandatory = True), | ||
}, | ||
toolchains = [ | ||
"@bazel_tools//tools/sh:toolchain_type", | ||
], | ||
test = True, | ||
implementation = _diff_test_impl, | ||
) | ||
|
||
def diff_test(name, file1, file2, failure_message = None, **kwargs): | ||
def diff_test(name, file1, file2, failure_message = None, ignore_line_endings = True, **kwargs): | ||
"""A test that compares two files. | ||
|
||
The test succeeds if the files' contents match. | ||
|
@@ -163,13 +224,16 @@ def diff_test(name, file1, file2, failure_message = None, **kwargs): | |
name: The name of the test rule. | ||
file1: Label of the file to compare to `file2`. | ||
file2: Label of the file to compare to `file1`. | ||
ignore_line_endings: Ignore differences between CRLF and LF line endings. On windows, this is | ||
forced to False if the 'tr' command can't be found in the bash installation on the host. | ||
failure_message: Additional message to log if the files' contents do not match. | ||
**kwargs: The [common attributes for tests](https://bazel.build/reference/be/common-definitions#common-attributes-tests). | ||
""" | ||
_diff_test( | ||
name = name, | ||
file1 = file1, | ||
file2 = file2, | ||
ignore_line_endings = ignore_line_endings, | ||
failure_message = failure_message, | ||
is_windows = select({ | ||
"@bazel_tools//src/conditions:host_windows": True, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,12 +80,13 @@ eof | |
echo bar > "$ws/$subdir/b.txt" | ||
|
||
(cd "$ws" && \ | ||
bazel test ${flags} "//${subdir%/}:same" --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test ${flags} "//${subdir%/}:same" --test_output=errors --noshow_progress 1>>"$TEST_log" 2>&1 \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you changing tests? |
||
|| fail "expected success") | ||
|
||
(cd "$ws" && \ | ||
bazel test ${flags} "//${subdir%/}:different" --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test ${flags} "//${subdir%/}:different" --test_output=all --noshow_progress 1>>"$TEST_log" 2>&1 \ | ||
&& fail "expected failure" || true) | ||
|
||
expect_log "FAIL: files \"${subdir}a.txt\" and \"${subdir}b.txt\" differ" | ||
} | ||
|
||
|
@@ -175,21 +176,21 @@ diff_test( | |
eof | ||
|
||
(cd "$ws/main" && \ | ||
bazel test ${flags} //:same --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test ${flags} //:same --test_output=errors --noshow_progress 1>"$TEST_log" 2>&1 \ | ||
|| fail "expected success") | ||
|
||
(cd "$ws/main" && \ | ||
bazel test ${flags} //:different1 --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test ${flags} //:different1 --test_output=all --noshow_progress 1>"$TEST_log" 2>&1 \ | ||
&& fail "expected failure" || true) | ||
expect_log 'FAIL: files "external/ext1/foo/foo.txt" and "external/ext2/foo/bar.txt" differ' | ||
|
||
(cd "$ws/main" && \ | ||
bazel test ${flags} //:different2 --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test ${flags} //:different2 --test_output=all --noshow_progress 1>"$TEST_log" 2>&1 \ | ||
&& fail "expected failure" || true) | ||
expect_log 'FAIL: files "external/ext1/foo/foo.txt" and "ext1/foo/foo.txt" differ' | ||
|
||
(cd "$ws/main" && \ | ||
bazel test ${flags} //:different3 --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test ${flags} //:different3 --test_output=all --noshow_progress 1>"$TEST_log" 2>&1 \ | ||
&& fail "expected failure" || true) | ||
expect_log 'FAIL: files "ext2/foo/foo.txt" and "external/ext2/foo/foo.txt" differ' | ||
} | ||
|
@@ -257,15 +258,15 @@ eof | |
echo bar > "$ws/d.txt" | ||
|
||
(cd "$ws" && \ | ||
bazel test //:different_with_message --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test //:different_with_message --test_output=errors --noshow_progress 1>"$TEST_log" 2>&1 \ | ||
&& fail "expected failure" || true) | ||
# TODO(arostovtsev): also test Windows cmd.exe escapes when https://github.com/bazelbuild/bazel-skylib/pull/363 is merged | ||
expect_log "FAIL: files \"a.txt\" and \"b.txt\" differ. This is an \`\$error\`" | ||
|
||
(cd "$ws" && \ | ||
bazel test //:different_without_message --test_output=errors 1>"$TEST_log" 2>&1 \ | ||
bazel test //:different_without_message --test_output=all --noshow_progress 1>"$TEST_log" 2>&1 \ | ||
&& fail "expected failure" || true) | ||
expect_log "FAIL: files \"c.txt\" and \"d.txt\" differ. $" | ||
expect_log "FAIL: files \"c.txt\" and \"d.txt\" differ. why? diff" | ||
} | ||
|
||
cd "$TEST_TMPDIR" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of a func for this, I'd opt for a one-liner on its call site. This way its a bit more readable, because I don't need to jump around file, to see what it does.
e.g.
"1" if ctx.attr.ignore_line_endings else "0"