Skip to content

Commit eb96b7d

Browse files
authored
stubsabot: Handle errors when determining action (#14473)
Use colors for output and move processed distribution name to the front
1 parent d5c3781 commit eb96b7d

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

scripts/stubsabot.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

956982
if __name__ == "__main__":
957-
asyncio.run(main())
983+
sys.exit(asyncio.run(main()))

0 commit comments

Comments
 (0)