@a9n-shoji/rvw 0.2.4 → 0.3.0
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/CHANGELOG.md +36 -0
- package/dist/cli-THIRD_PARTY_NOTICES.txt +703 -0
- package/dist/cli.mjs +14577 -1482
- package/dist/cli.mjs.map +4 -4
- package/dist/web/THIRD_PARTY_NOTICES.txt +29 -0
- package/dist/web/assets/DocumentViewer-DtusMl0r.js +1561 -0
- package/dist/web/assets/MarkdownTable-BjwiOHQe.js +15 -0
- package/dist/web/assets/WalkthroughViewer-BNwKsKzk.js +42 -0
- package/dist/web/assets/{abnfDiagram-N423BO3Z-CE1nZSC9.js → abnfDiagram-N423BO3Z-DtH8B7Z7.js} +1 -1
- package/dist/web/assets/architecture-TIHT7OUA-P_K7H_mW.js +1 -0
- package/dist/web/assets/{architectureDiagram-T3A2C74G-B88qYFUo.js → architectureDiagram-T3A2C74G-5Fq3Xylv.js} +1 -1
- package/dist/web/assets/{blockDiagram-VBNYF7ZC-BaX0rhbb.js → blockDiagram-VBNYF7ZC-BBG7PXeg.js} +1 -1
- package/dist/web/assets/{c4Diagram-5PPSVZJV-C1ppBaEC.js → c4Diagram-5PPSVZJV-oLErQeqr.js} +1 -1
- package/dist/web/assets/channel-wXu0iczQ.js +1 -0
- package/dist/web/assets/{chunk-2GRJ4B5K-D2TTocfh.js → chunk-2GRJ4B5K-Bknsyt9u.js} +1 -1
- package/dist/web/assets/{chunk-4I5QYGJK-ikT25rPN.js → chunk-4I5QYGJK-D-Icvgxq.js} +1 -1
- package/dist/web/assets/{chunk-5RXB4S5H-CGlPaulj.js → chunk-5RXB4S5H-B1iIyQwd.js} +1 -1
- package/dist/web/assets/{chunk-6Q2QTUOP-BuuMeCo2.js → chunk-6Q2QTUOP-C09OFw2-.js} +1 -1
- package/dist/web/assets/{chunk-7Z6QIM7H-DT3BAZ4L.js → chunk-7Z6QIM7H-BqCAUqX5.js} +1 -1
- package/dist/web/assets/{chunk-GF5L2VYU-mIdlxzfr.js → chunk-GF5L2VYU-BHy3jGGE.js} +1 -1
- package/dist/web/assets/{chunk-I66GZJ75-CGl1hx4J.js → chunk-I66GZJ75-BBhE3jWF.js} +1 -1
- package/dist/web/assets/{chunk-JQJVKLGR-BLG6gAfx.js → chunk-JQJVKLGR-DNslGDt7.js} +1 -1
- package/dist/web/assets/{chunk-KBJHAD2P-D_MPzBJx.js → chunk-KBJHAD2P-J7tWEBhK.js} +1 -1
- package/dist/web/assets/{chunk-NSK5VX7P-CiYiU8wP.js → chunk-NSK5VX7P-retcSoJp.js} +1 -1
- package/dist/web/assets/{chunk-QR6OTTB3-BK8Tnvcc.js → chunk-QR6OTTB3-DvFlp4db.js} +1 -1
- package/dist/web/assets/{chunk-UBXNYLIW-BuzttTFk.js → chunk-UBXNYLIW-gyX_iwb1.js} +1 -1
- package/dist/web/assets/{chunk-W5SLKNZC-UidmFHe2.js → chunk-W5SLKNZC-BGNgHuYL.js} +1 -1
- package/dist/web/assets/{chunk-WRU74C26-nox7WFnh.js → chunk-WRU74C26-66KXN6Rn.js} +1 -1
- package/dist/web/assets/classDiagram-JCYQIIEL-DOHE4q2M.js +1 -0
- package/dist/web/assets/classDiagram-v2-OCEON4UE-DOHE4q2M.js +1 -0
- package/dist/web/assets/{cynefin-VYW2F7L2-wDMibS5s.js → cynefin-VYW2F7L2-Dj_jqvQa.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-MW4NZA55-CBTrdvOE.js → cynefinDiagram-MW4NZA55-DSnUS3JS.js} +1 -1
- package/dist/web/assets/{dagre-VZM6K2ZE-Bbgn4Rr7.js → dagre-VZM6K2ZE-BTedug-5.js} +1 -1
- package/dist/web/assets/{diagram-7IWD3JNH-Bm9AuXb9.js → diagram-7IWD3JNH-kSc1kTCk.js} +1 -1
- package/dist/web/assets/{diagram-B4RE2ZJO-D3lZ-r-H.js → diagram-B4RE2ZJO-DNtXohxd.js} +1 -1
- package/dist/web/assets/{diagram-LBJQPF4R-D-GaynX7.js → diagram-LBJQPF4R-CVD-8DKW.js} +1 -1
- package/dist/web/assets/{diagram-Q27KOJAE-BeZRiu1d.js → diagram-Q27KOJAE-DBEnUsLJ.js} +1 -1
- package/dist/web/assets/{diagram-UB23O5K3-C3GP7iMe.js → diagram-UB23O5K3-DiPHfrk7.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-BXEA7PRR-BJWg0NVU.js → ebnfDiagram-BXEA7PRR-CE06v37i.js} +1 -1
- package/dist/web/assets/{erDiagram-JOGREHBK-XPmhUeB_.js → erDiagram-JOGREHBK-jm3RTuJX.js} +1 -1
- package/dist/web/assets/eventmodeling-45OFAUF4-C344zcDl.js +1 -0
- package/dist/web/assets/flowDiagram-UKHOOZJN-BAHsb6fm.js +1 -0
- package/dist/web/assets/{ganttDiagram-PKOTCBZU-CL-xEo-M.js → ganttDiagram-PKOTCBZU--GwSY0BM.js} +1 -1
- package/dist/web/assets/{gitGraph-TEB2WS4Q-BVRyuIx3.js → gitGraph-TEB2WS4Q-C6oA29oA.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-DS77QQ5N-BVNIEupW.js → gitGraphDiagram-DS77QQ5N-DR1mGQ6a.js} +1 -1
- package/dist/web/assets/index-BiPhui1B.js +384 -0
- package/dist/web/assets/index-CHlqmhif.css +1 -0
- package/dist/web/assets/{info-DKCQHKI2-BKBUVpfc.js → info-DKCQHKI2-BT4oYSnk.js} +1 -1
- package/dist/web/assets/{infoDiagram-6WML65LV-_dTFnzSE.js → infoDiagram-6WML65LV-D0mnXRu0.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-WSZJBQD7-DIRgD4hO.js → ishikawaDiagram-WSZJBQD7-ErnJ_7Sr.js} +1 -1
- package/dist/web/assets/{journeyDiagram-NVQOT4AX-bp7nZrfR.js → journeyDiagram-NVQOT4AX-CWvooGdp.js} +1 -1
- package/dist/web/assets/{kanban-definition-27J2QSJJ-C6mZIo8S.js → kanban-definition-27J2QSJJ-DsIS6ipP.js} +1 -1
- package/dist/web/assets/{line-DWTym7eJ.js → line-DCcVjraC.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-CbecsNA1.js → mermaid-parser.core-BmDn4VB6.js} +3 -3
- package/dist/web/assets/{mermaid.core-CdRuLyYI.js → mermaid.core-Cus_gjGs.js} +4 -4
- package/dist/web/assets/{mindmap-definition-FAOFIHXS-CU2P1z-9.js → mindmap-definition-FAOFIHXS-DdsB9lmP.js} +1 -1
- package/dist/web/assets/{packet-7NZHBO7P-CZsup6Od.js → packet-7NZHBO7P-BXuujfeh.js} +1 -1
- package/dist/web/assets/{pegDiagram-VL7TDLO6-DTTyttpe.js → pegDiagram-VL7TDLO6-CBF6Uic6.js} +1 -1
- package/dist/web/assets/{pie-RZYD4A2V-DgrIiWZA.js → pie-RZYD4A2V-DgssvIaB.js} +1 -1
- package/dist/web/assets/{pieDiagram-7S7Q4E2Y-BBNFyPT1.js → pieDiagram-7S7Q4E2Y-DejhR8Wh.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-CIZ2JOQS-ejp-Aa2l.js → quadrantDiagram-CIZ2JOQS-CryFsz7r.js} +1 -1
- package/dist/web/assets/{radar-I7S5WNFK-Cp_hfjrI.js → radar-I7S5WNFK-CoiIzjHC.js} +1 -1
- package/dist/web/assets/{railroad-3IZDKUUU-Dw-oMal2.js → railroad-3IZDKUUU-CWq6IkAh.js} +1 -1
- package/dist/web/assets/railroad-abnf-AHOZXSZD-D7Iqnp88.js +1 -0
- package/dist/web/assets/railroad-ebnf-EBAXGLYW-Dp2g2TtT.js +1 -0
- package/dist/web/assets/railroad-peg-LSFZ7HO6-DTqKNJKF.js +1 -0
- package/dist/web/assets/{railroadDiagram-AXF67PYL-DkBUaj6Z.js → railroadDiagram-AXF67PYL-DkePHtcR.js} +1 -1
- package/dist/web/assets/{requirementDiagram-LRYGKXZP-Dff1ex_h.js → requirementDiagram-LRYGKXZP-D2-9KlK1.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-W5VNT64P-DptSL9Bc.js → sankeyDiagram-W5VNT64P-DSOFAzno.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-SI44F4Z6-DEnPcs3U.js → sequenceDiagram-SI44F4Z6-BHEKSYJt.js} +1 -1
- package/dist/web/assets/{stateDiagram-OKZ733FA-BwJO1MKA.js → stateDiagram-OKZ733FA-f1GttDrB.js} +1 -1
- package/dist/web/assets/stateDiagram-v2-UEYNNEHI-CEn2YfQh.js +1 -0
- package/dist/web/assets/{swimlanes-SLNWSIFB-BosKiwZA.js → swimlanes-SLNWSIFB-Dx7QlDaA.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-CX2pXGLK.js +8 -0
- package/dist/web/assets/{timeline-definition-Z64GVDOM-C5isAn4X.js → timeline-definition-Z64GVDOM-C7eeBnPC.js} +1 -1
- package/dist/web/assets/{treeView-QDETBFTQ-zEyUXRc4.js → treeView-QDETBFTQ-BPsqqMsK.js} +1 -1
- package/dist/web/assets/{treemap-6X3UGDF4-B-X0EQSE.js → treemap-6X3UGDF4-CmBU76N7.js} +1 -1
- package/dist/web/assets/{vennDiagram-T6HMQDX7-QMdGieCa.js → vennDiagram-T6HMQDX7-DTIq1ec9.js} +1 -1
- package/dist/web/assets/{wardley-OPB4EBWU-BaeAF8d8.js → wardley-OPB4EBWU-DLOnGzPl.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-T6FBY63Y-DTQ_uLUq.js → wardleyDiagram-T6FBY63Y-BmzhEoo_.js} +1 -1
- package/dist/web/assets/{xychartDiagram-ELKLHX3M-BMdBWzib.js → xychartDiagram-ELKLHX3M-CcCGC0u-.js} +1 -1
- package/dist/web/index.html +2 -2
- package/migrations/011_comment_post_modifier.sql +3 -0
- package/migrations/012_pull_request_list.sql +5 -0
- package/migrations/013_pull_request_github_status.sql +5 -0
- package/package.json +4 -1
- package/skills/rvw/SKILL.md +1 -1
- package/skills/rvw-walkthrough/SKILL.md +7 -5
- package/skills/rvw-walkthrough/references/walkthrough-authoring.md +52 -0
- package/skills/rvw-watch-comments/SKILL.md +28 -13
- package/skills/rvw-watch-comments/scripts/auto-ack.mjs +18 -2
- package/skills/rvw-watch-comments/scripts/preflight.mjs +1 -1
- package/skills/rvw-watch-comments/scripts/watch-driver.mjs +47 -17
- package/skills/rvw-watch-comments/scripts/watch-state.mjs +50 -3
- package/dist/web/assets/DocumentViewer-B4LdSL1l.js +0 -1560
- package/dist/web/assets/MarkdownTable-CdbKPft2.js +0 -7
- package/dist/web/assets/WalkthroughViewer-D1LlSQw2.js +0 -1
- package/dist/web/assets/architecture-TIHT7OUA-edLV2Zq-.js +0 -1
- package/dist/web/assets/channel-J8FHSJDG.js +0 -1
- package/dist/web/assets/classDiagram-JCYQIIEL-CmTWSnH0.js +0 -1
- package/dist/web/assets/classDiagram-v2-OCEON4UE-CmTWSnH0.js +0 -1
- package/dist/web/assets/eventmodeling-45OFAUF4-C3c4qddw.js +0 -1
- package/dist/web/assets/flowDiagram-UKHOOZJN-DMA-a1zf.js +0 -1
- package/dist/web/assets/index-D8GJBw23.js +0 -384
- package/dist/web/assets/index-DMD2vvQW.css +0 -1
- package/dist/web/assets/railroad-abnf-AHOZXSZD-BN-ZBhE0.js +0 -1
- package/dist/web/assets/railroad-ebnf-EBAXGLYW-CG97zyI2.js +0 -1
- package/dist/web/assets/railroad-peg-LSFZ7HO6-DHLQ1evQ.js +0 -1
- package/dist/web/assets/stateDiagram-v2-UEYNNEHI-LaSNqvWy.js +0 -1
- package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-C5OBtBlv.js +0 -8
|
@@ -23,6 +23,7 @@ const EXIT_AUTO_ACK = 23;
|
|
|
23
23
|
const EXIT_ALREADY_RUNNING = 24;
|
|
24
24
|
const DEFAULT_MAX_IN_FLIGHT = 1;
|
|
25
25
|
const DEFAULT_AUTO_ACK_POLL_MS = 250;
|
|
26
|
+
const MAX_AUTHOR_LABEL_CHARACTERS = 100;
|
|
26
27
|
const scriptDirectory = path.dirname(fileURLToPath(import.meta.url));
|
|
27
28
|
const stateScript = path.join(scriptDirectory, "watch-state.mjs");
|
|
28
29
|
const autoAckScript = path.join(scriptDirectory, "auto-ack.mjs");
|
|
@@ -41,6 +42,7 @@ function parseArguments(values) {
|
|
|
41
42
|
let autoAck = false;
|
|
42
43
|
let maxInFlight = DEFAULT_MAX_IN_FLIGHT;
|
|
43
44
|
let maxInFlightProvided = false;
|
|
45
|
+
let authorLabel = null;
|
|
44
46
|
for (let index = 0; index < values.length; index += 1) {
|
|
45
47
|
const value = values[index];
|
|
46
48
|
if (value === "--auto-ack") {
|
|
@@ -60,6 +62,18 @@ function parseArguments(values) {
|
|
|
60
62
|
index += 1;
|
|
61
63
|
continue;
|
|
62
64
|
}
|
|
65
|
+
if (value === "--author-label") {
|
|
66
|
+
const next = values[index + 1];
|
|
67
|
+
if (!next || next.startsWith("--") || next.length > MAX_AUTHOR_LABEL_CHARACTERS) {
|
|
68
|
+
throw new DriverError(
|
|
69
|
+
`--author-label must contain 1 through ${MAX_AUTHOR_LABEL_CHARACTERS} characters`,
|
|
70
|
+
EXIT_WATCH,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
authorLabel = next;
|
|
74
|
+
index += 1;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
63
77
|
if (value === "--state") {
|
|
64
78
|
const next = values[index + 1];
|
|
65
79
|
if (!next || next.startsWith("--")) {
|
|
@@ -79,7 +93,10 @@ function parseArguments(values) {
|
|
|
79
93
|
if (!autoAck && maxInFlightProvided) {
|
|
80
94
|
throw new DriverError("--max-in-flight requires --auto-ack", EXIT_WATCH);
|
|
81
95
|
}
|
|
82
|
-
|
|
96
|
+
if (!autoAck && authorLabel !== null) {
|
|
97
|
+
throw new DriverError("--author-label requires --auto-ack", EXIT_WATCH);
|
|
98
|
+
}
|
|
99
|
+
return { state: path.resolve(state), autoAck, maxInFlight, authorLabel };
|
|
83
100
|
}
|
|
84
101
|
|
|
85
102
|
async function runNodeScript(script, args, input) {
|
|
@@ -219,20 +236,17 @@ function releaseDriverLock(lock) {
|
|
|
219
236
|
unlinkIfOwned(lock.path, lock.identity);
|
|
220
237
|
}
|
|
221
238
|
|
|
222
|
-
async function dispatchAutoAck(state, pullRequest) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
"--pull-request",
|
|
227
|
-
pullRequest,
|
|
228
|
-
]);
|
|
239
|
+
async function dispatchAutoAck(state, pullRequest, authorLabel) {
|
|
240
|
+
const args = ["--state", state, "--pull-request", pullRequest];
|
|
241
|
+
if (authorLabel !== null) args.push("--author-label", authorLabel);
|
|
242
|
+
const result = await runNodeScript(autoAckScript, args);
|
|
229
243
|
if (result.code !== 0 || !result.json?.ok) {
|
|
230
244
|
throw new DriverError(`auto-ack failed for ${pullRequest}`, EXIT_AUTO_ACK, result);
|
|
231
245
|
}
|
|
232
246
|
write({ ...result.json, type: "batch-acknowledged" });
|
|
233
247
|
}
|
|
234
248
|
|
|
235
|
-
async function dispatchPendingAutoAcks(state, maxInFlight) {
|
|
249
|
+
async function dispatchPendingAutoAcks(state, maxInFlight, authorLabel) {
|
|
236
250
|
const work = await stateCommand(state, "list");
|
|
237
251
|
const inFlight = Number(work.inFlight);
|
|
238
252
|
if (!Number.isSafeInteger(inFlight) || inFlight < 0 || !Array.isArray(work.pending)) {
|
|
@@ -241,12 +255,26 @@ async function dispatchPendingAutoAcks(state, maxInFlight) {
|
|
|
241
255
|
let available = Math.max(0, maxInFlight - inFlight);
|
|
242
256
|
for (const batch of work.pending) {
|
|
243
257
|
if (available === 0) break;
|
|
244
|
-
await dispatchAutoAck(state, batch.pullRequest);
|
|
258
|
+
await dispatchAutoAck(state, batch.pullRequest, authorLabel);
|
|
245
259
|
available -= 1;
|
|
246
260
|
}
|
|
247
261
|
}
|
|
248
262
|
|
|
249
|
-
async function
|
|
263
|
+
async function assertTaskAuthorLabel(state, authorLabel) {
|
|
264
|
+
const current = await stateCommand(state, "status");
|
|
265
|
+
if (!current.authorLabelBound || current.authorLabel === authorLabel) return;
|
|
266
|
+
throw new DriverError(
|
|
267
|
+
`Existing task author label ${current.authorLabel ?? "(unlabeled)"} does not match ${authorLabel ?? "(unlabeled)"}`,
|
|
268
|
+
EXIT_AUTO_ACK,
|
|
269
|
+
{
|
|
270
|
+
state,
|
|
271
|
+
expectedAuthorLabel: current.authorLabel,
|
|
272
|
+
receivedAuthorLabel: authorLabel,
|
|
273
|
+
},
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async function processFrame(state, frame, autoAck, maxInFlight, authorLabel) {
|
|
250
278
|
if (!frame || typeof frame !== "object" || typeof frame.type !== "string") {
|
|
251
279
|
throw new DriverError("Invalid RFC 7464 frame", EXIT_SEQUENCE, frame);
|
|
252
280
|
}
|
|
@@ -263,6 +291,7 @@ async function processFrame(state, frame, autoAck, maxInFlight) {
|
|
|
263
291
|
anchoredAtCurrent: frame.anchoredAtCurrent,
|
|
264
292
|
autoAck,
|
|
265
293
|
maxInFlight: autoAck ? maxInFlight : null,
|
|
294
|
+
authorLabel: autoAck ? authorLabel : null,
|
|
266
295
|
});
|
|
267
296
|
} else if (frame.type === "comment-posted" && ingested.status === "queued") {
|
|
268
297
|
if (!autoAck) {
|
|
@@ -286,7 +315,7 @@ function autoAckPollMilliseconds() {
|
|
|
286
315
|
: DEFAULT_AUTO_ACK_POLL_MS;
|
|
287
316
|
}
|
|
288
317
|
|
|
289
|
-
async function runWatchOnce(state, autoAck, maxInFlight, stopping) {
|
|
318
|
+
async function runWatchOnce(state, autoAck, maxInFlight, authorLabel, stopping) {
|
|
290
319
|
const current = await stateCommand(state, "status");
|
|
291
320
|
const args = ["comment", "watch"];
|
|
292
321
|
if (current.cursor) args.push("--after", current.cursor);
|
|
@@ -309,7 +338,7 @@ async function runWatchOnce(state, autoAck, maxInFlight, stopping) {
|
|
|
309
338
|
const pumpAutoAcks = async () => {
|
|
310
339
|
if (!autoAck || stopping.requested) return;
|
|
311
340
|
if (autoAckPump) return autoAckPump;
|
|
312
|
-
autoAckPump = dispatchPendingAutoAcks(state, maxInFlight);
|
|
341
|
+
autoAckPump = dispatchPendingAutoAcks(state, maxInFlight, authorLabel);
|
|
313
342
|
try {
|
|
314
343
|
await autoAckPump;
|
|
315
344
|
} catch (error) {
|
|
@@ -345,7 +374,7 @@ async function runWatchOnce(state, autoAck, maxInFlight, stopping) {
|
|
|
345
374
|
}
|
|
346
375
|
readySeen ||= frame.type === "ready";
|
|
347
376
|
stoppedSeen ||= frame.type === "stopped";
|
|
348
|
-
await processFrame(state, frame, autoAck, maxInFlight);
|
|
377
|
+
await processFrame(state, frame, autoAck, maxInFlight, authorLabel);
|
|
349
378
|
}
|
|
350
379
|
await pumpAutoAcks();
|
|
351
380
|
}
|
|
@@ -383,9 +412,10 @@ function delay(milliseconds) {
|
|
|
383
412
|
}
|
|
384
413
|
|
|
385
414
|
async function main() {
|
|
386
|
-
const { state, autoAck, maxInFlight } = parseArguments(process.argv.slice(2));
|
|
415
|
+
const { state, autoAck, maxInFlight, authorLabel } = parseArguments(process.argv.slice(2));
|
|
387
416
|
const driverLock = acquireDriverLock(state);
|
|
388
417
|
try {
|
|
418
|
+
if (autoAck) await assertTaskAuthorLabel(state, authorLabel);
|
|
389
419
|
const stopping = { requested: false, child: null };
|
|
390
420
|
const stop = () => {
|
|
391
421
|
stopping.requested = true;
|
|
@@ -398,8 +428,8 @@ async function main() {
|
|
|
398
428
|
try {
|
|
399
429
|
while (!stopping.requested) {
|
|
400
430
|
const startedAt = Date.now();
|
|
401
|
-
if (autoAck) await dispatchPendingAutoAcks(state, maxInFlight);
|
|
402
|
-
const result = await runWatchOnce(state, autoAck, maxInFlight, stopping);
|
|
431
|
+
if (autoAck) await dispatchPendingAutoAcks(state, maxInFlight, authorLabel);
|
|
432
|
+
const result = await runWatchOnce(state, autoAck, maxInFlight, authorLabel, stopping);
|
|
403
433
|
if (stopping.requested) return;
|
|
404
434
|
if (Date.now() - startedAt >= 30_000) restarts = 0;
|
|
405
435
|
restarts += 1;
|
|
@@ -11,7 +11,7 @@ function fail(message) {
|
|
|
11
11
|
|
|
12
12
|
function parseOptions(values) {
|
|
13
13
|
const result = {};
|
|
14
|
-
const flags = new Set(["follow"]);
|
|
14
|
+
const flags = new Set(["follow", "no-author-label"]);
|
|
15
15
|
for (let index = 0; index < values.length; index += 1) {
|
|
16
16
|
const key = values[index];
|
|
17
17
|
if (!key?.startsWith("--")) fail(`Unexpected argument: ${key ?? ""}`);
|
|
@@ -152,6 +152,32 @@ function setMeta(database, key, value) {
|
|
|
152
152
|
.run(key, value);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
function taskAuthorLabel(database) {
|
|
156
|
+
const stored = getMeta(database, "author_label");
|
|
157
|
+
return stored === null || stored === "" ? null : stored;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function bindTaskAuthorLabel(database, authorLabel) {
|
|
161
|
+
if (
|
|
162
|
+
authorLabel !== null &&
|
|
163
|
+
(typeof authorLabel !== "string" || authorLabel.length === 0 || authorLabel.length > 100)
|
|
164
|
+
) {
|
|
165
|
+
fail("authorLabel must contain 1 through 100 characters or be null");
|
|
166
|
+
}
|
|
167
|
+
const encoded = authorLabel ?? "";
|
|
168
|
+
const stored = getMeta(database, "author_label");
|
|
169
|
+
if (stored === null) {
|
|
170
|
+
setMeta(database, "author_label", encoded);
|
|
171
|
+
return authorLabel;
|
|
172
|
+
}
|
|
173
|
+
if (stored !== encoded) {
|
|
174
|
+
fail(
|
|
175
|
+
`Existing task author label ${stored || "(unlabeled)"} does not match ${encoded || "(unlabeled)"}`,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return taskAuthorLabel(database);
|
|
179
|
+
}
|
|
180
|
+
|
|
155
181
|
function tableExists(database, tableName) {
|
|
156
182
|
return Boolean(
|
|
157
183
|
database
|
|
@@ -523,9 +549,13 @@ function createBatch(database, pullRequestUrl, now) {
|
|
|
523
549
|
return batchId;
|
|
524
550
|
}
|
|
525
551
|
|
|
526
|
-
function claim(database, pullRequestUrl, writeKey) {
|
|
552
|
+
function claim(database, pullRequestUrl, writeKey, requestedAuthorLabel) {
|
|
527
553
|
const canonicalWriteKey = writeKey === undefined ? undefined : normalizeWriteKey(writeKey);
|
|
528
554
|
return transaction(database, () => {
|
|
555
|
+
const authorLabel =
|
|
556
|
+
requestedAuthorLabel === undefined
|
|
557
|
+
? taskAuthorLabel(database)
|
|
558
|
+
: bindTaskAuthorLabel(database, requestedAuthorLabel);
|
|
529
559
|
const now = new Date().toISOString();
|
|
530
560
|
const ownMode = getMeta(database, "own_mode");
|
|
531
561
|
if (canonicalWriteKey !== undefined && ownMode !== "fix-and-push") {
|
|
@@ -591,6 +621,7 @@ function claim(database, pullRequestUrl, writeKey) {
|
|
|
591
621
|
pullRequest: pullRequestUrl,
|
|
592
622
|
attempts: Number(batch.attempts) + 1,
|
|
593
623
|
writeKey: canonicalWriteKey ?? null,
|
|
624
|
+
authorLabel,
|
|
594
625
|
events,
|
|
595
626
|
operations,
|
|
596
627
|
};
|
|
@@ -802,6 +833,8 @@ function status(database) {
|
|
|
802
833
|
taskId: getMeta(database, "task_id"),
|
|
803
834
|
databaseId: getMeta(database, "database_id"),
|
|
804
835
|
cursor: getMeta(database, "cursor"),
|
|
836
|
+
authorLabel: taskAuthorLabel(database),
|
|
837
|
+
authorLabelBound: getMeta(database, "author_label") !== null,
|
|
805
838
|
expectedGitHubLogin: getMeta(database, "expected_login") || null,
|
|
806
839
|
ownPullRequests: getMeta(database, "own_mode"),
|
|
807
840
|
otherPullRequests: "investigate-and-reply",
|
|
@@ -852,9 +885,23 @@ async function main() {
|
|
|
852
885
|
return;
|
|
853
886
|
}
|
|
854
887
|
if (command === "claim") {
|
|
888
|
+
if (options["author-label"] !== undefined && options["no-author-label"] === true) {
|
|
889
|
+
fail("Pass either --author-label or --no-author-label, not both");
|
|
890
|
+
}
|
|
891
|
+
const requestedAuthorLabel =
|
|
892
|
+
options["author-label"] !== undefined
|
|
893
|
+
? options["author-label"]
|
|
894
|
+
: options["no-author-label"] === true
|
|
895
|
+
? null
|
|
896
|
+
: undefined;
|
|
855
897
|
write({
|
|
856
898
|
ok: true,
|
|
857
|
-
...claim(
|
|
899
|
+
...claim(
|
|
900
|
+
database,
|
|
901
|
+
required(options, "pull-request"),
|
|
902
|
+
options["write-key"],
|
|
903
|
+
requestedAuthorLabel,
|
|
904
|
+
),
|
|
858
905
|
});
|
|
859
906
|
return;
|
|
860
907
|
}
|