diff --git a/src/lib/client.ts b/src/lib/client.ts index 91fcc58..9a608ba 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -22,15 +22,13 @@ export class ApiClient { return parser.parse(unkn); } - async fetch_parse_paginated(path: string, parser: z.ZodType) { - const result = [] as T[]; + async *fetch_parse_paginated(path: string, parser: z.ZodType): AsyncIterable { let page = 1; while (true) { const fetched = await this.fetch_parse(path + "?per_page=100&page=" + page, parser.array()); - result.push(...fetched); + yield* fetched; if (fetch.length < 100) break; page += 1; } - return result; } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index c4f0259..d757cd9 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -3,8 +3,14 @@ export function sum(numbers: Iterable) { for (const item of numbers) result += item; return result; } -export async function parallel(inputs: I[], operation: (item: I) => Promise) { +export async function parallel(inputs: AsyncIterable, operation: (item: I) => Promise) { const promises = [] as Promise[]; - for (const input of inputs) promises.push(operation(input)); + for await (const input of inputs) promises.push(operation(input)); return await Promise.all(promises); } + +export async function collect(gen: AsyncIterable) { + const result = [] as T[]; + for await (const item of gen) result.push(item); + return result; +} diff --git a/src/okimeter.ts b/src/okimeter.ts index 4312aae..a16a0eb 100755 --- a/src/okimeter.ts +++ b/src/okimeter.ts @@ -11,7 +11,7 @@ async function main() { let { token } = parse_args(Deno.args); if (token === undefined) token = prompt_args(); const client = new ApiClient("gitlab.cri.epita.fr", token); - const merge_requests = await get_all_merge_requests(client); + const merge_requests = get_all_merge_requests(client); const total = sum(await parallel(merge_requests, (mr) => count_in_merge_request(mr, client))); console.log("Total", total, "oki"); } @@ -35,19 +35,23 @@ ${gr("> xxxxxxxxxxxxxxxxxxxx")} return result.trim(); } -async function get_all_merge_requests(client: ApiClient) { - return await client.fetch_parse_paginated(`api/v4/merge_requests`, merge_request_parser); +function get_all_merge_requests(client: ApiClient) { + return client.fetch_parse_paginated(`api/v4/merge_requests`, merge_request_parser); } async function count_in_merge_request(merge_request: MergeRequest, client: ApiClient) { + const all_notes = get_all_merge_request_notes(merge_request, client); let total = 0; - const merge_request_path = `api/v4/projects/${merge_request.project_id}/merge_requests/${merge_request.iid}`; - const all_notes = await client.fetch_parse_paginated(`${merge_request_path}/notes`, note_parser); - for (const note of all_notes) { + for await (const note of all_notes) { if (!await is_relevant(note.author.username)) continue; if (note.body.toLowerCase().includes("oki")) total += 1; } return total; } +function get_all_merge_request_notes(merge_request: MergeRequest, client: ApiClient) { + const merge_request_path = `api/v4/projects/${merge_request.project_id}/merge_requests/${merge_request.iid}`; + return client.fetch_parse_paginated(`${merge_request_path}/notes`, note_parser); +} + if (import.meta.main) await main();