@@ -549,6 +549,39 @@ def _collect_splicing_config(module, repository):
549549
550550 return config
551551
552+
553+ def _get_annotation_patches (module_ctx , annotations , crate_name , crate_version ):
554+ """Look up patch-related fields from annotations for a specific crate.
555+
556+ Args:
557+ module_ctx: The module context for reading files.
558+ annotations: Dict of crate name to list of annotation JSON strings.
559+ crate_name: The name of the crate to look up.
560+ crate_version: The version of the crate to look up.
561+
562+ Returns:
563+ A tuple of (patches, patch_args, patch_tool, patches_hash).
564+ patches_hash is a hash of patch file contents for cache invalidation.
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+
552585def _generate_hub_and_spokes (
553586 * ,
554587 module_ctx ,
@@ -732,15 +765,21 @@ def _generate_hub_and_spokes(
732765 version = version .replace ("+" , "-" ),
733766 )
734767
768+
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