2323from macaron .config .global_config import global_config
2424from macaron .environment_variables import get_patched_env
2525from macaron .errors import CloneError , GitTagError
26+ from macaron .util import BytesDecoder
2627
2728logger : logging .Logger = logging .getLogger (__name__ )
2829
@@ -412,7 +413,7 @@ def list_remote_references(arguments: list[str], repo: str) -> str | None:
412413 logger .error ("Failed to retrieve remote references from repo: %s" , repo )
413414 return None
414415
415- return result .stdout . decode ( "utf-8" )
416+ return decode_git_tags ( result .stdout )
416417
417418
418419def resolve_local_path (start_dir : str , local_path : str ) -> str :
@@ -944,7 +945,7 @@ def is_commit_hash(value: str) -> bool:
944945 return bool (re .match (pattern , value ))
945946
946947
947- def get_tags_via_git_remote (repo : str ) -> dict [str , str ] | None :
948+ def get_tags_via_git_remote (repo : str ) -> dict [str , str ]:
948949 """Retrieve all tags from a given repository using ls-remote.
949950
950951 Parameters
@@ -955,35 +956,14 @@ def get_tags_via_git_remote(repo: str) -> dict[str, str] | None:
955956 Returns
956957 -------
957958 dict[str]
958- A dictionary of tags mapped to their commits, or None if the operation failed. .
959+ A dictionary of tags mapped to their commits.
959960 """
960961 tag_data = list_remote_references (["--tags" ], repo )
961962 if not tag_data :
962- return None
963- tags = {}
964-
965- for tag_line in tag_data .splitlines ():
966- tag_line = tag_line .strip ()
967- if not tag_line :
968- continue
969- split = tag_line .split ("\t " )
970- if len (split ) != 2 :
971- continue
972- possible_tag = split [1 ]
973- if possible_tag .endswith ("^{}" ):
974- possible_tag = possible_tag [:- 3 ]
975- elif possible_tag in tags :
976- # If a tag already exists, it must be the annotated reference of an annotated tag.
977- # In that case we skip the tag as it does not point to the proper source commit.
978- # Note that this should only happen if the tags are received out of standard order.
979- continue
980- possible_tag = possible_tag .replace ("refs/tags/" , "" )
981- if not possible_tag :
982- continue
983- tags [possible_tag ] = split [0 ]
963+ return {}
984964
965+ tags = parse_git_tags (tag_data )
985966 logger .debug ("Found %s tags via ls-remote of %s" , len (tags ), repo )
986-
987967 return tags
988968
989969
@@ -1055,3 +1035,61 @@ def find_highest_git_tag(tags: set[str]) -> str:
10551035 raise GitTagError ("No valid version tag found." )
10561036
10571037 return highest_tag
1038+
1039+
1040+ def parse_git_tags (tag_data : str ) -> dict [str , str ]:
1041+ """Parse the tags and commits found within the passed data.
1042+
1043+ Parameters
1044+ ----------
1045+ tag_data: str
1046+ The tag data to parse.
1047+
1048+ Returns
1049+ -------
1050+ dict[str, str]
1051+ A dictionary of tags mapped to commits.
1052+ """
1053+ tags = {}
1054+ for tag_line in tag_data .splitlines ():
1055+ tag_line = tag_line .strip ()
1056+ if not tag_line :
1057+ continue
1058+ split = re .split ("[\t ]" , tag_line , maxsplit = 1 )
1059+ if len (split ) != 2 :
1060+ continue
1061+ possible_tag = split [1 ]
1062+ if possible_tag .endswith ("^{}" ):
1063+ possible_tag = possible_tag [:- 3 ]
1064+ elif possible_tag in tags :
1065+ # If a tag already exists, it must be the annotated reference of an annotated tag.
1066+ # In that case we skip the tag as it does not point to the proper source commit.
1067+ # Note that this should only happen if the tags are received out of standard order.
1068+ continue
1069+ possible_tag = possible_tag .replace ("refs/tags/" , "" )
1070+ if not possible_tag :
1071+ continue
1072+ tags [possible_tag ] = split [0 ]
1073+
1074+ return tags
1075+
1076+
1077+ def decode_git_tags (data : bytes ) -> str | None :
1078+ """Decode the passed Git tag data.
1079+
1080+ Parameters
1081+ ----------
1082+ data: bytes
1083+ The data to decode.
1084+
1085+ Returns
1086+ -------
1087+ str | None
1088+ The decoded data, or None if an error occurred.
1089+ """
1090+ try :
1091+ return data .decode ("utf-8" )
1092+ except UnicodeDecodeError as error :
1093+ logger .debug ("Error decoding stdout as utf-8: %s" , error )
1094+ # Try other character encodings.
1095+ return BytesDecoder .decode (data )
0 commit comments