mirror of
https://github.com/davidhalter/typeshed.git
synced 2026-05-04 20:45:49 +08:00
stubsabot: Handle errors when determining action (#14473)
Use colors for output and move processed distribution name to the front
This commit is contained in:
+35
-9
@@ -133,7 +133,7 @@ class Update:
|
||||
diff_analysis: DiffAnalysis | None
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Updating {self.distribution} from '{self.old_version_spec}' to '{self.new_version_spec}'"
|
||||
return f"{colored('updating', 'yellow')} from '{self.old_version_spec}' to '{self.new_version_spec}'"
|
||||
|
||||
@property
|
||||
def new_version(self) -> str:
|
||||
@@ -151,7 +151,7 @@ class Obsolete:
|
||||
links: dict[str, str]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Marking {self.distribution} as obsolete since {self.obsolete_since_version!r}"
|
||||
return f"{colored('marking as obsolete', 'yellow')} since {self.obsolete_since_version!r}"
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -161,7 +161,7 @@ class Remove:
|
||||
links: dict[str, str]
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Removing {self.distribution} as {self.reason}"
|
||||
return f"{colored('removing', 'yellow')} ({self.reason})"
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -170,7 +170,16 @@ class NoUpdate:
|
||||
reason: str
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Skipping {self.distribution}: {self.reason}"
|
||||
return f"{colored('skipping', 'green')} ({self.reason})"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Error:
|
||||
distribution: str
|
||||
message: str
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{colored('error', 'red')} ({self.message})"
|
||||
|
||||
|
||||
_T = TypeVar("_T")
|
||||
@@ -542,7 +551,16 @@ async def has_no_longer_updated_release(release_to_download: PypiReleaseDownload
|
||||
return await with_extracted_archive(release_to_download, session=session, handler=parse_no_longer_updated_from_archive)
|
||||
|
||||
|
||||
async def determine_action(distribution: str, session: aiohttp.ClientSession) -> Update | NoUpdate | Obsolete | Remove:
|
||||
async def determine_action(distribution: str, session: aiohttp.ClientSession) -> Update | NoUpdate | Obsolete | Remove | Error:
|
||||
try:
|
||||
return await determine_action_no_error_handling(distribution, session)
|
||||
except Exception as exc:
|
||||
return Error(distribution, str(exc))
|
||||
|
||||
|
||||
async def determine_action_no_error_handling(
|
||||
distribution: str, session: aiohttp.ClientSession
|
||||
) -> Update | NoUpdate | Obsolete | Remove:
|
||||
stub_info = read_metadata(distribution)
|
||||
if stub_info.is_obsolete:
|
||||
assert type(stub_info.obsolete) is ObsoleteMetadata
|
||||
@@ -861,7 +879,7 @@ async def suggest_typeshed_remove(remove: Remove, session: aiohttp.ClientSession
|
||||
await create_or_update_pull_request(title=title, body=body, branch_name=branch_name, session=session)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--action-level",
|
||||
@@ -890,11 +908,11 @@ async def main() -> None:
|
||||
print("Unexpected exception!")
|
||||
print(diff_result.stdout)
|
||||
print(diff_result.stderr)
|
||||
sys.exit(diff_result.returncode)
|
||||
return diff_result.returncode
|
||||
if diff_result.stdout:
|
||||
changed_files = ", ".join(repr(line) for line in diff_result.stdout.split("\n") if line)
|
||||
print(f"Cannot run stubsabot, as uncommitted changes are present in {changed_files}!")
|
||||
sys.exit(1)
|
||||
return 1
|
||||
|
||||
if args.action_level > ActionLevel.fork:
|
||||
if os.environ.get("GITHUB_TOKEN") is None:
|
||||
@@ -909,6 +927,8 @@ async def main() -> None:
|
||||
if args.action_level >= ActionLevel.local:
|
||||
subprocess.check_call(["git", "fetch", "--prune", "--all"])
|
||||
|
||||
error = False
|
||||
|
||||
try:
|
||||
conn = aiohttp.TCPConnector(limit_per_host=10)
|
||||
async with aiohttp.ClientSession(connector=conn) as session:
|
||||
@@ -921,10 +941,14 @@ async def main() -> None:
|
||||
action_count = 0
|
||||
for task in asyncio.as_completed(tasks):
|
||||
update = await task
|
||||
print(f"{update.distribution}... ", end="")
|
||||
print(update)
|
||||
|
||||
if isinstance(update, NoUpdate):
|
||||
continue
|
||||
if isinstance(update, Error):
|
||||
error = True
|
||||
continue
|
||||
|
||||
if args.action_count_limit is not None and action_count >= args.action_count_limit:
|
||||
print(colored("... but we've reached action count limit", "red"))
|
||||
@@ -952,6 +976,8 @@ async def main() -> None:
|
||||
if args.action_level >= ActionLevel.local and original_branch:
|
||||
subprocess.check_call(["git", "checkout", original_branch])
|
||||
|
||||
return 1 if error else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
sys.exit(asyncio.run(main()))
|
||||
|
||||
Reference in New Issue
Block a user