Patches in source.json are not sorted by name prior to applying
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 72
Description
### Description of the bug:
Looking at Bazel's code, it looks like it applies patches listed in source.json in the literal order in which they are provided. This is somewhat annoying, because JSON parsers for many languages out there don't spend any effort retaining the order of objects in dictionaries. Go is a good example of that. This means that any non-Bazel tool that tries to operate against BCR needs to resort to using a JSON parser that does provide such guarantees, assuming they exist.
In order to make interoperability easier, Bazel should apply some normalization to this dictionary (e.g., sorting patches by key first).
### Which category does this issue belong to?
_No response_
### What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Take this module: https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json
```json
{
"integrity": "sha256-FKIlhwq06RhpZSz9ae8gKCd/wdxJENZdNTti1uCuIfQ=",
"strip_prefix": "rules_proto-7.1.0",
"url": "https://github.com/bazelbuild/rules_proto/releases/download/7.1.0/rules_proto-7.1.0.tar.gz",
"patches": {
"module_dot_bazel_version.patch": "sha256-GFtfNnjXlShEmp3o0HiTq8AWf0YpNxLkmGVMt98QcfI=",
"MODULE.bazel.patch": "sha256-QC5hjx/QZTZ3deil1x9qT0Ni6G1+ZiFaQ+xGHtXR0HE="
},
"patch_strip": 1
}
```
Now let's look at these two patches:
```
$ curl https://bcr.bazel.build/modules/rules_proto/7.1.0/patches/module_dot_bazel_version.patch
===================================================================
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -2,9 +2,9 @@
module(
name = "rules_proto",
# Note: the publish-to-BCR app will patch this line to stamp the version being published.
- version = "0.0.0",
+ version = "7.1.0",
compatibility_level = 1,
)
bazel_dep(name = "protobuf", version = "27.1", repo_name = "com_google_protobuf")
$ curl https://bcr.bazel.build/modules/rules_proto/7.1.0/patches/MODULE.bazel.patch
diff --git a/MODULE.bazel b/MODULE.bazel
index 2a69659..1281fd1 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -7,7 +7,7 @@ module(
compatibility_level = 1,
)
-bazel_dep(name = "protobuf", version = "27.1", repo_name = "com_google_protobuf")
+bazel_dep(name = "protobuf", version = "29.1", repo_name = "com_google_protobuf")
bazel_dep(name = "bazel_skylib", version = "1.3.0")
bazel_dep(name = "rules_cc", version = "0.0.15")
bazel_dep(name = "rules_license", version = "0.0.7")
...
```
Applying these two changes in the order they are listed should work. But doing it the other way around should not, for the reason that the context of patch 1 contains:
```
bazel_dep(name = "protobuf", version = "27.1", repo_name = "com_google_protobuf")
```
Which got replaced by the second patch.
### Which operating system are you running Bazel on?
macOS
### What is the output of `bazel info release`?
_No response_
### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.
_No response_
### What's the output of `git remote get-url origin; git rev-parse HEAD` ?
```text
```
### If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.
_No response_
### Have you found anything relevant by searching the web?
_No response_
### Any other information, logs, or outputs that you want to share?
_No response_
Contributor guide
Research direction
Start by locating Bazel's source.json patch-application code and the existing tests for module source archives. Add a regression case based on the rules_proto 7.1.0 example, then verify that patches are applied in sorted key order and that the test passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100