Skip to content

Commit af84345

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

1 file changed

Lines changed: 45 additions & 6 deletions

File tree

crate_universe/extensions.bzl

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,40 @@ 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+
570+
# Check if version matches ("*" matches all, or exact match, or semver prefix)
571+
if version == "*" or version == crate_version or crate_version.startswith(version):
572+
patches = data.get("patches", None)
573+
patch_args = data.get("patch_args", None)
574+
patch_tool = data.get("patch_tool", None)
575+
if patches or patch_args or patch_tool:
576+
# Compute hash of patch file contents for cache invalidation
577+
patches_hash = None
578+
if patches:
579+
patch_content = ""
580+
for patch in patches:
581+
patch_content += module_ctx.read(module_ctx.path(Label(patch)))
582+
patches_hash = str(hash(patch_content))
583+
return (patches, patch_args, patch_tool, patches_hash)
584+
return (None, None, None, None)
585+
552586
def _generate_hub_and_spokes(
553587
*,
554588
module_ctx,
@@ -732,15 +766,20 @@ def _generate_hub_and_spokes(
732766
version = version.replace("+", "-"),
733767
)
734768

769+
# Look up patches from annotations
770+
ann_patches, ann_patch_args, ann_patch_tool, ann_patches_hash = _get_annotation_patches(module_ctx, annotations, name, version)
771+
735772
if "Http" in repo:
736773
# Replicates functionality in repo_http.j2.
737774
build_file_content = module_ctx.read(crates_dir.get_child("BUILD.%s-%s.bazel" % (name, version)))
738775
repo = repo["Http"]
739776
http_archive(
740777
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),
778+
# canonical_id forces re-download when patch content changes
779+
canonical_id = ann_patches_hash,
780+
patch_args = ann_patch_args if ann_patch_args else repo.get("patch_args", None),
781+
patch_tool = ann_patch_tool if ann_patch_tool else repo.get("patch_tool", None),
782+
patches = ann_patches if ann_patches else repo.get("patches", None),
744783
remote_patch_strip = 1,
745784
sha256 = repo.get("sha256", None),
746785
type = "tar.gz",
@@ -761,9 +800,9 @@ def _generate_hub_and_spokes(
761800
git_repository(
762801
name = crate_repo_name,
763802
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),
803+
patch_args = ann_patch_args if ann_patch_args else repo.get("patch_args", None),
804+
patch_tool = ann_patch_tool if ann_patch_tool else repo.get("patch_tool", None),
805+
patches = ann_patches if ann_patches else repo.get("patches", None),
767806
shallow_since = repo.get("shallow_since", None),
768807
remote = repo["remote"],
769808
build_file_content = build_file_content,

0 commit comments

Comments
 (0)