From 8b691cc882c6c9f94d0706ec56320db86d7077e6 Mon Sep 17 00:00:00 2001 From: Derek Cormier Date: Wed, 17 Jun 2026 17:17:14 -0700 Subject: [PATCH] feat: allow source patches to be placed in user-defined output groups --- README.md | 14 ++++++++++++++ diff/private/diff.bzl | 15 ++++++++++++++- diff/tests/BUILD.bazel | 10 ++++++++++ diff/tests/case_extra_output_group.a | 1 + diff/tests/case_extra_output_group.b | 1 + 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 diff/tests/case_extra_output_group.a create mode 100644 diff/tests/case_extra_output_group.b diff --git a/README.md b/README.md index cb42e61..6e0a04a 100644 --- a/README.md +++ b/README.md @@ -100,3 +100,17 @@ To validate all `diff`, `cmp`, etc. actions by default, set `common --@diff.bzl/ ### Support automatic patch workflows for CI This ruleset outputs patches into a distinct `diff_bzl__patch` output group making it easier for patches to be collected and then applied using automation. See the [build & patch](./examples/build-and-patch.sh) example script. + +Patches can be placed in separately identifiable output groups via the `source_patch_extra_output_groups` attr. For example, you may want all patches in the "autopatch" group to be automatically applied on a CI build failure, while patches from snapshot tests ought to be reviewed by a human first. + +```starlark +diff( + name = "foo", + srcs = [ + "foo.pb.go", + ":foo_generated", + ], + validate = 1, + source_patch_extra_output_groups = ["autopatch"], +) +``` diff --git a/diff/private/diff.bzl b/diff/private/diff.bzl index 58916f4..b247eb6 100644 --- a/diff/private/diff.bzl +++ b/diff/private/diff.bzl @@ -229,18 +229,31 @@ def _diff_rule_impl(ctx): ERROR: diff command exited with non-zero status. {}""".format(patch_msg))) + source_patches_depset = depset(source_patch_outputs) + source_patch_extra_output_groups = {group: source_patches_depset for group in ctx.attr.source_patch_extra_output_groups} + return [ DefaultInfo(files = depset(outputs)), OutputGroupInfo( _validation = depset(validation_outputs), # By reading the Build Events, a Bazel wrapper can identify this diff output group and apply the patch. - diff_bzl__patch = depset(source_patch_outputs), + diff_bzl__patch = source_patches_depset, + **source_patch_extra_output_groups ), ] diff_rule = rule( implementation = _diff_rule_impl, attrs = { + "source_patch_extra_output_groups": attr.string_list( + doc = """\ + Additional output groups to add non-empty source file patches to, in addition to the default + diff_bzl__patch group. Groups can be used to identify sets of patches, for example, patches + that should be automatically applied after a failing CI build might be placed in an "autopatch" + group. + """, + default = [], + ), "args": attr.string_list( doc = """\ Additional arguments to pass to the diff command. diff --git a/diff/tests/BUILD.bazel b/diff/tests/BUILD.bazel index 6fda3b9..7e1e58b 100644 --- a/diff/tests/BUILD.bazel +++ b/diff/tests/BUILD.bazel @@ -265,6 +265,15 @@ diff( validate = 1, ) +diff( + name = "case_source_patch_extra_output_groups", + srcs = [ + "case_extra_output_group.a", + "case_extra_output_group.b", + ], + source_patch_extra_output_groups = ["autopatch"], +) + genrule( name = "case_diff_genrule", srcs = [], @@ -536,6 +545,7 @@ build_test( ":case_to_file_directory_assert_patch", ":case_to_file_directory_newfile", ":case_to_file_directory_newfile_assert_patch", + ":case_source_patch_extra_output_groups", ":case_diff_genrule", ":case_cmp_genrule", ":case_cmp_same_binary", diff --git a/diff/tests/case_extra_output_group.a b/diff/tests/case_extra_output_group.a new file mode 100644 index 0000000..eec8c88 --- /dev/null +++ b/diff/tests/case_extra_output_group.a @@ -0,0 +1 @@ +moo diff --git a/diff/tests/case_extra_output_group.b b/diff/tests/case_extra_output_group.b new file mode 100644 index 0000000..cab3a22 --- /dev/null +++ b/diff/tests/case_extra_output_group.b @@ -0,0 +1 @@ +cow