co-maintainer 0.4.9 → 0.4.10
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/package.json +1 -1
- package/dist/src/cli/args.js +21 -0
- package/dist/src/config.d.ts +1 -0
- package/dist/src/github/collect.js +46 -6
- package/dist/src/services/setup.js +2 -0
- package/dist/src/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/package.json
CHANGED
package/dist/src/cli/args.js
CHANGED
|
@@ -53,6 +53,7 @@ export async function parseArgs(args) {
|
|
|
53
53
|
console.log(" --include-commit-history --include-how-repo-works");
|
|
54
54
|
console.log(" --max-commits=N --max-pr-months=N --max-pull-request-change-lines=N --max-comment=N");
|
|
55
55
|
console.log(" --only-request-changed-pr");
|
|
56
|
+
console.log(" --pr-state=open,closed,merged");
|
|
56
57
|
console.log(" --auth=gh|pat --github-pat=... --ai=none|openrouter|hetzner --token=... --low-model=... --high-model=...");
|
|
57
58
|
process.exit(0);
|
|
58
59
|
}
|
|
@@ -111,6 +112,24 @@ export async function parseArgs(args) {
|
|
|
111
112
|
: undefined;
|
|
112
113
|
};
|
|
113
114
|
const text = (name) => rest.find((item) => item.startsWith(`--${name}=`))?.slice(name.length + 3);
|
|
115
|
+
const prStateOption = (args, saved) => {
|
|
116
|
+
const prefix = "--pr-state=";
|
|
117
|
+
const raw = args
|
|
118
|
+
.find((arg) => arg.startsWith(prefix))
|
|
119
|
+
?.slice(prefix.length);
|
|
120
|
+
if (raw === undefined)
|
|
121
|
+
return saved && saved.length > 0 ? saved : undefined;
|
|
122
|
+
const allowed = ["open", "closed", "merged"];
|
|
123
|
+
const parts = raw
|
|
124
|
+
.split(",")
|
|
125
|
+
.map((part) => part.trim())
|
|
126
|
+
.filter(Boolean);
|
|
127
|
+
if (parts.length === 0 ||
|
|
128
|
+
parts.some((part) => !allowed.includes(part))) {
|
|
129
|
+
die("pr-state must be a comma-separated list of: open, closed, merged");
|
|
130
|
+
}
|
|
131
|
+
return [...new Set(parts)];
|
|
132
|
+
};
|
|
114
133
|
const choice = (name, allowed, fallback) => {
|
|
115
134
|
const prefix = `--${name}=`;
|
|
116
135
|
const raw = rest
|
|
@@ -130,6 +149,7 @@ export async function parseArgs(args) {
|
|
|
130
149
|
"max-pr-months",
|
|
131
150
|
"max-pull-request-change-lines",
|
|
132
151
|
"max-comment",
|
|
152
|
+
"pr-state",
|
|
133
153
|
"improve-matrix",
|
|
134
154
|
"env",
|
|
135
155
|
"gh-concurrent",
|
|
@@ -245,6 +265,7 @@ export async function parseArgs(args) {
|
|
|
245
265
|
includeHowRepoWorks: enabled("include-how-repo-works"),
|
|
246
266
|
onlyRequestChangedPr: rest.includes("--only-request-changed-pr") ||
|
|
247
267
|
repoConfig.onlyRequestChangedPr === true,
|
|
268
|
+
prState: prStateOption(rest, repoConfig.prState),
|
|
248
269
|
maxCommits: value("max-commits") ?? repoConfig.maxCommits ?? configDefault.maxCommits,
|
|
249
270
|
maxPrMonths: value("max-pr-months") ??
|
|
250
271
|
repoConfig.maxPrMonths ??
|
package/dist/src/config.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type RepoConfig = {
|
|
|
18
18
|
includeCommitHistory?: boolean;
|
|
19
19
|
includeHowRepoWorks?: boolean;
|
|
20
20
|
onlyRequestChangedPr?: boolean;
|
|
21
|
+
prState?: ("open" | "closed" | "merged")[];
|
|
21
22
|
/** Five field cron in UTC, checked by `serve` to queue a remake. */
|
|
22
23
|
remakeCron?: string;
|
|
23
24
|
};
|
|
@@ -30,6 +30,36 @@ function listingCovers(cachedMonths, current) {
|
|
|
30
30
|
return false;
|
|
31
31
|
return cachedMonths >= current;
|
|
32
32
|
}
|
|
33
|
+
function stateKey(states) {
|
|
34
|
+
if (!states || states.length === 0)
|
|
35
|
+
return "";
|
|
36
|
+
return [...states].sort().join(",");
|
|
37
|
+
}
|
|
38
|
+
/** `closed` is closed and not merged. GitHub's list has no merged state. */
|
|
39
|
+
function matchesPrState(pr, states) {
|
|
40
|
+
if (!states || states.length === 0)
|
|
41
|
+
return true;
|
|
42
|
+
const merged = Boolean(pr.merged_at);
|
|
43
|
+
const state = String(pr.state ?? "");
|
|
44
|
+
return states.some((wanted) => {
|
|
45
|
+
if (wanted === "merged")
|
|
46
|
+
return merged;
|
|
47
|
+
if (wanted === "open")
|
|
48
|
+
return state === "open";
|
|
49
|
+
return state === "closed" && !merged;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function listQueryState(states) {
|
|
53
|
+
if (!states || states.length === 0)
|
|
54
|
+
return "all";
|
|
55
|
+
const wantsOpen = states.includes("open");
|
|
56
|
+
const wantsClosed = states.includes("closed") || states.includes("merged");
|
|
57
|
+
if (wantsOpen && wantsClosed)
|
|
58
|
+
return "all";
|
|
59
|
+
if (wantsOpen)
|
|
60
|
+
return "open";
|
|
61
|
+
return "closed";
|
|
62
|
+
}
|
|
33
63
|
async function loadListing(repo) {
|
|
34
64
|
const raw = await cacheGet("pr-listing", repo);
|
|
35
65
|
if (!raw)
|
|
@@ -39,20 +69,26 @@ async function loadListing(repo) {
|
|
|
39
69
|
return undefined;
|
|
40
70
|
return parsed;
|
|
41
71
|
}
|
|
42
|
-
async function saveListing(repo, maxPrMonths, items) {
|
|
43
|
-
await cacheSet("pr-listing", repo, JSON.stringify({
|
|
72
|
+
async function saveListing(repo, maxPrMonths, states, items) {
|
|
73
|
+
await cacheSet("pr-listing", repo, JSON.stringify({
|
|
74
|
+
maxPrMonths: maxPrMonths ?? 0,
|
|
75
|
+
states: stateKey(states),
|
|
76
|
+
items,
|
|
77
|
+
}));
|
|
44
78
|
}
|
|
45
79
|
async function listPullRequestPages(client, options, phase) {
|
|
46
80
|
const cached = await loadListing(options.repo);
|
|
47
81
|
const canCatchUp = cached !== undefined &&
|
|
48
|
-
listingCovers(cached.maxPrMonths, options.maxPrMonths)
|
|
82
|
+
listingCovers(cached.maxPrMonths, options.maxPrMonths) &&
|
|
83
|
+
(cached.states ?? "") === stateKey(options.prState);
|
|
49
84
|
const cachedByNumber = new Map((cached?.items ?? []).map((pr) => [Number(pr.number), pr]));
|
|
50
85
|
const selected = [];
|
|
51
86
|
const seen = new Set();
|
|
52
87
|
const concurrency = Math.max(1, options.ghConcurrent);
|
|
53
|
-
|
|
88
|
+
const states = stateKey(options.prState) || "all";
|
|
89
|
+
log("fetch", `pull request listing · ${states} · concurrency=${concurrency}`);
|
|
54
90
|
const fetchPage = async (page) => {
|
|
55
|
-
const pageItems = await client.request(`repos/${options.repo}/pulls?state
|
|
91
|
+
const pageItems = await client.request(`repos/${options.repo}/pulls?state=${listQueryState(options.prState)}&sort=updated&direction=desc&per_page=100&page=${page}`);
|
|
56
92
|
return Array.isArray(pageItems) ? pageItems : [];
|
|
57
93
|
};
|
|
58
94
|
const ingest = (page, pageItems) => {
|
|
@@ -72,6 +108,8 @@ async function listPullRequestPages(client, options, phase) {
|
|
|
72
108
|
reason = "window reached";
|
|
73
109
|
break;
|
|
74
110
|
}
|
|
111
|
+
if (!matchesPrState(pr, options.prState))
|
|
112
|
+
continue;
|
|
75
113
|
const number = Number(pr.number);
|
|
76
114
|
selected.push(pr);
|
|
77
115
|
seen.add(number);
|
|
@@ -111,6 +149,8 @@ async function listPullRequestPages(client, options, phase) {
|
|
|
111
149
|
if (!withinPrWindow(String(pr.updated_at ?? ""), options.maxPrMonths)) {
|
|
112
150
|
continue;
|
|
113
151
|
}
|
|
152
|
+
if (!matchesPrState(pr, options.prState))
|
|
153
|
+
continue;
|
|
114
154
|
selected.push(pr);
|
|
115
155
|
seen.add(number);
|
|
116
156
|
reused++;
|
|
@@ -119,7 +159,7 @@ async function listPullRequestPages(client, options, phase) {
|
|
|
119
159
|
log("fetch", `pull request listing · reused ${reused} cached PRs · ${selected.length} total`);
|
|
120
160
|
}
|
|
121
161
|
}
|
|
122
|
-
await saveListing(options.repo, options.maxPrMonths, selected);
|
|
162
|
+
await saveListing(options.repo, options.maxPrMonths, options.prState, selected);
|
|
123
163
|
return selected;
|
|
124
164
|
}
|
|
125
165
|
async function mapPool(items, concurrency, fn) {
|
|
@@ -260,6 +260,7 @@ export async function runInitOrRemake(options) {
|
|
|
260
260
|
includeCommitHistory: options.includeCommitHistory,
|
|
261
261
|
includeHowRepoWorks: options.includeHowRepoWorks,
|
|
262
262
|
onlyRequestChangedPr: options.onlyRequestChangedPr,
|
|
263
|
+
prState: options.prState,
|
|
263
264
|
});
|
|
264
265
|
});
|
|
265
266
|
log("write", `${path} · ${result.changed.length
|
|
@@ -308,6 +309,7 @@ export function optionsFromConfig(repo, command) {
|
|
|
308
309
|
includeCommitHistory: repoConfig.includeCommitHistory ?? true,
|
|
309
310
|
includeHowRepoWorks: repoConfig.includeHowRepoWorks ?? true,
|
|
310
311
|
onlyRequestChangedPr: repoConfig.onlyRequestChangedPr === true,
|
|
312
|
+
prState: repoConfig.prState,
|
|
311
313
|
maxCommits: repoConfig.maxCommits ?? config.defaults?.maxCommits,
|
|
312
314
|
maxPrMonths: repoConfig.maxPrMonths ?? config.defaults?.maxPrMonths,
|
|
313
315
|
maxPullRequestChangeLines: repoConfig.maxPullRequestChangeLines ??
|
package/dist/src/types.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export type Options = {
|
|
|
37
37
|
/** Keep only pull requests in the window that have at least one
|
|
38
38
|
* `CHANGES_REQUESTED` review. Off by default, so the window is unchanged. */
|
|
39
39
|
onlyRequestChangedPr: boolean;
|
|
40
|
+
/** Empty or omitted means every state. `closed` is closed and not merged. */
|
|
41
|
+
prState?: ("open" | "closed" | "merged")[];
|
|
40
42
|
maxCommits?: number;
|
|
41
43
|
maxPrMonths?: number;
|
|
42
44
|
maxPullRequestChangeLines?: number;
|