Public: anyone can read this; the crew can change it.

A pull's re-check and conflict sentences live in one module, read by the pull page, conflicts and the terminal #5629

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

mason/forge:mason/5620-a-pull-s-re-check-and-conflict-sentences → main 2 commits fork

  • Merged. mason/5620-a-pull-s-re-check-and-conflict-sentences was merged into main as 0ec2145.

Review

Sign in to review this change.
6 files changed +52 −4
src/actions/pull_ask_words.ts added +11
@@ -0,0 +1,11 @@
1 /**
2 * What a person is told after asking something of a pull (#5620): a check at
3 * its head, or the crew's resolution of its conflicts. Said the same on the
4 * pull page, the conflicts page and the terminal, from here.
5 */
6
7 /** A check was asked for at the pull's head. */
8 export const CHECK_ASKED = "Check asked for at the current head.";
9
10 /** The crew was asked to resolve the pull's conflicts. */
11 export const RESOLUTION_ASKED = "Asked: the crew is resolving it on the pull's own branch.";
src/tui/screens/pull.ts +2 −1
@@ -109,6 +109,7 @@ import { assignPicker, assignedText } from "./assign.ts";
109109 import { DiffView, type DiffAnchor, type DiffNote } from "./commits.ts";
110110 import { liveBindings, liveKey } from "./mirror.ts";
111111 import { pullConflicts } from "../../actions/conflicts.ts";
112 import { RESOLUTION_ASKED } from "../../actions/pull_ask_words.ts";
112113 import { FINISH_REFUSALS, finishConflicts } from "../../actions/finish-conflicts.ts";
113114 import { PROPOSE_WHY, proposalOf, proposeResolution } from "../../crew/proposal.ts";
114115 import { conflictScreen } from "./conflicts.ts";
@@ -737,7 +738,7 @@ export function pullScreen(
737738 const fresh = getPull(f.db, target.id, number) ?? row;
738739 const made = await proposeResolution(f.app, f.user, target, fresh);
739740 return made.ok
740 ? { ok: true, message: "Asked: the crew is resolving it on the pull's own branch." }
741 ? { ok: true, message: RESOLUTION_ASKED }
741742 : { ok: false, message: PROPOSE_WHY[made.error] };
742743 },
743744 }),
src/tui/screens/stalled.ts +2 −1
@@ -6,6 +6,7 @@
66 * step under the cursor; the list is live, and a step that moves on leaves it.
77 */
88
9 import { CHECK_ASKED } from "../../actions/pull_ask_words.ts";
910 import { readStalled, type StalledStep } from "../../flow/stalled.ts";
1011 import { unblock } from "../../flow/unblock.ts";
1112 import type { Ctx, Screen } from "../app/app.ts";
@@ -37,7 +38,7 @@ export function stalledScreen(f: Session, ctx: Ctx): Screen {
3738 if (step === undefined || user === undefined) return;
3839 runAsync(ctx, async () => {
3940 const done = await unblock(f.app, user, step);
40 ctx.toast(done.ok ? "Check asked for at the current head." : done.message, done.ok ? "default" : "danger");
41 ctx.toast(done.ok ? CHECK_ASKED : done.message, done.ok ? "default" : "danger");
4142 reload();
4243 });
4344 };
src/web/pages/conflicts.ts +2 −1
@@ -28,6 +28,7 @@ import { notePhase, takeSessionTime, timePhase, timePhaseAsync } from "../../cor
2828 import type { Ctx } from "../../http/context.ts";
2929 import { crumbsFor, notFoundPage, repoBase, repoPalette, repoHeader } from "../chrome.ts";
3030 import { FINISH_REFUSALS, finishConflicts } from "../../actions/finish-conflicts.ts";
31 import { RESOLUTION_ASKED } from "../../actions/pull_ask_words.ts";
3132 import { field, readForm } from "../form.ts";
3233 import { html, type Html } from "../html.ts";
3334 import { flashTo, page } from "../layout.ts";
@@ -78,7 +79,7 @@ export async function proposeSubmit(ctx: Ctx): Promise<Response> {
7879 const made = await proposeResolution(ctx.app, ctx.auth.user, repo, pull);
7980 if (!made.ok) return flashTo(ctx, dest, { tone: "danger", message: PROPOSE_WHY[made.error] });
8081 return flashTo(ctx, dest, {
81 message: "Asked: the crew is resolving it on the pull's own branch.",
82 message: RESOLUTION_ASKED,
8283 });
8384 }
8485
src/web/pages/pull.ts +2 −1
@@ -21,6 +21,7 @@ import {
2121 submitReview,
2222 approveToRun,
2323 } from "../../actions/pulls.ts";
24 import { CHECK_ASKED } from "../../actions/pull_ask_words.ts";
2425 import { reviewWords } from "../../actions/review_words.ts";
2526 import { readFileAt } from "../../apps/checkout.ts";
2627 import { parseCheck } from "../../apps/manifest.ts";
@@ -1291,7 +1292,7 @@ export async function pullChecksSubmit(ctx: Ctx): Promise<Response> {
12911292 ctx,
12921293 dest,
12931294 asked.ok
1294 ? { message: "Check asked for at the current head." }
1295 ? { message: CHECK_ASKED }
12951296 : { tone: "danger", message: `No check was asked for: ${asked.message}.` },
12961297 );
12971298 }
test/pull-ask-words.test.ts added +33
@@ -0,0 +1,33 @@
1 /**
2 * A pull's re-check and conflict sentences are said from one module
3 * (#5620): the pull page, the conflicts page and the terminal import them,
4 * and none of them types a copy back.
5 */
6
7 import { expect, test } from "bun:test";
8 import { readFileSync } from "node:fs";
9 import { join } from "node:path";
10 import { CHECK_ASKED, RESOLUTION_ASKED } from "../src/actions/pull_ask_words.ts";
11
12 const ROOT = join(import.meta.dir, "..");
13 const READERS = [
14 "src/web/pages/pull.ts",
15 "src/web/pages/conflicts.ts",
16 "src/tui/screens/stalled.ts",
17 "src/tui/screens/pull.ts",
18 ];
19
20 test("the sentences read as they always have", () => {
21 expect(CHECK_ASKED).toBe("Check asked for at the current head.");
22 expect(RESOLUTION_ASKED).toBe("Asked: the crew is resolving it on the pull's own branch.");
23 });
24
25 test("every reader imports the module and types no copy of a sentence", () => {
26 for (const path of READERS) {
27 const text = readFileSync(join(ROOT, path), "utf8");
28 expect(text).toContain("actions/pull_ask_words.ts");
29 for (const sentence of [CHECK_ASKED, RESOLUTION_ASKED]) {
30 expect({ path, has: text.includes(sentence) }).toEqual({ path, has: false });
31 }
32 }
33 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs