Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 5 additions & 4 deletions MODULE.bazel.lock

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

20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ This also works for directories.

To validate all `diff`, `cmp`, etc. actions by default, set `common --@diff.bzl//diff:validate=true` in your bazelrc.

### Support automatic patch workflows for CI
### Support automatic patch workflows

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.
This ruleset outputs patches for source tree files into the `diff_bzl__patch` output group by default, making it easier to collect and apply patches in an automated fashion. See the [build & patch](./examples/build-and-patch.sh) example script.

The output groups for source patches can be customized via the `source_patch_output_groups` attribute. This can be used to categorize types of patches. For example, `diff` targets with `source_patch_output_groups = ["autopatch"]` might identify patches that should automatically be applied if the build fails on CI, whereas a `"snapshot_test"` group could identify patches that require human review, etc.

```starlark
diff(
name = "foo",
srcs = [
"foo.pb.go",
":foo_generated",
],
validate = 1,
source_patch_output_groups = ["autopatch"],
)
```

NB: Only patches for files in the source tree are placed in the above output group(s). Patches for files in the output tree are not included as they should not be modified outside of Bazel.
6 changes: 4 additions & 2 deletions diff/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def cmp(name, srcs, args = [], out = None, **kwargs):
**kwargs
)

def diff(name, srcs, args = ["--unified"], patch = None, **kwargs):
def diff(name, srcs, args = ["--unified"], patch = None, source_patch_output_groups = ["diff_bzl__patch"], **kwargs):
"""Runs a diff between files and return a patch.

Examples:
Expand Down Expand Up @@ -98,9 +98,10 @@ def diff(name, srcs, args = ["--unified"], patch = None, **kwargs):

Args:
name: The name of the rule
srcs: The files to compare.
srcs: The files to compare
args: Additional arguments to pass to diff
patch: The output file to write the diff to. Defaults to ${name}.patch.
source_patch_output_groups: Additional output groups to add source file patches to
**kwargs: Additional arguments to pass to the underlying rule
"""
for i in range(len(srcs)):
Expand All @@ -114,6 +115,7 @@ def diff(name, srcs, args = ["--unified"], patch = None, **kwargs):
args = args,
srcs = srcs,
patch = patch or name + ".patch",
source_patch_output_groups = source_patch_output_groups,
**kwargs
)

Expand Down
14 changes: 12 additions & 2 deletions diff/private/diff.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,28 @@ 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_output_groups = {group: source_patches_depset for group in ctx.attr.source_patch_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),
**source_patch_output_groups
),
]

diff_rule = rule(
implementation = _diff_rule_impl,
attrs = {
"source_patch_output_groups": attr.string_list(
doc = """\
Additional output groups to add source file patches to. Output groups can be used to categorize sets of patches
that a Bazel wrapper can identify and apply by reading build events.
""",
default = ["diff_bzl__patch"],
),
"args": attr.string_list(
doc = """\
Additional arguments to pass to the diff command.
Expand Down
53 changes: 53 additions & 0 deletions diff/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,53 @@ diff(
validate = 1,
)

diff(
name = "case_source_patch_default_output_group",
srcs = [
"case_source_patch_default_output_group.a",
"case_source_patch_default_output_group.b",
],
)

filegroup(
name = "case_source_patch_default_output_group_output",
srcs = [":case_source_patch_default_output_group"],
output_group = "diff_bzl__patch",
)

diff(
name = "case_source_patch_default_output_group_assert_patch",
srcs = [
"case_source_patch_default_output_group.golden.patch",
":case_source_patch_default_output_group_output",
],
validate = 1,
)

diff(
name = "case_source_patch_custom_output_group",
srcs = [
"case_source_patch_custom_output_group.a",
"case_source_patch_custom_output_group.b",
],
source_patch_output_groups = ["autopatch"],
)

filegroup(
name = "case_source_patch_custom_output_group_output",
srcs = [":case_source_patch_custom_output_group"],
output_group = "autopatch",
)

diff(
name = "case_source_patch_custom_output_group_assert_patch",
srcs = [
"case_source_patch_custom_output_group.golden.patch",
":case_source_patch_custom_output_group_output",
],
validate = 1,
)

genrule(
name = "case_diff_genrule",
srcs = [],
Expand Down Expand Up @@ -536,6 +583,12 @@ build_test(
":case_to_file_directory_assert_patch",
":case_to_file_directory_newfile",
":case_to_file_directory_newfile_assert_patch",
":case_source_patch_default_output_group",
":case_source_patch_default_output_group_output",
":case_source_patch_default_output_group_assert_patch",
":case_source_patch_custom_output_group",
":case_source_patch_custom_output_group_output",
":case_source_patch_custom_output_group_assert_patch",
":case_diff_genrule",
":case_cmp_genrule",
":case_cmp_same_binary",
Expand Down
1 change: 1 addition & 0 deletions diff/tests/case_source_patch_custom_output_group.a
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
moo
1 change: 1 addition & 0 deletions diff/tests/case_source_patch_custom_output_group.b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cow
5 changes: 5 additions & 0 deletions diff/tests/case_source_patch_custom_output_group.golden.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
--- diff/tests/case_source_patch_custom_output_group.a 1970-01-01 00:00:00.000000000 +0000
+++ diff/tests/case_source_patch_custom_output_group.b 1970-01-01 00:00:00.000000000 +0000
@@ -1 +1 @@
-moo
+cow
1 change: 1 addition & 0 deletions diff/tests/case_source_patch_default_output_group.a
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo
1 change: 1 addition & 0 deletions diff/tests/case_source_patch_default_output_group.b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
--- diff/tests/case_source_patch_default_output_group.a 1970-01-01 00:00:00.000000000 +0000
+++ diff/tests/case_source_patch_default_output_group.b 1970-01-01 00:00:00.000000000 +0000
@@ -1 +1 @@
-foo
+bar
5 changes: 3 additions & 2 deletions docs/rules.md

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

Loading