feat: add pr edit, close, and reopen (task 0011)
Add the PR-side state mutations mirroring the issue-side slice: - `pr edit` applies title/body/base/milestone and the recomputed assignee list in one PATCH, with additive label endpoints and (per the ADR 0007 amendment) the dedicated requested-reviewers POST/DELETE endpoints for `--add-reviewer`/`--remove-reviewer`. - `pr close --comment` posts the comment after the PATCH and surfaces a comment-post failure; an already-closed or merged PR is an `already: true` no-op reporting the actual state. - `pr reopen` is an `already: true` no-op when already open. Extract the fetch-then-patch assignee merge into a shared `src/assignees.ts` (`mergeAssignees` + `assigneeLogins`), now used by both `issue edit` and `pr edit`.
This commit was merged in pull request #11.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { Comment, CreateIssueOption, EditIssueOption, Issue, IssueMeta } from "gitea-js";
|
||||
import { assigneeLogins, mergeAssignees } from "../assignees.js";
|
||||
import { BODY_TRUNCATE_LIMIT, truncateBody } from "../body.js";
|
||||
import { requireBodySource, resolveBodySource } from "../body-source.js";
|
||||
import { createClient, type GiteaClient } from "../client.js";
|
||||
@@ -702,9 +703,9 @@ async function issueComment(deps: CliDeps, args: string[]): Promise<string> {
|
||||
|
||||
/**
|
||||
* The assignee list to PATCH: the issue's current assignees with the requested
|
||||
* additions appended and removals dropped (fetch-then-patch, ADR 0007). Matching
|
||||
* is case-insensitive and the result is de-duplicated, order-preserving, so a
|
||||
* login that is already assigned never lands in the list twice.
|
||||
* additions applied and removals dropped (fetch-then-patch, ADR 0007). The
|
||||
* current logins are read off a fresh GET, then merged by the shared
|
||||
* {@link mergeAssignees}.
|
||||
*/
|
||||
async function resolveAssignees(
|
||||
api: GiteaClient,
|
||||
@@ -714,26 +715,7 @@ async function resolveAssignees(
|
||||
remove: string[],
|
||||
): Promise<string[]> {
|
||||
const issue = await getIssue(api, context, number);
|
||||
const removeSet = new Set(remove.map((login) => login.toLowerCase()));
|
||||
const seen = new Set<string>();
|
||||
const result: string[] = [];
|
||||
const push = (login: string): void => {
|
||||
const key = login.toLowerCase();
|
||||
if (removeSet.has(key) || seen.has(key)) {
|
||||
return;
|
||||
}
|
||||
seen.add(key);
|
||||
result.push(login);
|
||||
};
|
||||
for (const assignee of issue.assignees ?? []) {
|
||||
if (assignee.login) {
|
||||
push(assignee.login);
|
||||
}
|
||||
}
|
||||
for (const login of add) {
|
||||
push(login);
|
||||
}
|
||||
return result;
|
||||
return mergeAssignees(assigneeLogins(issue.assignees), add, remove);
|
||||
}
|
||||
|
||||
async function issueEdit(deps: CliDeps, args: string[]): Promise<string> {
|
||||
|
||||
Reference in New Issue
Block a user