Help us shape the future of Go! Take the 2026 Go Developer Survey

forge

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package forge talks to the Git forge a repository lives on — GitHub or GitLab, hosted or on-premises.

Index

Constants

View Source
const (
	ReviewDraft = "draft"
	ReviewReady = "ready"
)

The draft facet's two values.

Variables

View Source
var (
	// ErrNoLog is a check the forge keeps no log for: a status, or a check run
	// from an app other than GitHub Actions.
	ErrNoLog = errors.New("the forge keeps no log for this check")
	// ErrInsecureLog is a log the forge redirected to an address that is not
	// https, which is not followed.
	ErrInsecureLog = errors.New("the forge sent the log to an address that is not https, so it was not read")
	// ErrLogNotRedirected is a redirect for a log that names no address to
	// follow it to.
	ErrLogNotRedirected = errors.New("the forge redirected the log without saying where it is")
	// ErrLogStorage is the storage a log was redirected to failing to hand it
	// over: its signed address expired, or the log is gone. It is not the
	// forge's answer, so it says nothing of the token.
	ErrLogStorage = errors.New("the storage the forge keeps the log in did not hand it over")
)

Why a job's log was not read.

View Source
var (
	// ErrUnauthorized reports a credential the forge did not accept.
	ErrUnauthorized = errors.New("the credential was not accepted")
	// ErrRefused reports a request the forge understood and would not serve
	// for this token, which is a question of what the token may do rather than
	// whether it is valid; the forge's own reason follows it in the message
	// when it gave one. A 403 that asks to wait is httpx.ErrRateLimited
	// instead.
	ErrRefused = errors.New("the forge refused the request")
	// ErrNoAPI reports an address with no forge API behind it.
	ErrNoAPI = errors.New("no forge API answered at that address")
	// ErrNotJSON reports an answer that was not JSON, which usually means the
	// base URL points at the web host rather than the API.
	ErrNotJSON = errors.New("the answer was not JSON")
	// ErrRejected reports a request the forge turned down and explained; the
	// explanation follows it in the message.
	ErrRejected = errors.New("the forge rejected the request")

	// ErrNoRepository reports a repository the forge will not show this token:
	// both forges answer 404 rather than 403, so as not to confirm it exists.
	ErrNoRepository = errors.New("the repository was not found, or the token cannot see it")
	// ErrUnexpectedStatus reports any other status.
	ErrUnexpectedStatus = errors.New("unexpected response status")
	// ErrUnreachable reports a request that never got an answer.
	ErrUnreachable = errors.New("could not reach the forge")
)

Errors the client returns. Callers distinguish them with errors.Is. A refused redirect and a rate limit come back as httpx's ErrRedirected and ErrRateLimited, which every client shares.

View Source
var (
	// ErrNotARemote reports a remote URL that does not name a repository.
	ErrNotARemote = errors.New("not a repository remote")
	// ErrUnknownForge reports a host that names neither GitHub nor GitLab.
	ErrUnknownForge = errors.New("cannot tell which forge this host is")
	// ErrKindNeedsHost reports a forge.kind with no forge.host beside it.
	ErrKindNeedsHost = errors.New("forge.kind is set without forge.host, the host it describes")
)

Errors this package returns. Callers distinguish them with errors.Is.

View Source
var ErrNoToken = errors.New("no forge token found")

ErrNoToken reports that no source supplied a credential.

View Source
var ErrNoUser = errors.New("no such user")

ErrNoUser reports a username GitLab does not know, so a reviewer or assignee named for a pull request cannot be set rather than being dropped in silence.

View Source
var ErrNotSupported = errors.New("the forge does not offer this")

ErrNotSupported reports a question the forge has no answer for, as GitHub has no group named as a user is: it spells every team org/team.

View Source
var ErrSomePeopleNotAdded = errors.New("some reviewers or assignees could not be added")

ErrSomePeopleNotAdded reports a pull request opened without some of the reviewers or assignees named for it, which the message names; it wraps why they could not be added, such as ErrNoUser. They are added best effort, so a mistyped name never costs the pull request.

View Source
var ErrTeamOfAnotherOrg = errors.New("the team belongs to another organization")

ErrTeamOfAnotherOrg reports a team reviewer of an organization other than the repository's, which GitHub cannot be asked for: it names a team by its slug alone, within the repository's own organization.

Functions

func AdmitsReview added in v0.9.0

func AdmitsReview(picked []ReviewFacet, request ReviewRequest) bool

AdmitsReview reports whether a request holds a picked value in every facet something is picked in.

func Advice added in v0.4.3

func Advice(err error) (string, bool)

Advice is how a token turned down is told — the same words wherever it is shown — naming the forge and the scope it asks for, then what the forge said: false for any other failure, which keeps its own words.

func Sources

func Sources(kind Kind, host string) string

Sources says where a token for a host would be read from, for telling someone who has none what to set. It names only what Resolve would read for that host.

Types

type Activity added in v0.6.0

type Activity struct {
	Events    []Event
	Truncated bool
}

Activity is what you did on the forge over a period, oldest first, and whether there was more than was read.

type CI

type CI struct {
	State CIState
	// Total, Done and Failed count checks where the forge reports them one by
	// one; GitLab reports a pipeline as a whole, so they stay zero there.
	Total, Done, Failed int
	// Checks are the reported checks one by one, so the interface can say which
	// failed rather than only how many.
	Checks []Check
}

CI is how CI stands, and how far through it is where the forge says.

type CIState

type CIState int

CIState is where CI stands on a pull request.

const (
	// CINone means nothing reports CI for this change.
	CINone CIState = iota
	// CIRunning means something is still to finish.
	CIRunning
	// CIPassed means everything finished without failing.
	CIPassed
	// CIFailed means something failed, whatever else is still running.
	CIFailed
)

func (CIState) Word added in v0.9.0

func (s CIState) Word() string

Word names the state in the one word every surface writes it in — the review filter's value, the command line's status and the API's CI state. A map, not a switch, so there is no last-case arm gobco can never see; exhaustive keeps it complete.

type Check added in v0.0.4

type Check struct {
	// ID is the forge's own id for the check, a check run's or a job's, so its
	// log can be asked for; empty for a status, which has none.
	ID    string
	Name  string
	State CIState
	URL   string
	// Stage is the pipeline stage a GitLab job ran in; empty on GitHub.
	Stage string
	// Reason is why a failed check failed, in the forge's few words — a check
	// run's title, a job's failure reason — or empty when it gives none.
	Reason string
	// LogAvailable is a check whose log the forge serves: a GitHub Actions run
	// or a GitLab job.
	LogAvailable bool
	// Project is the id of the fork a GitLab job's pipeline ran in, where its
	// log is read; empty for a job of the merge request's own project, and on
	// GitHub.
	Project string
}

Check is one reported check on a change: what it is called, where it stands, and the page that shows it in full — and, for one that failed, why, in the stage it ran in, and whether its log can be read.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client talks to one forge's REST API.

func New

func New(do Doer, base string, token Token) Client

New builds a client. Pass the base URL from Repo.APIBase.

func (Client) Activity added in v0.6.0

func (c Client) Activity(ctx context.Context, kind Kind, start, end time.Time) (Activity, error)

Activity reads what you did to pull or merge requests on the forge, in any repository, from start up to end.

func (Client) AssignIssue added in v0.5.0

func (c Client) AssignIssue(ctx context.Context, repo Repo, number int, username string) error

AssignIssue gives an issue to the user named, as Jira's assign does: added to its assignees on GitHub, and made its assignee on GitLab, which keys users by id and so looks the name up first.

func (Client) AssignedIssues added in v0.0.5

func (c Client) AssignedIssues(ctx context.Context, repo Repo) ([]Issue, error)

AssignedIssues lists the open issues in the repository assigned to the token's owner, for the Issues pane when there is no Jira to ask.

func (Client) CheckStatus

func (c Client) CheckStatus(ctx context.Context, repo Repo, pull PullRequest, head string) (CI, error)

CheckStatus reports how CI stands on a pull request whose head is the given commit.

func (Client) CloseIssue added in v0.0.5

func (c Client) CloseIssue(ctx context.Context, repo Repo, number int) error

CloseIssue closes an issue, the one state change a forge issue has, so picking one up and resolving it completes the loop.

func (Client) CommentOnIssue added in v0.6.0

func (c Client) CommentOnIssue(ctx context.Context, repo Repo, number int, text string) (IssueComment, error)

CommentOnIssue posts text as a comment on an issue, as written: the forge renders it as Markdown. GitLab answers a comment made only of quick actions by running them and keeping no note, which is the zero comment here, and not a failure to try again.

func (Client) CreatePullRequest

func (c Client) CreatePullRequest(ctx context.Context, repo Repo, request NewPullRequest) (PullRequest, error)

CreatePullRequest opens a pull request.

func (Client) EditPullRequest added in v0.0.7

func (c Client) EditPullRequest(
	ctx context.Context, repo Repo, pull PullRequest, edit PullRequestEdit,
) (PullRequest, error)

EditPullRequest changes an open pull request's title and description, leaving the pull request otherwise as it is.

func (Client) FindPullRequest

func (c Client) FindPullRequest(ctx context.Context, repo Repo, head Head) (PullRequest, bool, error)

FindPullRequest finds the pull request from head: an open one, or the merged one that means the branch is finished. A pull closed without merging is passed over. The returned PullRequest carries its State, so a caller that wants only an open one checks IsOpen rather than trusting found alone.

func (Client) IsGroup added in v0.5.0

func (c Client) IsGroup(ctx context.Context, name string) (bool, error)

IsGroup reports whether a bare CODEOWNERS name — @acme, which CODEOWNERS spells for a top-level GitLab group just as it does for a user — is a group: GitLab knows no user by it, and knows a group by it. A name it knows neither by is no group. GitHub spells every team org/team, so there it is ErrNotSupported.

func (Client) JobLog added in v0.5.0

func (c Client) JobLog(ctx context.Context, repo Repo, check Check) (JobLog, error)

JobLog reads the end of the log of check, a GitHub Actions run or a GitLab job. GitHub answers with a redirect to signed storage elsewhere: it is followed once, over https only, in a request that carries no token, since the storage needs none and is no host the token belongs to.

func (Client) Merge added in v0.0.7

func (c Client) Merge(ctx context.Context, repo Repo, pull PullRequest, method MergeMethod) error

Merge merges a pull request by the given method, which must be one the repository permits. Like re-running checks it needs a write scope the read path does not, so it can fail with ErrRefused where reading the pull did not.

func (Client) MergeMethods added in v0.0.7

func (c Client) MergeMethods(ctx context.Context, repo Repo) ([]MergeMethod, error)

MergeMethods lists the merge methods the repository permits, so a merge is only ever offered one it allows.

func (Client) On added in v0.4.3

func (c Client) On(kind Kind) Client

On is the client told which forge it talks to, so a token the forge turns down is told in that forge's terms: its name, and the scope it asks for.

func (Client) ReadIssue added in v0.0.5

func (c Client) ReadIssue(ctx context.Context, repo Repo, number int) (IssueDetail, error)

ReadIssue reads one issue in full, for the detail the pane shows.

func (Client) RecentIssueComments added in v0.6.0

func (c Client) RecentIssueComments(ctx context.Context, repo Repo, number, total int) ([]IssueComment, error)

RecentIssueComments reads the most recent of an issue's comments, as many as one page holds, oldest first: total is how many the issue has, which GitHub, listing a thread only oldest first, needs to find its last page. It costs one request on GitLab and at most two on GitHub, however long the thread. GitLab's notes about the issue's own changes, such as a new label, are left out.

func (Client) RerunChecks added in v0.0.7

func (c Client) RerunChecks(ctx context.Context, repo Repo, pull PullRequest, head string) (bool, error)

RerunChecks re-runs the failed CI on a pull request whose head is the given commit, and reports whether anything was re-run — a failure with no re-runnable job restarts nothing. It needs a write scope the read path does not, so it can fail with ErrRefused where reading the status did not.

func (Client) ReviewRequests added in v0.0.5

func (c Client) ReviewRequests(ctx context.Context, kind Kind) ([]ReviewRequest, error)

ReviewRequests lists the open pull or merge requests on the forge that ask the token's owner for a review. The kind chooses how to ask; the client can only reach the one forge its base URL points at.

func (Client) RewriteDescription added in v0.9.0

func (c Client) RewriteDescription(
	ctx context.Context, repo Repo, pull PullRequest, rewrite func(body string) (string, bool),
) (bool, error)

RewriteDescription changes an open pull request's description as rewrite says — the issue's line added, as linking a branch adds it — and leaves its title as it is. rewrite is handed the description as the forge holds it, every control, bidirectional mark and line ending kept, rather than as it is shown, so nothing but what rewrite changes is changed. It reports whether rewrite changed anything, and writes nothing when it did not.

func (Client) TokenScopes added in v0.4.3

func (c Client) TokenScopes(ctx context.Context) ([]string, error)

TokenScopes reports the scopes GitLab granted the credential, such as api or read_api. It asks GitLab only: an OAuth token, or an instance too old to answer, fails or answers no scopes, which a caller reads as not known.

func (Client) Whoami

func (c Client) Whoami(ctx context.Context) (Identity, error)

Whoami reports which account the credential belongs to.

type Configured

type Configured struct {
	// Kind is "github" or "gitlab", for a host whose name says neither.
	Kind string
	// Host is the host Kind and Token were written for, and the only one
	// either applies to.
	Host string
	// Token is consulted last, after the environment and the forge's own CLI.
	Token Token
}

Configured is what the configuration file says about the forge: forge.kind, forge.host and forge.token.

type Doer

type Doer = httpx.Doer

Doer is the HTTP seam this client accepts; see httpx.Doer.

type Event added in v0.6.0

type Event struct {
	At         time.Time
	Kind       EventKind
	Number     int
	Title      string
	URL        string
	Repository string
}

Event is one thing you did to a pull or merge request, and when. Repository is its owner/name on GitHub, and empty on GitLab, whose events name a project only by its id.

type EventKind added in v0.6.0

type EventKind int

EventKind is what you did to a pull or merge request.

const (
	// EventOpened is one you opened.
	EventOpened EventKind = iota + 1
	// EventMerged is one of yours merged, on GitHub, or one you merged, on GitLab.
	EventMerged
	// EventReviewed is one you reviewed, on GitHub, or approved, on GitLab.
	EventReviewed
)
type Head struct {
	Branch string
	// Fork is the path, on the forge of the repository the pull request
	// merges into, of the repository Branch was pushed to, as
	// contributor/repo; empty when it was pushed to that repository itself.
	Fork string
}

Head is where a pull request's work is: its branch, and the fork that branch was pushed to.

type Identity

type Identity struct {
	Login    string `json:"login"`
	Username string `json:"username"`
}

Identity is who a credential belongs to. The two forges name the same thing differently, which is the only difference this package has to care about.

func (Identity) Name

func (i Identity) Name() string

Name is the account name, whichever field the forge used.

type Issue added in v0.0.5

type Issue struct {
	Number int
	URL    string
	Title  string
}

Issue is an open issue on the forge assigned to you, for the tracker to offer when there is no Jira. It is scoped to one repository, because the loop that resolves it — a branch and a pull request — lives in that repository.

type IssueComment added in v0.6.0

type IssueComment struct {
	Author  string
	Body    string
	Created time.Time
}

IssueComment is one comment on an issue: who wrote it, what it says, and when.

type IssueDetail added in v0.0.5

type IssueDetail struct {
	Issue        Issue
	Body         string
	Author       string
	Closed       bool
	CommentCount int
}

IssueDetail is one issue read in full: its body, who opened it, whether it has been closed since it was listed, and how many comments it has.

type JobLog added in v0.5.0

type JobLog struct {
	Text      string
	Truncated bool
}

JobLog is the end of a failed job's log, with every terminal control taken out, and whether more was there than is kept.

type Kind

type Kind int

Kind is which forge a repository lives on.

const (
	// KindUnknown means the host names neither forge, which is the normal case
	// for an on-premises instance.
	KindUnknown Kind = iota
	// KindGitHub is github.com or GitHub Enterprise Server.
	KindGitHub
	// KindGitLab is gitlab.com or a self-managed GitLab.
	KindGitLab
)

func ParseKind

func ParseKind(name string) (Kind, error)

ParseKind reads a forge named in configuration.

func (Kind) Noun added in v0.3.0

func (k Kind) Noun() string

Noun is what this forge calls a proposed change: a merge request on GitLab, and a pull request everywhere else, including a forge it cannot name.

func (Kind) Sigil added in v0.3.0

func (k Kind) Sigil() string

Sigil is the mark this forge writes before a proposed change's number: "!" on GitLab, "#" everywhere else.

func (Kind) String

func (k Kind) String() string

String names the forge for humans.

type Look

type Look func(name string) (string, error)

Look reports where a program is, or an error if it is not on PATH. exec.LookPath satisfies it.

type MergeMethod added in v0.0.7

type MergeMethod string

MergeMethod is how a pull request is merged: a merge commit, a squashed commit, or a rebase. Which of these a repository permits is the repository's to say, so a merge is only ever offered one the repository allows.

const (
	// MergeCommit merges with a merge commit.
	MergeCommit MergeMethod = "merge"
	// MergeSquash squashes the branch into one commit.
	MergeSquash MergeMethod = "squash"
	// MergeRebase rebases the branch onto the base.
	MergeRebase MergeMethod = "rebase"
)

type Mergeability added in v0.0.3

type Mergeability int

Mergeability is whether the forge thinks a pull request can merge as it stands: unknown until the forge has worked it out, then clean or conflicting.

const (
	// MergeUnknown means the forge has not said, or is still computing it.
	MergeUnknown Mergeability = iota
	// MergeClean means the branch merges without conflict.
	MergeClean
	// MergeConflicts means the branch conflicts with its base.
	MergeConflicts
)

type NewPullRequest

type NewPullRequest struct {
	Title string
	Body  string
	// Head is where the work is; Base is the branch it merges into.
	Head  Head
	Base  string
	Draft bool
	// Reviewers and Assignees are usernames; Labels are label names. Each forge
	// asks for them its own way — GitHub in a request after the pull is opened,
	// GitLab at creation — but a failure to add them never discards a pull
	// request already opened. Reviewers, and on GitLab assignees, are added
	// best effort: one the forge cannot add leaves the rest added and
	// ErrSomePeopleNotAdded returned.
	Reviewers []string
	// TeamReviewers are teams named "org/team", asked to review as a team on
	// GitHub; on GitLab a group stands for its active direct members.
	TeamReviewers []string
	Assignees     []string
	Labels        []string
}

NewPullRequest is a pull request to open.

type PullRequest

type PullRequest struct {
	// Number is GitHub's number or GitLab's iid: the one people write as #42 or
	// !42.
	Number int
	URL    string
	Title  string
	// Body is the pull request's description, read so an edit can open on it.
	Body  string
	Draft bool
	// Base is the branch it merges into, as the forge says; a find reads it,
	// and it is empty where the forge did not.
	Base string
	// State is whether it is open, merged or closed, so a merged branch can be
	// finished. A find reads it; the zero value is open.
	State PullState
	// HeadCommit is the commit its branch is at on the forge — for a merged
	// one, the last the merge took — so a finish can tell a branch at what
	// merged from one holding more. A find reads it; it is empty where the
	// forge did not say.
	HeadCommit string
	// Approvals is how many reviewers have approved; ChangesRequested is whether
	// any reviewer is still asking for changes; Mergeable is whether it can merge.
	// These are best effort — a forge that will not say leaves them at zero and
	// unknown rather than failing the whole read.
	Approvals        int
	ChangesRequested bool
	Mergeable        Mergeability
}

PullRequest is a pull request on GitHub, or a merge request on GitLab.

func (PullRequest) IsOpen added in v0.0.7

func (p PullRequest) IsOpen() bool

IsOpen reports whether this pull request is in the open state. FindPullRequest also returns a merged pull request, so a caller that means "is there an open one" — the status line, the link offer, the offer to open a new one — asks this rather than trusting found alone. (Opened, below, is the different question of whether the forge created it at all.)

func (PullRequest) Opened added in v0.0.7

func (p PullRequest) Opened() bool

Opened reports whether this is a pull request the forge created, told from the zero value a failed create returns by its number, which the forge always assigns.

type PullRequestEdit added in v0.0.7

type PullRequestEdit struct {
	Title string
	Body  string
}

PullRequestEdit is what changes about an open pull request: its title and its description. Everything else about it — its branches, its reviewers — is left as it is.

type PullState added in v0.0.7

type PullState int

PullState is where a pull request stands in its life: open, merged, or closed without merging.

const (
	// StateOpen means the pull request is open. It is the zero value.
	StateOpen PullState = iota
	// StateMerged means it has merged, so its branch's work is done.
	StateMerged
	// StateClosed means it was closed without merging.
	StateClosed
)

type RefusalError added in v0.4.3

type RefusalError struct {
	Kind   Kind
	Status error
	Reason string
}

RefusalError is a forge turning down the token a request carried: not accepting it (401, ErrUnauthorized) or refusing what it asked (403, ErrRefused), with the forge's own reason when it gave one, and which forge said so.

func (*RefusalError) Error added in v0.4.3

func (r *RefusalError) Error() string

Error is the status, with the forge's reason after it.

func (*RefusalError) Unwrap added in v0.4.3

func (r *RefusalError) Unwrap() error

Unwrap is the status, so a refusal answers to ErrRefused or ErrUnauthorized.

type Repo

type Repo struct {
	// Kind is the forge, where the host says which one.
	Kind Kind
	// Host is the web host, including an HTTPS remote's port; an SSH remote's
	// port is SSH's, not the API's, and is not kept.
	Host string
	// Path is everything identifying the project on that host. It is not split
	// into an owner and a name because GitLab nests projects arbitrarily deep,
	// and splitting would quietly discard the middle.
	Path string
}

Repo identifies a repository on a forge.

func ParseRemote

func ParseRemote(remote string) (Repo, error)

ParseRemote reads the repository a git remote URL points at.

func (Repo) APIBase

func (r Repo) APIBase() (string, error)

APIBase is the root of the REST API serving this repository.

func (Repo) IssueURL added in v0.5.0

func (r Repo) IssueURL(number int) string

IssueURL is the issue's page on the forge, for a link to open or copy, or empty on a forge that could not be told.

func (Repo) WithConfiguredKind

func (r Repo) WithConfiguredKind(configured Configured) (Repo, error)

WithConfiguredKind fills in a forge the remote could not name.

It only ever fills a gap. A host that names itself — github.com, a ghe.com tenant, gitlab.com — keeps its own answer, because the remote is the better evidence and silently disagreeing with it would be the worse failure. And it fills the gap for one host: forge.kind describes forge.host, and says nothing about any other.

type Resolver

type Resolver struct {
	// Getenv reads an environment variable. os.Getenv satisfies it.
	Getenv func(string) string
	// Look and Run reach the forge's own command line tool, if it is installed.
	Look Look
	Run  Run
	// Configured is the configuration file's say, consulted last.
	Configured Configured
}

Resolver finds a forge credential. Every source it consults is a field, so its tests never read the real environment or spawn anything.

func (Resolver) Resolve

func (r Resolver) Resolve(ctx context.Context, kind Kind, host string) (Token, Source, error)

Resolve finds the credential for a forge, and says where it came from.

The order is deliberate. An environment variable is the most explicit thing a person can do and wins; the forge's own CLI is next, so anyone already signed in with it needs no configuration at all; forge.token comes last, because storing a credential we do not have to store is the option worth avoiding.

Every source answers for a host, as the forges' own tools have theirs do, and a token is offered to the host it is for and to no other.

type ReviewFacet added in v0.9.0

type ReviewFacet struct {
	Kind  ReviewFacetKind
	Value string
}

ReviewFacet is one value a request can hold in one facet: its repository ("" for none the forge named), how its CI stands, in CIState's words, draft or ready, or who asks.

func OfferedReviewFacets added in v0.9.0

func OfferedReviewFacets(requests []ReviewRequest) []ReviewFacet

OfferedReviewFacets is every value the queue's filter offers, in the order it lists them: the repositories the requests are in, by name, every CI state and draft then ready in a fixed order, and who asks, by name. A name is ordered by its UTF-8 bytes, which is code point order.

func (ReviewFacet) Label added in v0.9.0

func (f ReviewFacet) Label() string

Label is how every surface names a facet value, in the filter and in the line that says what the queue is narrowed to.

type ReviewFacetChoice added in v0.9.0

type ReviewFacetChoice struct {
	Facet ReviewFacet
	Count int
}

ReviewFacetChoice is a value the filter offers, with how many requests hold it.

func ReviewChoices added in v0.9.0

func ReviewChoices(requests []ReviewRequest, picked []ReviewFacet) []ReviewFacetChoice

ReviewChoices is every value the requests hold, with how many hold each, in the order OfferedReviewFacets offers them, then every picked value none holds, at zero, in the order it was picked, so it can still be unpicked.

type ReviewFacetKind added in v0.9.0

type ReviewFacetKind int

ReviewFacetKind is one of the four facets the review queue is narrowed by: a request's repository, how its CI stands, whether it is a draft, and who asks. Values picked in one facet widen the queue, and the facets narrow it together. The rules are written here alone: the terminal's filter calls them, and the web server ships each request's facets and the order they are offered in.

const (
	FacetRepository ReviewFacetKind = iota
	FacetCI
	FacetDraft
	FacetAuthor
)

The facets, in the order the filter offers them.

type ReviewRequest added in v0.0.5

type ReviewRequest struct {
	Number int
	URL    string
	Title  string
	Author string
	// Repository is the owner/name (GitHub) or group/project (GitLab) the request
	// is in, since a review queue spans repositories.
	Repository string
	Draft      bool
	// CI is best effort: the forge's own summary where the listing carries one,
	// and CINone where it does not, since the queue is read without a follow-up
	// request per entry.
	CI       CIState
	OpenedAt time.Time
}

ReviewRequest is an open pull or merge request that asks for your review. It carries what a review queue is read for — who wants it, since when, and where CI stands — across whichever repositories on the forge requested you.

func ByRepository added in v0.5.0

func ByRepository(requests []ReviewRequest) []ReviewRequest

ByRepository is the requests grouped by repository, in its name's order, and the longest-waiting first within each.

func NewestFirst added in v0.5.0

func NewestFirst(requests []ReviewRequest) []ReviewRequest

NewestFirst is the requests ordered with the one opened last first, for a look at what just arrived. Requests opened at the same moment keep the forge's order.

func OldestFirst added in v0.3.0

func OldestFirst(requests []ReviewRequest) []ReviewRequest

OldestFirst is the review queue in the order it is worked through, the longest-waiting request first — the order every surface lists it in. Requests opened at the same moment keep the forge's order, and the forge's answer is left as it came.

func (ReviewRequest) Facets added in v0.9.0

func (r ReviewRequest) Facets() []ReviewFacet

Facets is the value the request holds in each facet.

type Run

type Run func(ctx context.Context, name string, args ...string) ([]byte, error)

Run executes a program and returns its standard output. proc.Run satisfies it.

type Source

type Source int

Source is where a token came from, for reporting.

const (
	// SourceNone means nothing supplied one.
	SourceNone Source = iota
	// SourceEnvironment is an environment variable.
	SourceEnvironment
	// SourceCLI is the forge's own command line tool.
	SourceCLI
	// SourceConfiguration is forge.token in the configuration file.
	SourceConfiguration
)

func (Source) String

func (s Source) String() string

String names the source for humans.

type Template

type Template struct {
	// Name is the file's name without its extension.
	Name string
	// Path is where the file is, relative to the repository root.
	Path string
	Body string
}

Template is a pull request template a repository carries.

func FindTemplates

func FindTemplates(repo fs.FS, kind Kind) []Template

FindTemplates finds a repository's pull request templates where its forge looks for them, the default first.

GitHub reads a single pull_request_template file from .github, the root or docs, and a directory of them by that name in the same places; the single file is the default. GitLab reads .gitlab/merge_request_templates, and applies the one named Default by itself.

type Token

type Token string

Token is a forge credential.

It is a named type with a String and a GoString rather than a bare string, and that is a guard rather than a decoration: every verb a string takes — %v, %s, %q, %x, %X and %#v — goes through one of them and yields the mask, as does a Token in an exported field printed with %v, %+v or %#v. fmt calls neither method for a verb a string rejects (%d, %t, ...), which go vet's printf check flags, nor for a Token in an unexported field. Reading the real value takes an explicit Secret call, which is easy to find in review and impossible to do by accident.

func (Token) GoString added in v0.4.0

func (t Token) GoString() string

GoString masks the token under %#v, quoted so the output still reads as Go syntax: "****", or "" for an empty Token.

func (Token) Secret

func (t Token) Secret() string

Secret returns the real value. Call it only where the credential is being sent, never where it might be printed.

func (Token) String

func (t Token) String() string

String masks the token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL