Documentation
¶
Overview ¶
Package forge binds a forge's CLI, gh or glab. Every call goes through Host, so each CLI's spelling is picked in one place and its JSON read into one shape per noun; a non-zero exit is the CLI's own stderr verbatim, since it names the cause better than any paraphrase.
Index ¶
- Constants
- Variables
- func DecodePages[T any](ctx context.Context, h Host, path string) ([]T, error)
- func SameLogin(declared, login string) bool
- func Status(state string) string
- type Activity
- type CI
- type Comment
- type CommitStatus
- type Event
- type ForcePush
- type Host
- func (h Host) Activity(ctx context.Context, since time.Time) (Activity, error)
- func (h Host) At(dir string) Host
- func (h Host) Branches(ctx context.Context) (map[string]bool, error)
- func (h Host) CommitCI(ctx context.Context, sha string) (*CI, error)
- func (h Host) CreatePull(ctx context.Context, n NewPull) error
- func (h Host) Decode(ctx context.Context, v any, args ...string) error
- func (h Host) DefaultBranchName(ctx context.Context) (string, error)
- func (h Host) EarlierRequests(ctx context.Context, ids []string) (map[string][]PR, error)
- func (h Host) EditPull(ctx context.Context, selector, title, body string) error
- func (h Host) GLab() bool
- func (h Host) LatestStatus(ctx context.Context, sha, name string) (*CommitStatus, error)
- func (h Host) Login(ctx context.Context) (string, error)
- func (h Host) MRForcePushes(ctx context.Context, iid int, since time.Time) ([]ForcePush, error)
- func (h Host) MRReviews(ctx context.Context, iid int) ([]Review, error)
- func (h Host) PRForcePushes(ctx context.Context, number int, login string) ([]ForcePush, error)
- func (h Host) Pick(gh, glab []string) []string
- func (h Host) PostComment(ctx context.Context, number int, webURL, thread, body string) (string, error)
- func (h Host) PullComments(ctx context.Context, number int) ([]Comment, error)
- func (h Host) PullCommits(ctx context.Context, number int) ([]PRCommit, error)
- func (h Host) PullDiff(ctx context.Context, number int) (string, error)
- func (h Host) Pulls(ctx context.Context, login string, since time.Time) ([]PR, error)
- func (h Host) PullsByHead(ctx context.Context, branch string) ([]PR, error)
- func (h Host) PullsSince(ctx context.Context, since time.Time) ([]PR, error)
- func (h Host) Run(ctx context.Context, args ...string) (string, error)
- func (h Host) SearchPRs(ctx context.Context, query, fields string) ([]PR, error)
- func (h Host) SetStatus(ctx context.Context, sha string, s CommitStatus) error
- func (h Host) Thread(ctx context.Context, number int, threadURL string) (string, error)
- func (h Host) ThreadComments(ctx context.Context, number int, webURL, thread string) ([]Posted, error)
- type NewPull
- type PR
- type PRCommit
- type Posted
- type Review
- type Touched
Constants ¶
const ( EventOpened = "opened" EventReady = "ready" // out of draft EventCommit = "commit" EventMergeFromBase = "merge-from-base" // a commit with more than one parent EventForcePush = "force-push" EventReview = "review" EventReviewRequested = "review-requested" EventMerged = "merged" EventClosed = "closed" )
What happened to a request in a window, one kind per event. Opened is read off the request's creation time; the rest are timeline events.
const ( Open = "open" Merged = "merged" Closed = "closed" )
The three states a request can be in, whichever CLI spelled them.
const ( OwnFields = "number,title,state,isDraft,headRefName,baseRefName,url,author,createdAt,mergedAt,changedFiles,mergeCommit" ForeignFields = "number,title,state,url,author,mergedAt,mergedBy" BoardFields = "number,title,state,isDraft,headRefName,baseRefName,headRefOid,url,author,assignees," + "reviewRequests,reviews,reviewDecision,mergeable,mergeStateStatus,statusCheckRollup," + "createdAt,updatedAt,mergedAt,mergedBy,closedAt,body,mergeCommit" )
The gh field sets: a person's own requests, other people's, and what a board wants to know about every request.
const ( Approved = "approved" ChangesRequested = "changes_requested" ReviewRequired = "review_required" Commented = "commented" Clean = "clean" Conflicts = "conflicts" Blocked = "blocked" Green = "green" Red = "red" Pending = "pending" )
The vocabularies the host's words are read into.
const ActivityQuery = `` /* 1365-byte string literal not displayed */
ActivityQuery is the GraphQL a GitHub feed reads: requests updated since the window's start with their timeline, and the quiet open ones counted. A timeline keeps its newest 100 events, which a request rarely passes.
const ForcePushesQuery = "query($owner: String!, $name: String!, $number: Int!) { repository(owner: $owner, name: $name) " +
"{ pullRequest(number: $number) { timelineItems(last: 100, itemTypes: [HEAD_REF_FORCE_PUSHED_EVENT]) " +
"{ nodes { ... on HeadRefForcePushedEvent { createdAt actor { login } beforeCommit { oid } afterCommit { oid } } } } } } }"
ForcePushesQuery is the GraphQL that lists a PR's force-pushes.
const HeadFields = "number,state,headRefName,headRefOid,baseRefName,url,author,createdAt,mergedAt,closedAt"
HeadFields are what the janitor reads of a branch's requests.
const PRLimit = 1000
PRLimit caps each gh search. Reaching it is an error rather than a report silently missing the rest.
Variables ¶
var ErrNoThread = errors.New("the url names no thread to reply in")
ErrNoThread is a url that names no thread to reply in: an issue comment, a review with no inline comments, a check run.
Functions ¶
func DecodePages ¶
DecodePages runs a `api --paginate` call and reads every page into one list. gh merges the pages of an array into one array; glab may print one document per page, so every document in the output is read in turn.
Types ¶
type Activity ¶ added in v0.39.0
type Activity struct {
Requests []Touched
QuietCount int
QuietOldest time.Time // the oldest quiet request's creation time
}
Activity is what a repository did since a time: every request touched, and how many open ones nobody touched, with the oldest of them.
type CI ¶
CI is how the checks on a commit ended: Red when any failed, At the time of the last failure.
type CommitStatus ¶ added in v0.49.0
A CommitStatus is one named status on a commit; State is "success", "failure" or the host's own word for anything else.
type Event ¶ added in v0.39.0
type Event struct {
Kind string
At time.Time
Actor string
Message string // a commit's whole message, trailers included
State string // a review's: Approved, ChangesRequested or Commented
}
An Event is one thing that happened to a request.
type ForcePush ¶
type ForcePush struct {
At time.Time
Before string
After string
// SamePatches is whether every commit kept its patch, nil when git
// cannot tell; the reader that owns the checkout fills it.
SamePatches *bool
}
A ForcePush is one force-push to a PR: the head it replaced and the one it set.
type Host ¶
type Host struct {
Name string // "gh" or "glab"
Dir string // the checkout the CLI reads the remote from
// Repo names the repository when no checkout can: `owner/repo`, or
// `host/owner/repo` off the CLI's default host; set, every command carries it.
Repo string
}
A Host is one of the two forge CLIs, bound to the checkout it answers for, or to a repository named outright where no checkout exists.
func (Host) Activity ¶ added in v0.39.0
Activity reads what the repository did since since: one paged query on GitHub, on GitLab a list of the updated merge requests read one by one.
func (Host) Branches ¶ added in v0.39.0
Branches is every branch the host has, one paged listing: what the board asks of every merged request at once.
func (Host) CommitCI ¶
CommitCI is how the checks on a commit ended, nil when it has none. On GitHub that is its check runs and its commit statuses; on GitLab its last pipeline.
func (Host) CreatePull ¶ added in v0.49.0
CreatePull opens a request from a branch already on the remote, so neither CLI stops to ask about pushing it.
func (Host) DefaultBranchName ¶
DefaultBranchName is the repo's default branch as the host has it.
func (Host) EarlierRequests ¶ added in v0.39.0
EarlierRequests is every request that may name each id, to tell a task's first request from a follow-up: one GraphQL call for every id on GitHub, one list per id on GitLab. The searches only narrow; the caller matches.
func (Host) EditPull ¶ added in v0.49.0
EditPull rewrites a request's title, its body, or both; "" leaves one as it is. selector is what the CLI takes: a number or a branch.
func (Host) LatestStatus ¶ added in v0.49.0
LatestStatus is the newest status named name on sha, nil when it has none.
func (Host) MRForcePushes ¶
MRForcePushes reads GitLab's MR versions, one per push, since the time: a version whose previous head is not its ancestor replaced commits. GitLab records no pusher, so on the user's own MR each counts as theirs.
func (Host) MRReviews ¶
MRReviews is the notes that count as reviewing: any plain comment, and the system note an approval leaves.
func (Host) PRForcePushes ¶
PRForcePushes is the force-pushes the user made to a PR, the last 100: GitHub records each with the head before and after.
func (Host) PostComment ¶ added in v0.49.0
func (h Host) PostComment(ctx context.Context, number int, webURL, thread, body string) (string, error)
PostComment posts body in thread, or as a top-level comment when thread is "", and returns the new comment's url.
func (Host) PullComments ¶ added in v0.49.0
PullComments is the request's conversation; GitLab's system notes (pushes, approvals, label changes) are events, not comments, and are left out.
func (Host) PullCommits ¶
PullCommits is the commits a request lists, one call per request: asked for inside the list query, gh's GraphQL refuses a node count past its limit.
func (Host) PullDiff ¶ added in v0.49.0
PullDiff is the request's diff as the host has it: what was pushed, not what a checkout holds.
func (Host) Pulls ¶
Pulls is every request a person's standup needs: their own, with their commits and force-pushes, and others' they reviewed or merged since since.
func (Host) PullsByHead ¶ added in v0.45.0
PullsByHead is every request whose head is branch, in any state, newest first. A branch can carry several: one closed, then another opened.
func (Host) PullsSince ¶
PullsSince is what a board reads: every open request, and every one merged since since, each with the board's fields and no commits.
func (Host) SetStatus ¶ added in v0.49.0
SetStatus sets a named status on sha; state is "success" or "failure", which GitLab spells "failed".
func (Host) Thread ¶ added in v0.49.0
Thread is the thread a url names on request number: GitHub's top-level review comment, which replies attach to (a reply to a reply is refused), or GitLab's discussion. A review url is the url review pick records for an inline review, and names the thread of its first comment.
func (Host) ThreadComments ¶ added in v0.49.0
func (h Host) ThreadComments(ctx context.Context, number int, webURL, thread string) ([]Posted, error)
ThreadComments is every comment in thread, or the request's top-level conversation when thread is "". webURL is the request's own url, which a GitLab note's url hangs off.
type NewPull ¶ added in v0.49.0
A NewPull is a request to open: the branch, the branch it targets, and what the CLIs set on it at creation.
type PR ¶
type PR struct {
Number int
Title string
URL string
Status string // Open, Merged or Closed
Draft bool
Empty bool // no changes yet: no changed files on GitHub, no commits on GitLab
Head string
HeadSHA string
Base string
Author string
Assignees []string
Reviewers []string // reviewers requested and not yet heard from
CreatedAt time.Time
UpdatedAt time.Time
MergedAt time.Time // zero unless merged
ClosedAt time.Time // zero unless closed
MergedBy string
Body string
Decision string // Approved, ChangesRequested, ReviewRequired or ""
Mergeable string // Clean, Conflicts, Blocked or ""
Checks string // Green, Red, Pending or "" with none
Commits []PRCommit // the commits the host lists for it, where asked for
MergeSHA []string // the merge and squash commits it landed as
Reviews []Review // where asked for
ForcePushes []ForcePush // the requester's own, where asked for
}
A PR is a pull or merge request as the host reported it.
type PRCommit ¶
type PRCommit struct {
SHA string
Subject string
Message string // the whole message, trailers included
Email string // the author's email, as the commit records it
At time.Time
Parents int // more than one is a merge
}
A PRCommit is one commit a PR lists. A rebase merge lands it on the default branch under a new sha, keeping its author date and subject.
type Posted ¶ added in v0.49.0
A Posted comment is one already on a request, as far as a duplicate check needs it.