Skip to content

Commit 8c1c199

Browse files
committed
Add patches and canonical_id from annotations to http_archive
1 parent 32bb21d commit 8c1c199

1 file changed

Lines changed: 44 additions & 6 deletions

File tree

crate_universe/extensions.bzl

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,39 @@ def _collect_splicing_config(module, repository):
549549

550550
return config
551551

552+
def _get_annotation_patches(module_ctx, annotations, crate_name, crate_version):
553+
"""Look up patch-related fields from annotations for a specific crate.
554+
555+
Args:
556+
module_ctx: The module context for reading files.
557+
annotations: Dict of crate name to list of annotation JSON strings.
558+
crate_name: The name of the crate to look up.
559+
crate_version: The version of the crate to look up.
560+
561+
Returns:
562+
A tuple of (patches, patch_args, patch_tool, patches_hash).
563+
patches_hash is a hash of patch file contents for cache invalidation.
564+
"""
565+
566+
crate_annotations = annotations.get(crate_name, [])
567+
for annotation_json in crate_annotations:
568+
version, data = json.decode(annotation_json)
569+
# Check if version matches ("*" matches all, or exact match, or semver prefix)
570+
if version == "*" or version == crate_version or crate_version.startswith(version):
571+
patches = data.get("patches", None)
572+
patch_args = data.get("patch_args", None)
573+
patch_tool = data.get("patch_tool", None)
574+
if patches or patch_args or patch_tool:
575+
# Compute hash of patch file contents for cache invalidation
576+
patches_hash = None
577+
if patches:
578+
patch_content = ""
579+
for patch in patches:
580+
patch_content += module_ctx.read(module_ctx.path(Label(patch)))
581+
patches_hash = str(hash(patch_content))
582+
return (patches, patch_args, patch_tool, patches_hash)
583+
return (None, None, None, None)
584+
552585
def _generate_hub_and_spokes(
553586
*,
554587
module_ctx,
@@ -732,15 +765,20 @@ def _generate_hub_and_spokes(
732765
version = version.replace("+", "-"),
733766
)
734767

768+
# Look up patches from annotations
769+
ann_patches, ann_patch_args, ann_patch_tool, ann_patches_hash = _get_annotation_patches(module_ctx, annotations, name, version)
770+
735771
if "Http" in repo:
736772
# Replicates functionality in repo_http.j2.
737773
build_file_content = module_ctx.read(crates_dir.get_child("BUILD.%s-%s.bazel" % (name, version)))
738774
repo = repo["Http"]
739775
http_archive(
740776
name = crate_repo_name,
741-
patch_args = repo.get("patch_args", None),
742-
patch_tool = repo.get("patch_tool", None),
743-
patches = repo.get("patches", None),
777+
# canonical_id forces re-download when patch content changes
778+
canonical_id = ann_patches_hash,
779+
patch_args = ann_patch_args if ann_patch_args else repo.get("patch_args", None),
780+
patch_tool = ann_patch_tool if ann_patch_tool else repo.get("patch_tool", None),
781+
patches = ann_patches if ann_patches else repo.get("patches", None),
744782
remote_patch_strip = 1,
745783
sha256 = repo.get("sha256", None),
746784
type = "tar.gz",
@@ -761,9 +799,9 @@ def _generate_hub_and_spokes(
761799
git_repository(
762800
name = crate_repo_name,
763801
init_submodules = True,
764-
patch_args = repo.get("patch_args", None),
765-
patch_tool = repo.get("patch_tool", None),
766-
patches = repo.get("patches", None),
802+
patch_args = ann_patch_args if ann_patch_args else repo.get("patch_args", None),
803+
patch_tool = ann_patch_tool if ann_patch_tool else repo.get("patch_tool", None),
804+
patches = ann_patches if ann_patches else repo.get("patches", None),
767805
shallow_since = repo.get("shallow_since", None),
768806
remote = repo["remote"],
769807
build_file_content = build_file_content,

0 commit comments

Comments
 (0)