diff --git a/docs/write_source_files.md b/docs/write_source_files.md
index 74be7ddd7..d7050726a 100644
--- a/docs/write_source_files.md
+++ b/docs/write_source_files.md
@@ -75,6 +75,23 @@ To update *only* this file, run:
bazel run //a/b/c:write_foo
```
+You can also add a more customized error message using the `diff_test_failure_message` argument:
+
+```starlark
+write_source_file(
+ name = "write_foo",
+ out_file = "foo.json",
+ in_file = ":generated-foo",
+ diff_test_failure_message = "Failed to build Foo; please run {{TARGET}} to update."
+)
+```
+
+A test failure from `foo.json` being out of date will then yield:
+
+```
+Failed to build Foo; please run //a/b/c:write_foo to update.
+```
+
If you have many `write_source_files` targets that you want to update as a group, we recommend wrapping
`write_source_files` in a macro that defaults `suggested_update_target` to the umbrella update target.
@@ -105,7 +122,8 @@ Provider for write_source_file targets
write_source_file(name, in_file, out_file, executable, additional_update_targets,
- suggested_update_target, diff_test, check_that_out_file_exists, kwargs)
+ suggested_update_target, diff_test, diff_test_failure_message,
+ file_missing_failure_message, check_that_out_file_exists, **kwargs)
Write a file or directory to the source tree.
@@ -127,6 +145,8 @@ To disable the exists check and up-to-date test set `diff_test` to `False`.
| additional_update_targets | List of other `write_source_files` or `write_source_file` targets to call in the same run. | `[]` |
| suggested_update_target | Label of the `write_source_files` or `write_source_file` target to suggest running when files are out of date. | `None` |
| diff_test | Test that the source tree file or directory exist and is up to date. | `True` |
+| diff_test_failure_message | Text to print when the diff test fails, with templating options for relevant targets.
Substitutions are performed on the failure message, with the following substitutions being available:
`{{DEFAULT_MESSAGE}}`: Prints the default error message, listing the target(s) that may be run to update the file(s).
`{{TARGET}}`: The target to update the individual file that does not match in the diff test.
`{{SUGGESTED_UPDATE_TARGET}}`: The suggested_update_target if specified. | `"{{DEFAULT_MESSAGE}}"` |
+| file_missing_failure_message | Text to print when the output file is missing. Subject to the same substitutions as diff_test_failure_message. | `"{{DEFAULT_MESSAGE}}"` |
| check_that_out_file_exists | Test that the output file exists and print a helpful error message if it doesn't.
If `True`, the output file or directory must be in the same containing Bazel package as the target since the underlying mechanism for this check is limited to files in the same Bazel package. | `True` |
| kwargs | Other common named parameters such as `tags` or `visibility` | none |
@@ -141,7 +161,8 @@ Name of the generated test target if requested, otherwise None.
write_source_files(name, files, executable, additional_update_targets, suggested_update_target,
- diff_test, check_that_out_file_exists, kwargs)
+ diff_test, diff_test_failure_message, file_missing_failure_message,
+ check_that_out_file_exists, **kwargs)
Write one or more files and/or directories to the source tree.
@@ -162,6 +183,8 @@ To disable the exists check and up-to-date tests set `diff_test` to `False`.
| additional_update_targets | List of other `write_source_files` or `write_source_file` targets to call in the same run. | `[]` |
| suggested_update_target | Label of the `write_source_files` or `write_source_file` target to suggest running when files are out of date. | `None` |
| diff_test | Test that the source tree files and/or directories exist and are up to date. | `True` |
+| diff_test_failure_message | Text to print when the diff test fails, with templating options for relevant targets.
Substitutions are performed on the failure message, with the following substitutions being available:
`{{DEFAULT_MESSAGE}}`: Prints the default error message, listing the target(s) that may be run to update the file(s).
`{{TARGET}}`: The target to update the individual file that does not match in the diff test.
`{{SUGGESTED_UPDATE_TARGET}}`: The suggested_update_target if specified, or the target which will update all of the files which do not match. | `"{{DEFAULT_MESSAGE}}"` |
+| file_missing_failure_message | Text to print when the output file is missing. Subject to the same substitutions as diff_test_failure_message. | `"{{DEFAULT_MESSAGE}}"` |
| check_that_out_file_exists | Test that each output file exists and print a helpful error message if it doesn't.
If `True`, destination files and directories must be in the same containing Bazel package as the target since the underlying mechanism for this check is limited to files in the same Bazel package. | `True` |
| kwargs | Other common named parameters such as `tags` or `visibility` | none |
diff --git a/lib/private/write_source_file.bzl b/lib/private/write_source_file.bzl
index ef043e307..bfdd51da9 100644
--- a/lib/private/write_source_file.bzl
+++ b/lib/private/write_source_file.bzl
@@ -20,6 +20,8 @@ def write_source_file(
additional_update_targets = [],
suggested_update_target = None,
diff_test = True,
+ diff_test_failure_message = "{{DEFAULT_MESSAGE}}",
+ file_missing_failure_message = "{{DEFAULT_MESSAGE}}",
check_that_out_file_exists = True,
**kwargs):
"""Write a file or directory to the source tree.
@@ -48,6 +50,22 @@ def write_source_file(
diff_test: Test that the source tree file or directory exist and is up to date.
+ diff_test_failure_message: Text to print when the diff test fails, with templating options for
+ relevant targets.
+
+ Substitutions are performed on the failure message, with the following substitutions being available:
+
+ `{{DEFAULT_MESSAGE}}`: Prints the default error message, listing the target(s) that
+ may be run to update the file(s).
+
+ `{{TARGET}}`: The target to update the individual file that does not match in the
+ diff test.
+
+ `{{SUGGESTED_UPDATE_TARGET}}`: The suggested_update_target if specified.
+
+ file_missing_failure_message: Text to print when the output file is missing. Subject to the same
+ substitutions as diff_test_failure_message.
+
check_that_out_file_exists: Test that the output file exists and print a helpful error message if it doesn't.
If `True`, the output file or directory must be in the same containing Bazel package as the target since the underlying mechanism
@@ -92,17 +110,20 @@ def write_source_file(
out_file_missing = check_that_out_file_exists and _is_file_missing(out_file)
test_target_name = "%s_test" % name
+ update_target_string = "//%s:%s" % (native.package_name(), name)
+ suggested_update_target_string = str(utils.to_label(suggested_update_target)) if suggested_update_target else None
+
if out_file_missing:
if suggested_update_target == None:
- message = """
+ default_message = """
%s does not exist. To create & update this file, run:
- bazel run //%s:%s
+ bazel run %s
-""" % (out_file, native.package_name(), name)
+""" % (out_file, update_target_string)
else:
- message = """
+ default_message = """
%s does not exist. To create & update this and other generated files, run:
@@ -110,9 +131,11 @@ def write_source_file(
To create an update *only* this file, run:
- bazel run //%s:%s
+ bazel run %s
+
+""" % (out_file, suggested_update_target_string, update_target_string)
-""" % (out_file, utils.to_label(suggested_update_target), native.package_name(), name)
+ message = _do_diff_test_message_replacements(file_missing_failure_message, default_message, update_target_string, suggested_update_target_string)
# Stamp out a test that fails with a helpful message when the source file doesn't exist.
# Note that we cannot simply call fail() here since it will fail during the analysis
@@ -126,15 +149,15 @@ To create an update *only* this file, run:
)
else:
if suggested_update_target == None:
- message = """
+ default_message = """
%s is out of date. To update this file, run:
- bazel run //%s:%s
+ bazel run %s
-""" % (out_file, native.package_name(), name)
+""" % (out_file, update_target_string)
else:
- message = """
+ default_message = """
%s is out of date. To update this and other generated files, run:
@@ -142,9 +165,11 @@ To create an update *only* this file, run:
To update *only* this file, run:
- bazel run //%s:%s
+ bazel run %s
+
+""" % (out_file, suggested_update_target_string, update_target_string)
-""" % (out_file, utils.to_label(suggested_update_target), native.package_name(), name)
+ message = _do_diff_test_message_replacements(diff_test_failure_message, default_message, update_target_string, suggested_update_target_string)
# Stamp out a diff test the check that the source file is up to date
_diff_test(
@@ -394,3 +419,16 @@ def _is_file_missing(label):
subpackage_glob = native.subpackages(include = [file_rel], allow_empty = True)
return len(file_glob) == 0 and len(subpackage_glob) == 0
+
+def _do_diff_test_message_replacements(message, default_message, target, suggested_update_target):
+ """Constructs the diff test failures message from the provided template.
+
+ Replaces the {{DEFAULT_MESSAGE}}, {{TARGET}}, and {{SUGGESTED_UPDATE_TARGET}} strings in
+ message with the corresponding arguments.
+
+ Args:
+ message: The user-provided message to do template replacement on.
+ default_message: The message to fill in for the {{DEFAULT_MESSAGE}} parameter.
+ target: The string to fill in for the {{TARGET}} parameter.
+ suggested_update_target: The string to fill in for the {{SUGGESTED_UPDATE_TARGET}} parameter."""
+ return message.replace("{{DEFAULT_MESSAGE}}", default_message).replace("{{TARGET}}", target).replace("{{SUGGESTED_UPDATE_TARGET}}", suggested_update_target if suggested_update_target else "")
diff --git a/lib/tests/write_source_files/BUILD.bazel b/lib/tests/write_source_files/BUILD.bazel
index 56a5486da..949d34d48 100644
--- a/lib/tests/write_source_files/BUILD.bazel
+++ b/lib/tests/write_source_files/BUILD.bazel
@@ -128,6 +128,8 @@ write_source_file_test(
write_source_file(
name = "e_dir_test",
+ diff_test_failure_message = "\nSample failure message for {{TARGET}}. Default message:\n{{DEFAULT_MESSAGE}}",
+ file_missing_failure_message = "\nSample failure message for a missing {{TARGET}}. Default message:\n{{DEFAULT_MESSAGE}}",
in_file = ":e_dir-desired",
out_file = "e_dir",
)
@@ -161,6 +163,7 @@ write_source_files(
additional_update_targets = [
"//lib/tests/write_source_files/subdir:macro_smoke_test",
],
+ diff_test_failure_message = "\nSample failure message for {{TARGET}} of {{SUGGESTED_UPDATE_TARGET}}. Default message:\n{{DEFAULT_MESSAGE}}",
files = {
"a2.js": ":a-desired",
"b2.js": ":b-desired",
diff --git a/lib/write_source_files.bzl b/lib/write_source_files.bzl
index faa189b28..936a7b90a 100644
--- a/lib/write_source_files.bzl
+++ b/lib/write_source_files.bzl
@@ -73,6 +73,23 @@ To update *only* this file, run:
bazel run //a/b/c:write_foo
```
+You can also add a more customized error message using the `diff_test_failure_message` argument:
+
+```starlark
+write_source_file(
+ name = "write_foo",
+ out_file = "foo.json",
+ in_file = ":generated-foo",
+ diff_test_failure_message = "Failed to build Foo; please run {{TARGET}} to update."
+)
+```
+
+A test failure from `foo.json` being out of date will then yield:
+
+```
+Failed to build Foo; please run //a/b/c:write_foo to update.
+```
+
If you have many `write_source_files` targets that you want to update as a group, we recommend wrapping
`write_source_files` in a macro that defaults `suggested_update_target` to the umbrella update target.
@@ -96,6 +113,8 @@ def write_source_files(
additional_update_targets = [],
suggested_update_target = None,
diff_test = True,
+ diff_test_failure_message = "{{DEFAULT_MESSAGE}}",
+ file_missing_failure_message = "{{DEFAULT_MESSAGE}}",
check_that_out_file_exists = True,
**kwargs):
"""Write one or more files and/or directories to the source tree.
@@ -125,6 +144,23 @@ def write_source_files(
diff_test: Test that the source tree files and/or directories exist and are up to date.
+ diff_test_failure_message: Text to print when the diff test fails, with templating options for
+ relevant targets.
+
+ Substitutions are performed on the failure message, with the following substitutions being available:
+
+ `{{DEFAULT_MESSAGE}}`: Prints the default error message, listing the target(s) that
+ may be run to update the file(s).
+
+ `{{TARGET}}`: The target to update the individual file that does not match in the
+ diff test.
+
+ `{{SUGGESTED_UPDATE_TARGET}}`: The suggested_update_target if specified, or the
+ target which will update all of the files which do not match.
+
+ file_missing_failure_message: Text to print when the output file is missing. Subject to the same
+ substitutions as diff_test_failure_message.
+
check_that_out_file_exists: Test that each output file exists and print a helpful error message if it doesn't.
If `True`, destination files and directories must be in the same containing Bazel package as the target since the underlying
@@ -157,6 +193,8 @@ def write_source_files(
additional_update_targets = additional_update_targets if single_update_target else [],
suggested_update_target = this_suggested_update_target,
diff_test = diff_test,
+ diff_test_failure_message = diff_test_failure_message,
+ file_missing_failure_message = file_missing_failure_message,
check_that_out_file_exists = check_that_out_file_exists,
**kwargs
)