Skip to content
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: Add diff_test_failure_message attribute to write_source_file* #1030

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions docs/write_source_files.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 50 additions & 12 deletions lib/private/write_source_file.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def write_source_file(
additional_update_targets = [],
suggested_update_target = None,
diff_test = True,
diff_test_failure_message = "{{DEFAULT_MESSAGE}}",
jameskuszmaul-brt marked this conversation as resolved.
Show resolved Hide resolved
file_missing_failure_message = "{{DEFAULT_MESSAGE}}",
check_that_out_file_exists = True,
**kwargs):
"""Write a file or directory to the source tree.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -92,27 +110,32 @@ 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:

bazel run %s

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
Expand All @@ -126,25 +149,27 @@ 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:

bazel run %s

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(
Expand Down Expand Up @@ -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 "")
jameskuszmaul-brt marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions lib/tests/write_source_files/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
)
Expand Down Expand Up @@ -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",
Expand Down
38 changes: 38 additions & 0 deletions lib/write_source_files.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
)
Expand Down
Loading