195 lines
6.2 KiB
Python
195 lines
6.2 KiB
Python
"""Tests for write_source_files"""
|
|
# Inspired by https://github.com/cgrindel/bazel-starlib/blob/main/updatesrc/private/updatesrc_update_test.bzl
|
|
|
|
load("//lib/private:directory_path.bzl", "DirectoryPathInfo")
|
|
load("//lib/private:write_source_file.bzl", _write_source_file = "write_source_file")
|
|
|
|
def _write_source_file_test_impl_sh(ctx, in_file_path, out_file_path):
|
|
test = ctx.actions.declare_file(
|
|
ctx.label.name + "_test.sh",
|
|
)
|
|
|
|
contents = []
|
|
|
|
contents.append("""
|
|
#!/usr/bin/env bash
|
|
set -o errexit -o nounset -o pipefail
|
|
|
|
assert_different() {
|
|
local in_file="${1}"
|
|
local out_file="${2}"
|
|
diff "${in_file}" "${out_file}" > /dev/null && (echo >&2 "Expected files to differ. in: ${in_file}, out: ${out_file}" && return -1)
|
|
return 0
|
|
}
|
|
|
|
assert_same() {
|
|
local in_file="${1}"
|
|
local out_file="${2}"
|
|
diff "${in_file}" "${out_file}" || (echo >&2 "Expected files to be same. in: ${in_file}, out: ${out_file}" && return -1)
|
|
}""")
|
|
|
|
contents.append("""
|
|
# Check that in and out files are different
|
|
assert_different {in_file} {out_file}
|
|
""".format(
|
|
in_file = in_file_path,
|
|
out_file = out_file_path,
|
|
))
|
|
|
|
contents.append("""# Write to the source files
|
|
{write_source_files}
|
|
""".format(write_source_files = ctx.file.write_source_file_target.short_path))
|
|
|
|
contents.append("""# Check that in and out files are the same
|
|
assert_same {in_file} {out_file}""".format(
|
|
in_file = in_file_path,
|
|
out_file = out_file_path,
|
|
))
|
|
|
|
ctx.actions.write(
|
|
output = test,
|
|
is_executable = True,
|
|
content = "\n".join(contents),
|
|
)
|
|
|
|
return test
|
|
|
|
def _write_source_file_test_impl_bat(ctx, in_file_path, out_file_path):
|
|
test = ctx.actions.declare_file(
|
|
ctx.label.name + "_test.bat",
|
|
)
|
|
|
|
# BUG: Windows is having trouble executing the symlink to the write_source_files executable,
|
|
# but it is able to execute the actual output script so point to that for now.
|
|
#
|
|
# What we would use if this bug didn't exist:
|
|
# write_source_files = ctx.executable.write_source_file_target.short_path.replace("/", "\\")
|
|
#
|
|
# Instead back out of the runfiles execution directory:
|
|
# write_to_source_files_test_test.bat.runfiles/aspect_bazel_lib
|
|
# And point to the output script.
|
|
write_source_files = "..\\..\\%s" % ctx.executable.write_source_file_target.basename
|
|
|
|
contents = []
|
|
|
|
contents.append("""
|
|
@rem @generated by @aspect_bazel_lib//:lib/tests/write_source_files:write_source_file_test.bzl
|
|
@echo off
|
|
@rem Check that in and out files are different
|
|
call :assert_different {in_file}, {out_file}
|
|
if %errorlevel% neq 0 exit /b 1
|
|
""".format(
|
|
in_file = in_file_path.replace("/", "\\"),
|
|
out_file = out_file_path.replace("/", "\\"),
|
|
))
|
|
|
|
contents.append("""
|
|
@rem Write to the source files
|
|
call {write_source_files}
|
|
if %errorlevel% neq 0 exit /b 1
|
|
""".format(write_source_files = write_source_files))
|
|
|
|
contents.append("""
|
|
@rem Check that in and out files are the same
|
|
call :assert_same {in_file}, {out_file}
|
|
if %errorlevel% neq 0 exit /b 1
|
|
""".format(
|
|
in_file = in_file_path.replace("/", "\\"),
|
|
out_file = out_file_path.replace("/", "\\"),
|
|
))
|
|
|
|
contents.append("""
|
|
exit /b 0
|
|
|
|
:assert_different
|
|
fc /b %~1 %~2 > nul
|
|
if %errorlevel% equ 1 exit /b 0
|
|
echo Error: %~1 and %~2 are not different
|
|
exit /b 1
|
|
|
|
:assert_same
|
|
fc /b %~1 %~2 > nul
|
|
if %errorlevel% equ 0 exit /b 0
|
|
echo Error: %~1 and %~2 are not the same
|
|
exit /b 1
|
|
""")
|
|
|
|
ctx.actions.write(
|
|
output = test,
|
|
is_executable = True,
|
|
content = "\n".join(contents).replace("\n", "\r\n"),
|
|
)
|
|
|
|
return test
|
|
|
|
def _write_source_file_test_impl(ctx):
|
|
is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo])
|
|
|
|
if DirectoryPathInfo in ctx.attr.in_file:
|
|
in_file = ctx.attr.in_file[DirectoryPathInfo].directory
|
|
in_file_path = "/".join([in_file.short_path, ctx.attr.in_file[DirectoryPathInfo].path])
|
|
else:
|
|
if len(ctx.files.in_file) != 1:
|
|
fail("in_file must be a single file or a target that provides a DirectoryPathInfo")
|
|
in_file = ctx.files.in_file[0]
|
|
in_file_path = in_file.short_path
|
|
|
|
if is_windows:
|
|
test = _write_source_file_test_impl_bat(ctx, in_file_path, ctx.file.out_file.short_path)
|
|
else:
|
|
test = _write_source_file_test_impl_sh(ctx, in_file_path, ctx.file.out_file.short_path)
|
|
|
|
return DefaultInfo(
|
|
executable = test,
|
|
runfiles = ctx.runfiles(
|
|
files = [ctx.executable.write_source_file_target, in_file, ctx.file.out_file],
|
|
),
|
|
)
|
|
|
|
_write_source_file_test = rule(
|
|
implementation = _write_source_file_test_impl,
|
|
attrs = {
|
|
"write_source_file_target": attr.label(
|
|
allow_single_file = True,
|
|
executable = True,
|
|
# Intentionally use the target platform since the target is always meant to be `bazel
|
|
# run` on the host machine but we don't want to transition it to the host platform and
|
|
# have the generated file rebuilt in a separate output tree. Target platform should
|
|
# always be equal to the host platform when using `write_source_files`.
|
|
cfg = "target",
|
|
mandatory = True,
|
|
),
|
|
"out_file": attr.label(
|
|
allow_single_file = True,
|
|
mandatory = True,
|
|
),
|
|
"in_file": attr.label(
|
|
allow_files = True,
|
|
mandatory = True,
|
|
),
|
|
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
|
|
},
|
|
test = True,
|
|
)
|
|
|
|
def write_source_file_test(name, in_file, out_file, check_that_out_file_exists = True, size = "small"):
|
|
"""Stamp a write_source_files executable and a test to run against it"""
|
|
|
|
_write_source_file(
|
|
name = name + "_updater",
|
|
in_file = in_file,
|
|
out_file = out_file,
|
|
diff_test = False,
|
|
check_that_out_file_exists = check_that_out_file_exists,
|
|
)
|
|
|
|
# Note that for testing we update the source files in the sandbox,
|
|
# not the actual source tree.
|
|
_write_source_file_test(
|
|
name = name,
|
|
write_source_file_target = name + "_updater",
|
|
in_file = in_file,
|
|
out_file = out_file,
|
|
size = size,
|
|
)
|