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

protocol

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package protocol is the contract between git-stack and its provider plugins: executables named git-stack-<provider> that manage pull requests (or merge requests) on one kind of Git host.

git-stack runs a provider once per operation as

git-stack-<provider> <op>

with a JSON Request on stdin, and reads a JSON Response from stdout. A failed operation exits non-zero with Response.Error set. Providers written in Go implement Provider and call Serve from main.

Index

Constants

View Source
const (
	OpDescribe         = "describe"
	OpDetect           = "detect"
	OpGetCR            = "get_cr"
	OpFindCRForBranch  = "find_cr_for_branch"
	OpSearchCRs        = "search_crs"
	OpListCRsTargeting = "list_crs_targeting"
	OpCreateCR         = "create_cr"
	OpUpdateCR         = "update_cr"
	OpMarkReady        = "mark_ready"
	OpCancelAutoMerge  = "cancel_auto_merge"
	OpMerge            = "merge"
	OpGetBranch        = "get_branch"
	OpGetRepo          = "get_repo"
	OpSyncStack        = "stack_sync"
	OpUnstack          = "stack_unstack"
)

Operation names (the first argument of a provider executable).

View Source
const (
	StateOpen    = "open"
	StateClosed  = "closed"
	StateMerged  = "merged"
	StateMerging = "merging" // the host is performing the merge right now
)

State of a change request.

View Source
const (
	MethodMerge  = "merge"
	MethodSquash = "squash"
	MethodRebase = "rebase"
)

Merge methods.

View Source
const (
	BlockHTMLComment = "html-comment" // <!-- git-stack:begin {...} -->
	BlockLinkRef     = "link-ref"     // [//]: # (git-stack:begin {...})
)

Block styles: how the machine-readable stack data is hidden in descriptions.

View Source
const (
	CodeUnsupported = "unsupported" // the provider cannot do this
	CodeNotFound    = "not_found"
	CodeAuth        = "auth" // not logged in, or not allowed
	CodeFailure     = "failure"
)

Error codes.

View Source
const ExecutablePrefix = "git-stack-"

ExecutablePrefix is prepended to a provider name to get its executable.

View Source
const Version = 1

Version is the protocol version spoken by this package. git-stack refuses providers that report a different major version in Describe.

Variables

This section is empty.

Functions

func CodeOf

func CodeOf(err error) string

CodeOf returns the code of err, CodeFailure if it carries none.

func Errorf

func Errorf(code, format string, args ...any) error

Errorf returns an *Error with code.

func Serve

func Serve(p Plugin)

Serve runs one operation from the command line and exits. Call it from main.

Types

type Branch

type Branch struct {
	Protected bool `json:"protected"`
	Default   bool `json:"default"`
}

Branch is what git-stack needs to know about a branch on the host.

type CR

type CR struct {
	Number int    `json:"number"`
	Title  string `json:"title"`
	Body   string `json:"body"`
	State  string `json:"state"`
	Draft  bool   `json:"draft,omitempty"`
	// Head is the source branch, Base the target branch.
	Head string `json:"head"`
	Base string `json:"base"`
	URL  string `json:"url"`
	// HeadSHA is the commit the head branch is (or, once merged, was) at.
	HeadSHA string `json:"head_sha,omitempty"`
	// AutoMerge reports that the CR merges by itself once checks pass.
	AutoMerge bool `json:"auto_merge,omitempty"`
	// DeleteHead reports that the head branch should be deleted after merging.
	DeleteHead bool `json:"delete_head,omitempty"`
	// Checking reports that the host is still working out mergeability.
	Checking bool `json:"checking,omitempty"`
	// MergeError is the host's reason a merge did not happen, if any.
	MergeError string `json:"merge_error,omitempty"`
	// FromFork reports that Head lives in another repository.
	FromFork bool `json:"from_fork,omitempty"`
}

CR is a change request: a pull request or merge request.

func (*CR) Merged

func (c *CR) Merged() bool

Merged reports whether the CR has been merged.

func (*CR) Open

func (c *CR) Open() bool

Open reports whether the CR is open.

type Error

type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

Error is a provider failure with a machine-readable code.

func (*Error) Error

func (e *Error) Error() string

type Info

type Info struct {
	Name     string `json:"name"`
	Protocol int    `json:"protocol"`
	Terms    Terms  `json:"terms"`
	// BlockStyle is one of the Block* constants; empty means BlockHTMLComment.
	BlockStyle string `json:"block_style,omitempty"`
	// MaxBody is the longest description the host accepts; 0 means no limit.
	MaxBody int `json:"max_body,omitempty"`
	// MergeMethods lists the methods Merge supports.
	MergeMethods []string `json:"merge_methods,omitempty"`
	// NativeStacks reports that SyncStack and Unstack manage a stack object
	// on the host, beyond the block git-stack keeps in each description.
	NativeStacks bool `json:"native_stacks,omitempty"`
}

Info describes a provider. It does not depend on a repository.

type NewCR

type NewCR struct {
	Head  string `json:"head"`
	Base  string `json:"base"`
	Title string `json:"title"`
	Body  string `json:"body"`
	Draft bool   `json:"draft,omitempty"`
}

NewCR describes a change request to create.

type Plugin

type Plugin struct {
	Info Info
	// Detect reports whether repo is hosted where this provider works, for
	// hosts git-stack does not know. It may be nil.
	Detect func(repo Repo) bool
	// Open returns a Provider for repo.
	Open func(repo Repo) (Provider, error)
}

Plugin is what a provider executable implements.

type Provider

type Provider interface {
	// GetCR fetches a CR by number.
	GetCR(number int) (*CR, error)
	// FindCRForBranch returns the open CR whose head is branch, else the most
	// recently merged one, else nil. CRs from forks are ignored.
	FindCRForBranch(branch string) (*CR, error)
	// SearchCRs returns open CRs whose description contains text.
	SearchCRs(text string) ([]*CR, error)
	// ListCRsTargeting returns open CRs, not from forks, whose base is branch.
	ListCRsTargeting(branch string) ([]*CR, error)
	// CreateCR opens a CR.
	CreateCR(n NewCR) (*CR, error)
	// UpdateCR changes the attributes set in u.
	UpdateCR(number int, u Update) (*CR, error)
	// MarkReady takes a CR out of draft.
	MarkReady(number int) (*CR, error)
	// CancelAutoMerge turns auto-merge off.
	CancelAutoMerge(number int) error
	// Merge asks the host to merge the CR with method once head is at sha.
	// The host may merge at once, or set the CR to merge when checks pass
	// (AutoMerge set in the result). The head branch is never deleted.
	Merge(number int, method, sha string) (*CR, error)
	// GetBranch fetches a branch.
	GetBranch(name string) (*Branch, error)
	// GetRepo fetches repository settings.
	GetRepo() (*RepoSettings, error)
	// SyncStack makes the host's native stack hold exactly numbers, bottom
	// first. Providers without native stacks return nil.
	SyncStack(numbers []int) error
	// Unstack removes the CRs from the host's native stack, if any.
	Unstack(numbers []int) error
}

Provider manages change requests for one repository.

type Repo

type Repo struct {
	// RemoteURL is the git remote URL as configured.
	RemoteURL string `json:"remote_url"`
	// Host is the API host, e.g. github.com, with ssh config aliases resolved.
	Host string `json:"host"`
	// Path is the repository path on the host, e.g. owner/repo or group/sub/repo.
	Path string `json:"path"`
}

Repo identifies the repository an operation works on.

type RepoSettings

type RepoSettings struct {
	// DefaultMergeMethod is merge, squash or rebase: what the repository
	// prefers when the user has not chosen.
	DefaultMergeMethod string `json:"default_merge_method"`
}

RepoSettings are the repository settings git-stack uses.

type Request

type Request struct {
	Protocol int     `json:"protocol"`
	Repo     Repo    `json:"repo"`
	Number   int     `json:"number,omitempty"`
	Numbers  []int   `json:"numbers,omitempty"`
	Branch   string  `json:"branch,omitempty"`
	Text     string  `json:"text,omitempty"`
	Method   string  `json:"method,omitempty"`
	SHA      string  `json:"sha,omitempty"`
	New      *NewCR  `json:"new,omitempty"`
	Update   *Update `json:"update,omitempty"`
}

Request is the JSON sent on stdin. Fields not used by an operation are omitted.

type Response

type Response struct {
	Error  *Error        `json:"error,omitempty"`
	Info   *Info         `json:"info,omitempty"`
	Match  bool          `json:"match,omitempty"`
	CR     *CR           `json:"cr,omitempty"`
	CRs    []*CR         `json:"crs,omitempty"`
	Branch *Branch       `json:"branch,omitempty"`
	Repo   *RepoSettings `json:"repo,omitempty"`
}

Response is the JSON written to stdout.

func Dispatch

func Dispatch(p Plugin, op string, r io.Reader) Response

Dispatch decodes a request from r and runs op on p.

type Terms

type Terms struct {
	Short string `json:"short"` // PR, MR
	Long  string `json:"long"`  // pull request, merge request
	// Ref formats a CR number in text, with %d for the number: "#%d", "!%d".
	Ref string `json:"ref"`
}

Terms name change requests in the host's own words.

type Update

type Update struct {
	Base  *string `json:"base,omitempty"`
	Title *string `json:"title,omitempty"`
	Body  *string `json:"body,omitempty"`
}

Update lists the attributes to change; nil fields are left alone.

Jump to

Keyboard shortcuts

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