@@ -133,7 +133,7 @@ class Update:
133133 diff_analysis : DiffAnalysis | None
134134
135135 def __str__ (self ) -> str :
136- return f"Updating { self . distribution } from '{ self .old_version_spec } ' to '{ self .new_version_spec } '"
136+ return f"{ colored ( 'updating' , 'yellow' ) } from '{ self .old_version_spec } ' to '{ self .new_version_spec } '"
137137
138138 @property
139139 def new_version (self ) -> str :
@@ -151,7 +151,7 @@ class Obsolete:
151151 links : dict [str , str ]
152152
153153 def __str__ (self ) -> str :
154- return f"Marking { self . distribution } as obsolete since { self .obsolete_since_version !r} "
154+ return f"{ colored ( 'marking as obsolete' , 'yellow' ) } since { self .obsolete_since_version !r} "
155155
156156
157157@dataclass
@@ -161,7 +161,7 @@ class Remove:
161161 links : dict [str , str ]
162162
163163 def __str__ (self ) -> str :
164- return f"Removing { self . distribution } as { self .reason } "
164+ return f"{ colored ( 'removing' , 'yellow' ) } ( { self .reason } ) "
165165
166166
167167@dataclass
@@ -170,7 +170,16 @@ class NoUpdate:
170170 reason : str
171171
172172 def __str__ (self ) -> str :
173- return f"Skipping { self .distribution } : { self .reason } "
173+ return f"{ colored ('skipping' , 'green' )} ({ self .reason } )"
174+
175+
176+ @dataclass
177+ class Error :
178+ distribution : str
179+ message : str
180+
181+ def __str__ (self ) -> str :
182+ return f"{ colored ('error' , 'red' )} ({ self .message } )"
174183
175184
176185_T = TypeVar ("_T" )
@@ -542,7 +551,16 @@ async def has_no_longer_updated_release(release_to_download: PypiReleaseDownload
542551 return await with_extracted_archive (release_to_download , session = session , handler = parse_no_longer_updated_from_archive )
543552
544553
545- async def determine_action (distribution : str , session : aiohttp .ClientSession ) -> Update | NoUpdate | Obsolete | Remove :
554+ async def determine_action (distribution : str , session : aiohttp .ClientSession ) -> Update | NoUpdate | Obsolete | Remove | Error :
555+ try :
556+ return await determine_action_no_error_handling (distribution , session )
557+ except Exception as exc :
558+ return Error (distribution , str (exc ))
559+
560+
561+ async def determine_action_no_error_handling (
562+ distribution : str , session : aiohttp .ClientSession
563+ ) -> Update | NoUpdate | Obsolete | Remove :
546564 stub_info = read_metadata (distribution )
547565 if stub_info .is_obsolete :
548566 assert type (stub_info .obsolete ) is ObsoleteMetadata
@@ -861,7 +879,7 @@ async def suggest_typeshed_remove(remove: Remove, session: aiohttp.ClientSession
861879 await create_or_update_pull_request (title = title , body = body , branch_name = branch_name , session = session )
862880
863881
864- async def main () -> None :
882+ async def main () -> int :
865883 parser = argparse .ArgumentParser ()
866884 parser .add_argument (
867885 "--action-level" ,
@@ -890,11 +908,11 @@ async def main() -> None:
890908 print ("Unexpected exception!" )
891909 print (diff_result .stdout )
892910 print (diff_result .stderr )
893- sys . exit ( diff_result .returncode )
911+ return diff_result .returncode
894912 if diff_result .stdout :
895913 changed_files = ", " .join (repr (line ) for line in diff_result .stdout .split ("\n " ) if line )
896914 print (f"Cannot run stubsabot, as uncommitted changes are present in { changed_files } !" )
897- sys . exit ( 1 )
915+ return 1
898916
899917 if args .action_level > ActionLevel .fork :
900918 if os .environ .get ("GITHUB_TOKEN" ) is None :
@@ -909,6 +927,8 @@ async def main() -> None:
909927 if args .action_level >= ActionLevel .local :
910928 subprocess .check_call (["git" , "fetch" , "--prune" , "--all" ])
911929
930+ error = False
931+
912932 try :
913933 conn = aiohttp .TCPConnector (limit_per_host = 10 )
914934 async with aiohttp .ClientSession (connector = conn ) as session :
@@ -921,10 +941,14 @@ async def main() -> None:
921941 action_count = 0
922942 for task in asyncio .as_completed (tasks ):
923943 update = await task
944+ print (f"{ update .distribution } ... " , end = "" )
924945 print (update )
925946
926947 if isinstance (update , NoUpdate ):
927948 continue
949+ if isinstance (update , Error ):
950+ error = True
951+ continue
928952
929953 if args .action_count_limit is not None and action_count >= args .action_count_limit :
930954 print (colored ("... but we've reached action count limit" , "red" ))
@@ -952,6 +976,8 @@ async def main() -> None:
952976 if args .action_level >= ActionLevel .local and original_branch :
953977 subprocess .check_call (["git" , "checkout" , original_branch ])
954978
979+ return 1 if error else 0
980+
955981
956982if __name__ == "__main__" :
957- asyncio .run (main ())
983+ sys . exit ( asyncio .run (main () ))
0 commit comments