MCPcopy Create free account
hub / github.com/alibaba/open-code-review / getPrDiffHunks

Function getPrDiffHunks

scripts/github-actions/post-review-comments.js:1971–2057  ·  view source on GitHub ↗
({ github, owner, repo, prNumber, commitSha, log, cache })

Source from the content-addressed store, hash-verified

1969// `cache` (optional) memoizes the result for the run: with several batches each
1970// failing 422, the inventory would otherwise be refetched per batch.
1971async function getPrDiffHunks({ github, owner, repo, prNumber, commitSha, log, cache }) {
1972 const logFn = typeof log === "function" ? log : () => {};
1973 if (cache && cache.diff !== undefined) return cache.diff;
1974
1975 const files = new Map();
1976 const known = new Set();
1977 let complete = true;
1978
1979 const PER_PAGE = 100;
1980 const MAX_PAGES = 30;
1981 let page = 1;
1982 while (page <= MAX_PAGES) {
1983 const res = await readWithPacing(
1984 `listFiles (page ${page})`,
1985 () => github.rest.pulls.listFiles({ owner, repo, pull_number: prNumber, per_page: PER_PAGE, page }),
1986 logFn
1987 );
1988 const batch = (res && res.data) || [];
1989 for (const file of batch) {
1990 if (!file || !file.filename) continue;
1991 known.add(file.filename);
1992 if (file.patch) {
1993 const parsed = parseDiffHunkInventory(file.patch);
1994 if (parsed.complete) {
1995 files.set(file.filename, parsed.ranges);
1996 } else {
1997 logFn(
1998 `[422-fallback] Patch data for ${file.filename} is incomplete or malformed; ` +
1999 `comments on that file will be treated as unknown rather than out-of-diff.`
2000 );
2001 }
2002 }
2003 }
2004 if (batch.length < PER_PAGE) break;
2005 page++;
2006 }
2007 if (page > MAX_PAGES) {
2008 complete = false;
2009 logFn(
2010 `[422-fallback] PR changed-file list exceeded ${MAX_PAGES * PER_PAGE} files; ` +
2011 `diff inventory is incomplete, so no comment will be discarded as out-of-diff.`
2012 );
2013 }
2014
2015 // An empty inventory proves nothing. A PR that produced review comments
2016 // necessarily has changed files, so an empty listFiles response is an anomaly
2017 // (diff not yet materialized server-side, or a malformed/empty response body)
2018 // rather than evidence that every commented path sits outside the diff.
2019 // Trusting it would classify EVERY comment "invalid" and discard the whole
2020 // batch without a single posting attempt — the exact outcome the tri-state
2021 // classification exists to prevent. Note this is the mirror of the truncation
2022 // case above: too many files and zero files are both "cannot judge".
2023 if (known.size === 0) {
2024 complete = false;
2025 logFn(
2026 `[422-fallback] PR changed-file list came back empty, which cannot be right for a PR ` +
2027 `under review; treating the diff inventory as incomplete, so no comment will be ` +
2028 `discarded as out-of-diff.`

Calls 4

readWithPacingFunction · 0.85
parseDiffHunkInventoryFunction · 0.85
listFilesMethod · 0.80
setMethod · 0.80