@popoverai/dotrequirements 0.39.0 → 0.39.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/dist/commands/solution/author.js +14 -2
- package/dist/commands/solution/checkout.js +1 -0
- package/dist/commands/solution/index.js +1 -1
- package/dist/commands/solution/own-changes.d.ts +22 -0
- package/dist/commands/solution/own-changes.js +78 -0
- package/dist/commands/solution/pull-request.d.ts +5 -1
- package/dist/commands/solution/pull-request.js +8 -3
- package/dist/commands/solution/pushing.d.ts +1 -0
- package/dist/commands/solution/pushing.js +4 -0
- package/dist/commands/solution/stall.js +1 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { api } from "../../convex.js";
|
|
|
4
4
|
import { currentBranch, headCommit, repositoryRoot } from "./branch.js";
|
|
5
5
|
import { solutionClient } from "./client.js";
|
|
6
6
|
import { readImage, uploadImage } from "./image.js";
|
|
7
|
+
import { ownChangesOf } from "./own-changes.js";
|
|
7
8
|
import { screenshotPreview } from "./preview-screenshot.js";
|
|
8
9
|
import { checkPullRequest } from "./pull-request.js";
|
|
9
10
|
import { pushBeforeRecord, refuseUncommitted } from "./pushing.js";
|
|
@@ -76,6 +77,12 @@ export async function authorCommand(references, options) {
|
|
|
76
77
|
// SOLDOC-12.2.0: a file from the checkout's own branch keeps the commit
|
|
77
78
|
// it was submitted at, so the page can tell when it changes after.
|
|
78
79
|
const commit = checkout ? headCommit(cwd) : null;
|
|
80
|
+
// CHECKPOINT-12.4 to 12.6: what the pull request would merge, taken after
|
|
81
|
+
// the push, so the checkpoint can tell a branch brought up to date from
|
|
82
|
+
// changed code. Without one, as when the fetch fails, the work is
|
|
83
|
+
// recorded all the same and reads as changed.
|
|
84
|
+
const merging = [...pullRequests.values()].find((made) => made.base);
|
|
85
|
+
const ownChanges = checkout && merging?.base ? ownChangesOf(cwd, merging.base) : null;
|
|
79
86
|
/** A reference as it is submitted: where the thing is, as the backend keeps it. */
|
|
80
87
|
const submissionOf = async (thing) => {
|
|
81
88
|
const recording = videos.get(thing);
|
|
@@ -99,8 +106,12 @@ export async function authorCommand(references, options) {
|
|
|
99
106
|
return { kind: "image", storageId, name: image.name };
|
|
100
107
|
}
|
|
101
108
|
const pullRequest = pullRequests.get(thing);
|
|
102
|
-
if (pullRequest)
|
|
103
|
-
|
|
109
|
+
if (pullRequest) {
|
|
110
|
+
// The branch it merges into is the CLI's, for `ownChanges`; the
|
|
111
|
+
// backend keeps the pull request by its number and address.
|
|
112
|
+
const { base: _base, ...kept } = pullRequest;
|
|
113
|
+
return { kind: "pull request", ...kept };
|
|
114
|
+
}
|
|
104
115
|
if (thing.kind === "preview") {
|
|
105
116
|
// SIGHT-12.0, 12.2: a screenshot of the page it opens on, kept as an
|
|
106
117
|
// image is; without one, it is submitted all the same.
|
|
@@ -141,6 +152,7 @@ export async function authorCommand(references, options) {
|
|
|
141
152
|
comment,
|
|
142
153
|
...(summary ? { summary } : {}),
|
|
143
154
|
...(files.length ? { files } : {}),
|
|
155
|
+
...(ownChanges ? { ownChanges } : {}),
|
|
144
156
|
};
|
|
145
157
|
const result = await client.mutation(api.solutions.mutations.complete, args);
|
|
146
158
|
const saved = result?.saved ?? [];
|
|
@@ -48,6 +48,7 @@ export async function pushCommand(options) {
|
|
|
48
48
|
? await pushWork(solutionClient(), {
|
|
49
49
|
solutionId: where.solutionId,
|
|
50
50
|
branch: where.branch,
|
|
51
|
+
...(where.agent ? { agent: where.agent } : {}),
|
|
51
52
|
})
|
|
52
53
|
: { ok: true, pushed: false };
|
|
53
54
|
const result = outcome.ok
|
|
@@ -220,7 +220,7 @@ export function registerSolution(program) {
|
|
|
220
220
|
whereOptions(solution
|
|
221
221
|
.command("author <reference...>", HIDDEN)
|
|
222
222
|
.description("Record what you made, and what changed and why"))
|
|
223
|
-
.option("--comment <text>", "What changed and why: the next reader sees it first (required)")
|
|
223
|
+
.option("--comment <text>", "What changed and why: the next reader sees it first, so open on a sentence that stands on its own and says what changed (required)")
|
|
224
224
|
.option("--executive-summary <text>", "For the owner, when your work moves on before anyone reviews it (required there)")
|
|
225
225
|
.option("--summary <text>", "Short for --executive-summary")
|
|
226
226
|
.option("--title <text>", "A reference's name on the outcome's tab, for the owner: one per reference, in the order the references are given, or none", (value, previous = []) => [...previous, value])
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pull request's own changes, fingerprinted from the checkout: what it
|
|
3
|
+
* would merge into `base`, as `git patch-id` sees it (CHECKPOINT-12.4 to
|
|
4
|
+
* 12.6). Merging a newer `base` in, or rebasing onto it, leaves the
|
|
5
|
+
* fingerprint as it was; resolving a conflict, a whitespace change or a new
|
|
6
|
+
* commit of the branch's own gives a new one.
|
|
7
|
+
*
|
|
8
|
+
* `--verbatim` keeps whitespace, and `-U0` drops the context lines and
|
|
9
|
+
* leaves line numbers only in the hunk headers, which `patch-id` ignores, so
|
|
10
|
+
* what moved under the change doesn't count as changing it. The cost, an
|
|
11
|
+
* accepted limit (12.4.0): a fix that only moves the branch's own lines
|
|
12
|
+
* elsewhere in the same file keeps the fingerprint too.
|
|
13
|
+
*
|
|
14
|
+
* Null when any step fails, the fetch included: the work is then recorded
|
|
15
|
+
* without one, and the checkpoint counts the pull request as changed
|
|
16
|
+
* (12.6). Never throws.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ownChangesOf(cwd: string, base: string): {
|
|
19
|
+
commit: string;
|
|
20
|
+
patchId: string;
|
|
21
|
+
} | null;
|
|
22
|
+
//# sourceMappingURL=own-changes.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* The pull request's own changes, fingerprinted from the checkout: what it
|
|
4
|
+
* would merge into `base`, as `git patch-id` sees it (CHECKPOINT-12.4 to
|
|
5
|
+
* 12.6). Merging a newer `base` in, or rebasing onto it, leaves the
|
|
6
|
+
* fingerprint as it was; resolving a conflict, a whitespace change or a new
|
|
7
|
+
* commit of the branch's own gives a new one.
|
|
8
|
+
*
|
|
9
|
+
* `--verbatim` keeps whitespace, and `-U0` drops the context lines and
|
|
10
|
+
* leaves line numbers only in the hunk headers, which `patch-id` ignores, so
|
|
11
|
+
* what moved under the change doesn't count as changing it. The cost, an
|
|
12
|
+
* accepted limit (12.4.0): a fix that only moves the branch's own lines
|
|
13
|
+
* elsewhere in the same file keeps the fingerprint too.
|
|
14
|
+
*
|
|
15
|
+
* Null when any step fails, the fetch included: the work is then recorded
|
|
16
|
+
* without one, and the checkpoint counts the pull request as changed
|
|
17
|
+
* (12.6). Never throws.
|
|
18
|
+
*/
|
|
19
|
+
export function ownChangesOf(cwd, base) {
|
|
20
|
+
try {
|
|
21
|
+
// The base as the repository has it now: an older one would put its
|
|
22
|
+
// newer commits, merged into the branch, among the branch's own.
|
|
23
|
+
const fetched = run(cwd, [
|
|
24
|
+
"fetch",
|
|
25
|
+
"--quiet",
|
|
26
|
+
"origin",
|
|
27
|
+
`+refs/heads/${base}:refs/remotes/origin/${base}`,
|
|
28
|
+
]);
|
|
29
|
+
if (!fetched)
|
|
30
|
+
return null;
|
|
31
|
+
const commit = text(run(cwd, ["rev-parse", "--verify", "--quiet", "HEAD"]));
|
|
32
|
+
if (!commit)
|
|
33
|
+
return null;
|
|
34
|
+
const mergeBase = text(run(cwd, ["merge-base", "HEAD", `refs/remotes/origin/${base}`]));
|
|
35
|
+
if (!mergeBase)
|
|
36
|
+
return null;
|
|
37
|
+
const diff = run(cwd, [
|
|
38
|
+
"diff",
|
|
39
|
+
"--no-ext-diff",
|
|
40
|
+
"--no-textconv",
|
|
41
|
+
"--no-color",
|
|
42
|
+
"--binary",
|
|
43
|
+
"-U0",
|
|
44
|
+
mergeBase,
|
|
45
|
+
commit,
|
|
46
|
+
]);
|
|
47
|
+
if (!diff)
|
|
48
|
+
return null;
|
|
49
|
+
// `patch-id` prints nothing for an empty diff.
|
|
50
|
+
if (diff.length === 0)
|
|
51
|
+
return { commit, patchId: "empty" };
|
|
52
|
+
const id = run(cwd, ["patch-id", "--verbatim"], diff);
|
|
53
|
+
if (!id)
|
|
54
|
+
return null;
|
|
55
|
+
// A diff it gives no id for, as one only changing a file's mode, can't
|
|
56
|
+
// be told from another: no fingerprint.
|
|
57
|
+
const patchId = text(id)?.split(/\s+/)[0];
|
|
58
|
+
return patchId ? { commit, patchId } : null;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Git's stdout, as bytes, or null when it failed. */
|
|
65
|
+
function run(cwd, args, input) {
|
|
66
|
+
const ran = spawnSync("git", args, {
|
|
67
|
+
cwd,
|
|
68
|
+
input,
|
|
69
|
+
maxBuffer: 1024 * 1024 * 1024,
|
|
70
|
+
// A fetch that wants a password fails rather than waiting for one.
|
|
71
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
|
|
72
|
+
});
|
|
73
|
+
return ran.status === 0 && !ran.error ? ran.stdout : null;
|
|
74
|
+
}
|
|
75
|
+
function text(out) {
|
|
76
|
+
return out?.toString("utf8").trim() || null;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=own-changes.js.map
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { type Where, type WhereOptions } from "./run-file.js";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* The solution's pull request: its number and where it opens, and, when
|
|
4
|
+
* checked by its number, the branch it merges into (CHECKPOINT-12.4).
|
|
5
|
+
*/
|
|
3
6
|
export type PullRequest = {
|
|
4
7
|
url: string;
|
|
5
8
|
number: number;
|
|
9
|
+
base?: string;
|
|
6
10
|
};
|
|
7
11
|
/** The command that opens the solution's pull request and prints its reference. */
|
|
8
12
|
export declare const OPEN_IT = "dotreq solution pr open";
|
|
@@ -20,6 +20,7 @@ export async function pullRequestCommand(options) {
|
|
|
20
20
|
const pushed = await pushWork(solutionClient(), {
|
|
21
21
|
solutionId: where.solutionId,
|
|
22
22
|
branch: where.branch,
|
|
23
|
+
agent: where.agent,
|
|
23
24
|
});
|
|
24
25
|
if (!pushed.ok) {
|
|
25
26
|
throw new Error(pushed.tell
|
|
@@ -91,9 +92,13 @@ export async function checkPullRequest(where, number) {
|
|
|
91
92
|
return pullRequest;
|
|
92
93
|
}
|
|
93
94
|
function pullRequestIn(said) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
if (!said.url || typeof said.number !== "number")
|
|
96
|
+
return null;
|
|
97
|
+
return {
|
|
98
|
+
url: said.url,
|
|
99
|
+
number: said.number,
|
|
100
|
+
...(typeof said.base === "string" && said.base ? { base: said.base } : {}),
|
|
101
|
+
};
|
|
97
102
|
}
|
|
98
103
|
/**
|
|
99
104
|
* Ask the app's pull-request route, on the project's credentials: with the
|
|
@@ -35,6 +35,7 @@ export type PushOutcome = {
|
|
|
35
35
|
export declare function pushWork(client: Client, where: {
|
|
36
36
|
solutionId: string;
|
|
37
37
|
branch: string;
|
|
38
|
+
agent?: string;
|
|
38
39
|
}, cwd?: string): Promise<PushOutcome>;
|
|
39
40
|
/** Push before a record, or refuse it with what the agent is to do (SOLBRANCH-3). */
|
|
40
41
|
export declare function pushBeforeRecord(client: Client, where: Where): Promise<void>;
|
|
@@ -26,6 +26,9 @@ export async function pushWork(client, where, cwd = process.cwd()) {
|
|
|
26
26
|
branch,
|
|
27
27
|
before: pushed.before,
|
|
28
28
|
after: pushed.after,
|
|
29
|
+
// Which agent pushed, so the solution's agent is told of others'
|
|
30
|
+
// pushes since its last turn (SOLBRANCH-2.4.0).
|
|
31
|
+
...(where.agent ? { agent: where.agent } : {}),
|
|
29
32
|
});
|
|
30
33
|
return { ok: true, pushed: true };
|
|
31
34
|
case "nothing to push":
|
|
@@ -83,6 +86,7 @@ export async function pushBeforeRecord(client, where) {
|
|
|
83
86
|
const outcome = await pushWork(client, {
|
|
84
87
|
solutionId: where.solutionId,
|
|
85
88
|
branch: where.branch,
|
|
89
|
+
agent: where.agent,
|
|
86
90
|
});
|
|
87
91
|
if (!outcome.ok)
|
|
88
92
|
throw new Error(outcome.tell);
|
package/package.json
CHANGED