@ascribed/review 0.1.2-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +183 -0
- package/dist/github/index.d.ts +7 -0
- package/dist/github/index.js +8 -0
- package/dist/github/index.js.map +1 -0
- package/dist/github/marker.d.ts +63 -0
- package/dist/github/marker.js +156 -0
- package/dist/github/marker.js.map +1 -0
- package/dist/github/queries.d.ts +16 -0
- package/dist/github/queries.js +174 -0
- package/dist/github/queries.js.map +1 -0
- package/dist/github/read.d.ts +84 -0
- package/dist/github/read.js +141 -0
- package/dist/github/read.js.map +1 -0
- package/dist/github/repository.d.ts +30 -0
- package/dist/github/repository.js +77 -0
- package/dist/github/repository.js.map +1 -0
- package/dist/github/requests.d.ts +65 -0
- package/dist/github/requests.js +274 -0
- package/dist/github/requests.js.map +1 -0
- package/dist/github/session.d.ts +143 -0
- package/dist/github/session.js +581 -0
- package/dist/github/session.js.map +1 -0
- package/dist/github/transport.d.ts +33 -0
- package/dist/github/transport.js +206 -0
- package/dist/github/transport.js.map +1 -0
- package/dist/marks/index.d.ts +92 -0
- package/dist/marks/index.js +766 -0
- package/dist/marks/index.js.map +1 -0
- package/dist/overlay/index.d.ts +4 -0
- package/dist/overlay/index.js +7 -0
- package/dist/overlay/index.js.map +1 -0
- package/dist/overlay/markdown.d.ts +4 -0
- package/dist/overlay/markdown.js +368 -0
- package/dist/overlay/markdown.js.map +1 -0
- package/dist/overlay/overlay.d.ts +47 -0
- package/dist/overlay/overlay.js +1710 -0
- package/dist/overlay/overlay.js.map +1 -0
- package/dist/overlay/style.d.ts +1 -0
- package/dist/overlay/style.js +570 -0
- package/dist/overlay/style.js.map +1 -0
- package/dist/overlay/text.d.ts +33 -0
- package/dist/overlay/text.js +200 -0
- package/dist/overlay/text.js.map +1 -0
- package/dist/overlay/types.d.ts +60 -0
- package/dist/overlay/types.js +2 -0
- package/dist/overlay/types.js.map +1 -0
- package/dist/place/anchor.d.ts +23 -0
- package/dist/place/anchor.js +49 -0
- package/dist/place/anchor.js.map +1 -0
- package/dist/place/index.d.ts +4 -0
- package/dist/place/index.js +6 -0
- package/dist/place/index.js.map +1 -0
- package/dist/place/lines.d.ts +56 -0
- package/dist/place/lines.js +280 -0
- package/dist/place/lines.js.map +1 -0
- package/dist/place/place.d.ts +77 -0
- package/dist/place/place.js +182 -0
- package/dist/place/place.js.map +1 -0
- package/dist/shared/errors.d.ts +40 -0
- package/dist/shared/errors.js +22 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/git.d.ts +4 -0
- package/dist/shared/git.js +29 -0
- package/dist/shared/git.js.map +1 -0
- package/dist/shared/types.d.ts +56 -0
- package/dist/shared/types.js +3 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +61 -0
- package/src/marks/marks.css +361 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// Moving a line number between a commit and the working tree, through the
|
|
2
|
+
// line changes `git diff --unified=0` reports.
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { git, gitMaybe } from "../shared/git.js";
|
|
7
|
+
/** The hunks of a unified diff of one file, in order. */
|
|
8
|
+
export function parseHunks(diff) {
|
|
9
|
+
const hunks = [];
|
|
10
|
+
for (const match of diff.matchAll(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/gm)) {
|
|
11
|
+
hunks.push({
|
|
12
|
+
oldStart: Number(match[1]),
|
|
13
|
+
oldCount: match[2] === undefined ? 1 : Number(match[2]),
|
|
14
|
+
newStart: Number(match[3]),
|
|
15
|
+
newCount: match[4] === undefined ? 1 : Number(match[4]),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return hunks;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Where line `line` of the old side is on the new side. A line the diff
|
|
22
|
+
* replaced maps onto the line that replaced it, with `replaced` set; a line it
|
|
23
|
+
* only deleted maps to `undefined`. Hunks come from a diff with no context
|
|
24
|
+
* lines.
|
|
25
|
+
*
|
|
26
|
+
* Old lines pair with new ones by position, clamped to the last new line.
|
|
27
|
+
* But a hunk with fewer new lines than old can have deleted some lines and
|
|
28
|
+
* reworded others, so with `sides` each of its old lines pairs with the new
|
|
29
|
+
* line most like it, in order, and an old line like none of them was deleted.
|
|
30
|
+
* When none of them pairs (the text was rewritten), or the hunk is too large
|
|
31
|
+
* to compare, it's by position again.
|
|
32
|
+
*/
|
|
33
|
+
export function shiftLine(hunks, line, sides) {
|
|
34
|
+
let delta = 0;
|
|
35
|
+
for (const hunk of hunks) {
|
|
36
|
+
if (hunk.oldCount === 0) {
|
|
37
|
+
// Lines inserted after old line `oldStart`.
|
|
38
|
+
if (line > hunk.oldStart)
|
|
39
|
+
delta += hunk.newCount;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const end = hunk.oldStart + hunk.oldCount;
|
|
43
|
+
if (line >= hunk.oldStart && line < end) {
|
|
44
|
+
if (hunk.newCount === 0)
|
|
45
|
+
return undefined;
|
|
46
|
+
const pairs = sides && pairLines(hunk, sides);
|
|
47
|
+
const offset = pairs === undefined
|
|
48
|
+
? Math.min(line - hunk.oldStart, hunk.newCount - 1)
|
|
49
|
+
: pairs[line - hunk.oldStart];
|
|
50
|
+
return offset === undefined ? undefined : { line: hunk.newStart + offset, replaced: true };
|
|
51
|
+
}
|
|
52
|
+
if (line >= end)
|
|
53
|
+
delta += hunk.newCount - hunk.oldCount;
|
|
54
|
+
}
|
|
55
|
+
return { line: line + delta, replaced: false };
|
|
56
|
+
}
|
|
57
|
+
/** How alike two lines must be, by their words, for one to be the other reworded. */
|
|
58
|
+
const ALIKE = 0.3;
|
|
59
|
+
const pairings = new WeakMap();
|
|
60
|
+
/**
|
|
61
|
+
* For each old line of a hunk with fewer new lines than old, the offset of
|
|
62
|
+
* the new line it became, or `undefined` if it was deleted: the pairing, in
|
|
63
|
+
* order, that makes the paired lines most alike. `undefined` when the hunk
|
|
64
|
+
* has as many new lines as old, is too large to compare, or no line pairs.
|
|
65
|
+
*/
|
|
66
|
+
function pairLines(hunk, sides) {
|
|
67
|
+
let cache = pairings.get(sides);
|
|
68
|
+
if (cache === undefined) {
|
|
69
|
+
cache = new WeakMap();
|
|
70
|
+
pairings.set(sides, cache);
|
|
71
|
+
}
|
|
72
|
+
if (cache.has(hunk))
|
|
73
|
+
return cache.get(hunk);
|
|
74
|
+
const n = hunk.oldCount;
|
|
75
|
+
const m = hunk.newCount;
|
|
76
|
+
let pairs;
|
|
77
|
+
if (m < n && n * m <= 250_000) {
|
|
78
|
+
const oldTokens = sides.old.slice(hunk.oldStart - 1, hunk.oldStart - 1 + n).map(tokens);
|
|
79
|
+
const newTokens = sides.new.slice(hunk.newStart - 1, hunk.newStart - 1 + m).map(tokens);
|
|
80
|
+
// `best(i, j)`: the most likeness pairing old lines from `i` on with new lines from `j` on.
|
|
81
|
+
const width = m + 1;
|
|
82
|
+
const table = new Float64Array((n + 1) * width);
|
|
83
|
+
const best = (i, j) => table[i * width + j] ?? 0;
|
|
84
|
+
const like = (i, j) => {
|
|
85
|
+
const score = likeness(oldTokens[i] ?? [], newTokens[j] ?? []);
|
|
86
|
+
return score >= ALIKE ? score : 0;
|
|
87
|
+
};
|
|
88
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
89
|
+
for (let j = m - 1; j >= 0; j--) {
|
|
90
|
+
const score = like(i, j);
|
|
91
|
+
table[i * width + j] = Math.max(score > 0 ? best(i + 1, j + 1) + score : 0, best(i + 1, j), best(i, j + 1));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (best(0, 0) > 0) {
|
|
95
|
+
pairs = [];
|
|
96
|
+
let i = 0;
|
|
97
|
+
let j = 0;
|
|
98
|
+
while (i < n) {
|
|
99
|
+
const score = j < m ? like(i, j) : 0;
|
|
100
|
+
if (score > 0 && best(i, j) === best(i + 1, j + 1) + score) {
|
|
101
|
+
pairs.push(j);
|
|
102
|
+
i++;
|
|
103
|
+
j++;
|
|
104
|
+
}
|
|
105
|
+
else if (j >= m || best(i, j) === best(i + 1, j)) {
|
|
106
|
+
pairs.push(undefined);
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
j++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
cache.set(hunk, pairs);
|
|
116
|
+
return pairs;
|
|
117
|
+
}
|
|
118
|
+
/** Scripts written without spaces between words, compared by pairs of characters instead. */
|
|
119
|
+
const UNSPACED = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Thai}]/u;
|
|
120
|
+
/**
|
|
121
|
+
* What a line is compared by: its words, in lower case, with text in scripts
|
|
122
|
+
* written without spaces as pairs of characters; or, for a line with no
|
|
123
|
+
* letters or digits, such as `});` or `---`, its characters.
|
|
124
|
+
*/
|
|
125
|
+
function tokens(line) {
|
|
126
|
+
const text = (line ?? "").toLowerCase();
|
|
127
|
+
const found = [];
|
|
128
|
+
for (const [word] of text.matchAll(/[\p{L}\p{M}\p{N}]+/gu)) {
|
|
129
|
+
if (!UNSPACED.test(word)) {
|
|
130
|
+
found.push(word);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const chars = Array.from(word);
|
|
134
|
+
if (chars.length === 1)
|
|
135
|
+
found.push(word);
|
|
136
|
+
for (let i = 0; i + 1 < chars.length; i++)
|
|
137
|
+
found.push(`${chars[i]}${chars[i + 1]}`);
|
|
138
|
+
}
|
|
139
|
+
return found.length > 0 ? found : Array.from(text.replace(/\s+/g, ""));
|
|
140
|
+
}
|
|
141
|
+
/** How many tokens two lines share, from 0 to 1: twice the shared count over the total. */
|
|
142
|
+
function likeness(a, b) {
|
|
143
|
+
if (a.length === 0 || b.length === 0)
|
|
144
|
+
return 0;
|
|
145
|
+
const counts = new Map();
|
|
146
|
+
for (const token of a)
|
|
147
|
+
counts.set(token, (counts.get(token) ?? 0) + 1);
|
|
148
|
+
let shared = 0;
|
|
149
|
+
for (const token of b) {
|
|
150
|
+
const count = counts.get(token) ?? 0;
|
|
151
|
+
if (count > 0) {
|
|
152
|
+
shared++;
|
|
153
|
+
counts.set(token, count - 1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return (2 * shared) / (a.length + b.length);
|
|
157
|
+
}
|
|
158
|
+
const NOTHING = { map: () => undefined, identity: false };
|
|
159
|
+
/**
|
|
160
|
+
* A map of the lines of the repository-relative `file` between `commit` and
|
|
161
|
+
* the working tree, in the direction given. Every line maps to nothing when
|
|
162
|
+
* the commit isn't in the repository or the file is missing on either side.
|
|
163
|
+
*/
|
|
164
|
+
export async function lineMap(root, commit, file, direction) {
|
|
165
|
+
const atCommit = await gitMaybe(root, ["cat-file", "-e", `${commit}:${file}`]);
|
|
166
|
+
if (atCommit === undefined)
|
|
167
|
+
return NOTHING;
|
|
168
|
+
if (!existsSync(path.join(root, ...file.split("/"))))
|
|
169
|
+
return NOTHING;
|
|
170
|
+
const diff = await git(root, [
|
|
171
|
+
"diff",
|
|
172
|
+
"--no-color",
|
|
173
|
+
"--no-ext-diff",
|
|
174
|
+
"--no-renames",
|
|
175
|
+
"--unified=0",
|
|
176
|
+
...(direction === "to-commit" ? ["-R"] : []),
|
|
177
|
+
commit,
|
|
178
|
+
"--",
|
|
179
|
+
`:(literal)${file}`,
|
|
180
|
+
]);
|
|
181
|
+
const hunks = parseHunks(diff);
|
|
182
|
+
if (hunks.length === 0)
|
|
183
|
+
return { map: (line) => ({ line, replaced: false }), identity: true };
|
|
184
|
+
let sides;
|
|
185
|
+
if (hunks.some((hunk) => hunk.oldCount > 0 && hunk.newCount > 0)) {
|
|
186
|
+
const atCommitText = (await gitMaybe(root, ["cat-file", "blob", `${commit}:${file}`])) ?? "";
|
|
187
|
+
const inWorktree = await readFile(path.join(root, ...file.split("/")), "utf8").catch(() => "");
|
|
188
|
+
const [from, to] = direction === "to-worktree" ? [atCommitText, inWorktree] : [inWorktree, atCommitText];
|
|
189
|
+
sides = { old: from.split(/\r?\n/), new: to.split(/\r?\n/) };
|
|
190
|
+
}
|
|
191
|
+
return { map: (line) => shiftLine(hunks, line, sides), identity: false };
|
|
192
|
+
}
|
|
193
|
+
/** Lines `first`..`last` of the repository-relative `file` at `commit`, or `undefined`. */
|
|
194
|
+
export async function linesAt(root, commit, file, first, last) {
|
|
195
|
+
const text = await gitMaybe(root, ["cat-file", "blob", `${commit}:${file}`]);
|
|
196
|
+
if (text === undefined)
|
|
197
|
+
return undefined;
|
|
198
|
+
const lines = text.split(/\r?\n/);
|
|
199
|
+
if (last > lines.length)
|
|
200
|
+
return undefined;
|
|
201
|
+
return lines.slice(first - 1, last).join("\n");
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The hunks that turn `before` into `after`, line by line, as
|
|
205
|
+
* `git diff --unified=0` would report them: for text in hand, such as a file
|
|
206
|
+
* and an editor's unsaved copy of it. Lines common to both ends are skipped
|
|
207
|
+
* first; a middle too large to compare line by line is one hunk.
|
|
208
|
+
*/
|
|
209
|
+
export function lineHunks(before, after) {
|
|
210
|
+
const a = before.split(/\r?\n/);
|
|
211
|
+
const b = after.split(/\r?\n/);
|
|
212
|
+
let start = 0;
|
|
213
|
+
while (start < a.length && start < b.length && a[start] === b[start])
|
|
214
|
+
start++;
|
|
215
|
+
let endA = a.length;
|
|
216
|
+
let endB = b.length;
|
|
217
|
+
while (endA > start && endB > start && a[endA - 1] === b[endB - 1]) {
|
|
218
|
+
endA--;
|
|
219
|
+
endB--;
|
|
220
|
+
}
|
|
221
|
+
const n = endA - start;
|
|
222
|
+
const m = endB - start;
|
|
223
|
+
if (n === 0 && m === 0)
|
|
224
|
+
return [];
|
|
225
|
+
if (n * m > 4_000_000 || n === 0 || m === 0)
|
|
226
|
+
return [hunk(start, n, start, m)];
|
|
227
|
+
// The longest common subsequence of the middles, by dynamic programming:
|
|
228
|
+
// `lcs(i, j)` is its length for the lines from `start + i` and `start + j` on.
|
|
229
|
+
const width = m + 1;
|
|
230
|
+
const table = new Uint32Array((n + 1) * width);
|
|
231
|
+
const lcs = (i, j) => table[i * width + j] ?? 0;
|
|
232
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
233
|
+
for (let j = m - 1; j >= 0; j--) {
|
|
234
|
+
table[i * width + j] =
|
|
235
|
+
a[start + i] === b[start + j]
|
|
236
|
+
? lcs(i + 1, j + 1) + 1
|
|
237
|
+
: Math.max(lcs(i + 1, j), lcs(i, j + 1));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const hunks = [];
|
|
241
|
+
let i = 0;
|
|
242
|
+
let j = 0;
|
|
243
|
+
let fromA = 0;
|
|
244
|
+
let fromB = 0;
|
|
245
|
+
const flush = () => {
|
|
246
|
+
if (i > fromA || j > fromB)
|
|
247
|
+
hunks.push(hunk(start + fromA, i - fromA, start + fromB, j - fromB));
|
|
248
|
+
};
|
|
249
|
+
while (i < n || j < m) {
|
|
250
|
+
if (i < n && j < m && a[start + i] === b[start + j]) {
|
|
251
|
+
flush();
|
|
252
|
+
i++;
|
|
253
|
+
j++;
|
|
254
|
+
fromA = i;
|
|
255
|
+
fromB = j;
|
|
256
|
+
}
|
|
257
|
+
else if (j >= m || (i < n && lcs(i + 1, j) >= lcs(i, j + 1))) {
|
|
258
|
+
i++;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
j++;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
flush();
|
|
265
|
+
return hunks;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* A hunk of `count` lines after `at` lines (counted from 0) on each side,
|
|
269
|
+
* numbered as `git diff --unified=0` does: an empty side names the line
|
|
270
|
+
* before it.
|
|
271
|
+
*/
|
|
272
|
+
function hunk(atA, countA, atB, countB) {
|
|
273
|
+
return {
|
|
274
|
+
oldStart: countA === 0 ? atA : atA + 1,
|
|
275
|
+
oldCount: countA,
|
|
276
|
+
newStart: countB === 0 ? atB : atB + 1,
|
|
277
|
+
newCount: countB,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/place/lines.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Thread } from "../shared/types.js";
|
|
2
|
+
import { type Anchor } from "./anchor.js";
|
|
3
|
+
/** A rendered page, as placing needs it. */
|
|
4
|
+
export interface PageRef {
|
|
5
|
+
/** The build the page is rendered for. */
|
|
6
|
+
build: string;
|
|
7
|
+
/** The page's own content path. */
|
|
8
|
+
path: string;
|
|
9
|
+
/** Every anchored block on the page, in the page's order. */
|
|
10
|
+
anchors: Anchor[];
|
|
11
|
+
/**
|
|
12
|
+
* Where the diff's removed, moved, and changed blocks on this page were
|
|
13
|
+
* (each such change's `was`), for threads on the text they had.
|
|
14
|
+
*/
|
|
15
|
+
removed?: Anchor[] | undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Why a thread isn't on a block. */
|
|
18
|
+
export type DetachReason =
|
|
19
|
+
/** The line it's on isn't in the working tree any more. */
|
|
20
|
+
"line-gone"
|
|
21
|
+
/** It's on a whole file, not a line. */
|
|
22
|
+
| "file"
|
|
23
|
+
/** No block on the page holds its line. */
|
|
24
|
+
| "no-block";
|
|
25
|
+
/** A thread, located in the working tree. */
|
|
26
|
+
export interface LocatedThread extends Thread {
|
|
27
|
+
/** The file's content path. */
|
|
28
|
+
path: string;
|
|
29
|
+
/**
|
|
30
|
+
* The thread's lines: in the working tree for the right side, at the diff's
|
|
31
|
+
* base for the left side. `undefined` when it's detached.
|
|
32
|
+
*/
|
|
33
|
+
lines: {
|
|
34
|
+
first: number;
|
|
35
|
+
last: number;
|
|
36
|
+
} | undefined;
|
|
37
|
+
/** Why it's detached, or `undefined` when it's on lines. */
|
|
38
|
+
detached: DetachReason | undefined;
|
|
39
|
+
}
|
|
40
|
+
/** A page's threads. */
|
|
41
|
+
export interface PlacedThreads {
|
|
42
|
+
/** Threads on the page's blocks, by anchor, in the page's order. */
|
|
43
|
+
blocks: {
|
|
44
|
+
anchor: Anchor;
|
|
45
|
+
threads: LocatedThread[];
|
|
46
|
+
}[];
|
|
47
|
+
/** Threads on removed text, by the removed block's anchor. */
|
|
48
|
+
removed: {
|
|
49
|
+
anchor: Anchor;
|
|
50
|
+
threads: LocatedThread[];
|
|
51
|
+
}[];
|
|
52
|
+
/** Threads on the page's files that aren't on any block. */
|
|
53
|
+
detached: LocatedThread[];
|
|
54
|
+
}
|
|
55
|
+
/** What locating needs to know about the checkout and the pull request. */
|
|
56
|
+
export interface LocateContext {
|
|
57
|
+
/** The repository's top-level directory. */
|
|
58
|
+
root: string;
|
|
59
|
+
/** The content root's path in the repository, with a trailing `/`, or `""` at the root. */
|
|
60
|
+
contentPrefix: string;
|
|
61
|
+
/** The pull request's head commit, which current threads' lines are counted at. */
|
|
62
|
+
headOid: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Locates threads in the working tree. Threads on files outside the content
|
|
66
|
+
* root are left out; every other thread is returned, on lines or detached.
|
|
67
|
+
*/
|
|
68
|
+
export declare function locateThreads(threads: readonly Thread[], context: LocateContext): Promise<LocatedThread[]>;
|
|
69
|
+
/**
|
|
70
|
+
* The threads on one page. A thread goes on the smallest block that holds all
|
|
71
|
+
* its lines (or, failing that, its last line), on every place that block is
|
|
72
|
+
* shown: a fragment included twice is two blocks with the same source. A
|
|
73
|
+
* thread on one of the page's files that no block holds is detached, as are
|
|
74
|
+
* detached threads on those files. Conversation comments marked for another
|
|
75
|
+
* build are left out.
|
|
76
|
+
*/
|
|
77
|
+
export declare function placeOnPage(page: PageRef, threads: readonly LocatedThread[]): PlacedThreads;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { anchorKey, parseSource } from "./anchor.js";
|
|
2
|
+
import { lineMap, linesAt } from "./lines.js";
|
|
3
|
+
/**
|
|
4
|
+
* Locates threads in the working tree. Threads on files outside the content
|
|
5
|
+
* root are left out; every other thread is returned, on lines or detached.
|
|
6
|
+
*/
|
|
7
|
+
export async function locateThreads(threads, context) {
|
|
8
|
+
const maps = new Map();
|
|
9
|
+
const mapFor = (commit, file) => {
|
|
10
|
+
const key = `${commit}\0${file}`;
|
|
11
|
+
let map = maps.get(key);
|
|
12
|
+
if (map === undefined) {
|
|
13
|
+
map = lineMap(context.root, commit, file, "to-worktree");
|
|
14
|
+
maps.set(key, map);
|
|
15
|
+
}
|
|
16
|
+
return map;
|
|
17
|
+
};
|
|
18
|
+
const located = [];
|
|
19
|
+
for (const thread of threads) {
|
|
20
|
+
if (!thread.repositoryPath.startsWith(context.contentPrefix))
|
|
21
|
+
continue;
|
|
22
|
+
const path = thread.repositoryPath.slice(context.contentPrefix.length);
|
|
23
|
+
const result = (lines, detached, quote) => located.push({
|
|
24
|
+
...thread,
|
|
25
|
+
path,
|
|
26
|
+
lines,
|
|
27
|
+
detached,
|
|
28
|
+
quote: quote ?? thread.quote,
|
|
29
|
+
});
|
|
30
|
+
if (thread.kind === "conversation" || thread.side === "LEFT") {
|
|
31
|
+
const last = thread.kind === "review" && thread.outdated ? undefined : thread.line;
|
|
32
|
+
if (thread.subject === "file")
|
|
33
|
+
result(undefined, "file");
|
|
34
|
+
else if (last === null || last === undefined) {
|
|
35
|
+
result(undefined, "line-gone", hunkQuote(thread, thread.side));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const first = thread.startLine ?? last;
|
|
39
|
+
result({ first, last }, undefined, thread.quote ?? hunkQuote(thread, thread.side));
|
|
40
|
+
}
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (thread.subject === "file") {
|
|
44
|
+
result(undefined, "file");
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const commit = thread.outdated ? thread.originalCommit : context.headOid;
|
|
48
|
+
const last = thread.outdated ? thread.originalLine : thread.line;
|
|
49
|
+
const start = (thread.outdated ? thread.originalStartLine : thread.startLine) ?? last;
|
|
50
|
+
if (commit === undefined || last === null || start === null) {
|
|
51
|
+
result(undefined, "line-gone", hunkQuote(thread, "RIGHT"));
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const original = async () => (await linesAt(context.root, commit, thread.repositoryPath, start, last)) ??
|
|
55
|
+
hunkQuote(thread, "RIGHT");
|
|
56
|
+
const map = await mapFor(commit, thread.repositoryPath);
|
|
57
|
+
// When some of the thread's lines went but others stayed, it keeps what's left.
|
|
58
|
+
const kept = [];
|
|
59
|
+
let replaced = false;
|
|
60
|
+
for (let line = start; line <= last; line++) {
|
|
61
|
+
const mapped = map.map(line);
|
|
62
|
+
if (mapped === undefined)
|
|
63
|
+
replaced = true;
|
|
64
|
+
else {
|
|
65
|
+
kept.push(mapped.line);
|
|
66
|
+
replaced ||= mapped.replaced;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (kept.length === 0) {
|
|
70
|
+
result(undefined, "line-gone", await original());
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// Reworded text keeps its place, marked outdated, with what it said.
|
|
74
|
+
const outdated = thread.outdated || replaced;
|
|
75
|
+
located.push({
|
|
76
|
+
...thread,
|
|
77
|
+
path,
|
|
78
|
+
lines: { first: Math.min(...kept), last: Math.max(...kept) },
|
|
79
|
+
detached: undefined,
|
|
80
|
+
outdated,
|
|
81
|
+
quote: outdated ? await original() : thread.quote,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return located;
|
|
85
|
+
}
|
|
86
|
+
/** The thread's lines, from the end of GitHub's diff hunk. */
|
|
87
|
+
function hunkQuote(thread, side) {
|
|
88
|
+
if (thread.diffHunk === undefined)
|
|
89
|
+
return undefined;
|
|
90
|
+
const skip = side === "LEFT" ? "+" : "-";
|
|
91
|
+
const lines = thread.diffHunk
|
|
92
|
+
.split(/\r?\n/)
|
|
93
|
+
.filter((line) => !line.startsWith("@@") && !line.startsWith(skip))
|
|
94
|
+
.map((line) => line.slice(1));
|
|
95
|
+
const last = thread.outdated ? thread.originalLine : thread.line;
|
|
96
|
+
const first = (thread.outdated ? thread.originalStartLine : thread.startLine) ?? last;
|
|
97
|
+
const count = first !== null && last !== null ? last - first + 1 : 1;
|
|
98
|
+
return lines.slice(-Math.max(1, count)).join("\n");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The threads on one page. A thread goes on the smallest block that holds all
|
|
102
|
+
* its lines (or, failing that, its last line), on every place that block is
|
|
103
|
+
* shown: a fragment included twice is two blocks with the same source. A
|
|
104
|
+
* thread on one of the page's files that no block holds is detached, as are
|
|
105
|
+
* detached threads on those files. Conversation comments marked for another
|
|
106
|
+
* build are left out.
|
|
107
|
+
*/
|
|
108
|
+
export function placeOnPage(page, threads) {
|
|
109
|
+
const anchors = parseAnchors(page.anchors);
|
|
110
|
+
const removedAnchors = parseAnchors(page.removed ?? []);
|
|
111
|
+
const files = new Set([page.path, ...anchors.map((a) => a.range.path)]);
|
|
112
|
+
const onBlocks = new Map();
|
|
113
|
+
const onRemoved = new Map();
|
|
114
|
+
const detached = [];
|
|
115
|
+
for (const thread of threads) {
|
|
116
|
+
const build = thread.marker?.build;
|
|
117
|
+
if (build !== undefined && build !== page.build)
|
|
118
|
+
continue;
|
|
119
|
+
if (thread.lines === undefined) {
|
|
120
|
+
if (files.has(thread.path))
|
|
121
|
+
detached.push(thread);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const left = thread.kind === "review" && thread.side === "LEFT";
|
|
125
|
+
const matches = holding(left ? removedAnchors : anchors, thread.path, thread.lines);
|
|
126
|
+
if (matches.length === 0) {
|
|
127
|
+
if (files.has(thread.path))
|
|
128
|
+
detached.push({ ...thread, detached: "no-block" });
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const into = left ? onRemoved : onBlocks;
|
|
132
|
+
for (const match of matches) {
|
|
133
|
+
const key = anchorKey(match.anchor);
|
|
134
|
+
const list = into.get(key) ?? [];
|
|
135
|
+
list.push(thread);
|
|
136
|
+
into.set(key, list);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const collect = (list, by) => {
|
|
140
|
+
const out = [];
|
|
141
|
+
const seen = new Set();
|
|
142
|
+
for (const { anchor } of list) {
|
|
143
|
+
const key = anchorKey(anchor);
|
|
144
|
+
const found = by.get(key);
|
|
145
|
+
if (found === undefined || seen.has(key))
|
|
146
|
+
continue;
|
|
147
|
+
seen.add(key);
|
|
148
|
+
out.push({ anchor, threads: found });
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
blocks: collect(anchors, onBlocks),
|
|
154
|
+
removed: collect(removedAnchors, onRemoved),
|
|
155
|
+
detached,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function parseAnchors(anchors) {
|
|
159
|
+
const parsed = [];
|
|
160
|
+
for (const anchor of anchors) {
|
|
161
|
+
const range = parseSource(anchor.source);
|
|
162
|
+
if (range !== undefined)
|
|
163
|
+
parsed.push({ anchor, range });
|
|
164
|
+
}
|
|
165
|
+
return parsed;
|
|
166
|
+
}
|
|
167
|
+
/** The smallest anchors on `path` holding `lines`, else the smallest holding its last line. */
|
|
168
|
+
function holding(anchors, path, lines) {
|
|
169
|
+
const onFile = anchors.filter((a) => a.range.path === path);
|
|
170
|
+
for (const [first, last] of [
|
|
171
|
+
[lines.first, lines.last],
|
|
172
|
+
[lines.last, lines.last],
|
|
173
|
+
]) {
|
|
174
|
+
const containing = onFile.filter((a) => a.range.first <= first && a.range.last >= last);
|
|
175
|
+
if (containing.length === 0)
|
|
176
|
+
continue;
|
|
177
|
+
const size = Math.min(...containing.map((a) => a.range.last - a.range.first));
|
|
178
|
+
return containing.filter((a) => a.range.last - a.range.first === size);
|
|
179
|
+
}
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=place.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"place.js","sourceRoot":"","sources":["../../src/place/place.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Why a request to GitHub, or a step around it, failed. */
|
|
2
|
+
export type ReviewErrorCode =
|
|
3
|
+
/** `gh` isn't on the path. */
|
|
4
|
+
"gh-missing"
|
|
5
|
+
/** `gh` is older than the oldest version this package supports. */
|
|
6
|
+
| "gh-too-old"
|
|
7
|
+
/** `gh` isn't signed in to the host, or the host refused the token. */
|
|
8
|
+
| "not-signed-in"
|
|
9
|
+
/** GitHub's secondary rate limit: wait `retryAfter` seconds and try again. */
|
|
10
|
+
| "rate-limited"
|
|
11
|
+
/** GitHub answered with an error. */
|
|
12
|
+
| "refused"
|
|
13
|
+
/** The request didn't reach GitHub, or the answer couldn't be read. */
|
|
14
|
+
| "network"
|
|
15
|
+
/** A comment's block has lines that aren't at the pull request's head commit. */
|
|
16
|
+
| "push-first"
|
|
17
|
+
/** A reply can't be sent at once while the viewer has a pending review. */
|
|
18
|
+
| "reply-held"
|
|
19
|
+
/**
|
|
20
|
+
* A comment GitHub can't anchor can't be held in the viewer's pending
|
|
21
|
+
* review, which was started on GitHub without a summary.
|
|
22
|
+
*/
|
|
23
|
+
| "cant-hold"
|
|
24
|
+
/** The thread, or another object named, isn't in the pull request. */
|
|
25
|
+
| "not-found"
|
|
26
|
+
/** `git` failed, or the checkout isn't a git repository. */
|
|
27
|
+
| "git";
|
|
28
|
+
/** An error from this package. `message` is a sentence a host can show. */
|
|
29
|
+
export declare class ReviewError extends Error {
|
|
30
|
+
name: string;
|
|
31
|
+
readonly code: ReviewErrorCode;
|
|
32
|
+
/** For `rate-limited`: the seconds to wait, when GitHub said. */
|
|
33
|
+
readonly retryAfter: number | undefined;
|
|
34
|
+
constructor(code: ReviewErrorCode, message: string, options?: {
|
|
35
|
+
cause?: unknown;
|
|
36
|
+
retryAfter?: number;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** `text` with anything shaped like a GitHub token replaced. */
|
|
40
|
+
export declare function scrub(text: string): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// The errors this package throws, each with a code a host can switch on to
|
|
2
|
+
// explain it.
|
|
3
|
+
/** An error from this package. `message` is a sentence a host can show. */
|
|
4
|
+
export class ReviewError extends Error {
|
|
5
|
+
name = "ReviewError";
|
|
6
|
+
code;
|
|
7
|
+
/** For `rate-limited`: the seconds to wait, when GitHub said. */
|
|
8
|
+
retryAfter;
|
|
9
|
+
constructor(code, message, options = {}) {
|
|
10
|
+
super(scrub(message), options.cause === undefined ? undefined : { cause: options.cause });
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.retryAfter = options.retryAfter;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
// GitHub's token formats: classic (`ghp_`), OAuth (`gho_`), user-to-server
|
|
16
|
+
// (`ghu_`), server-to-server (`ghs_`), refresh (`ghr_`), and fine-grained.
|
|
17
|
+
const TOKEN = /\b(?:gh[opusr]_[A-Za-z0-9_]{16,}|github_pat_[A-Za-z0-9_]{20,})\b/g;
|
|
18
|
+
/** `text` with anything shaped like a GitHub token replaced. */
|
|
19
|
+
export function scrub(text) {
|
|
20
|
+
return text.replace(TOKEN, "[token]");
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc;AA8Bd,2EAA2E;AAC3E,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,GAAG,aAAa,CAAC;IACrB,IAAI,CAAkB;IAC/B,iEAAiE;IACxD,UAAU,CAAqB;IAExC,YACE,IAAqB,EACrB,OAAe,EACf,OAAO,GAA6C,EAAE;QAEtD,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,CAAC;CACF;AAED,2EAA2E;AAC3E,2EAA2E;AAC3E,MAAM,KAAK,GAAG,mEAAmE,CAAC;AAElF,gEAAgE;AAChE,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Runs `git` in `cwd` and resolves with its standard output. */
|
|
2
|
+
export declare function git(cwd: string, args: readonly string[]): Promise<string>;
|
|
3
|
+
/** Like `git`, but resolves with `undefined` instead of rejecting when git exits non-zero. */
|
|
4
|
+
export declare function gitMaybe(cwd: string, args: readonly string[]): Promise<string | undefined>;
|