codespace¶
Package codespace wraps the GitHub CLI (gh) to list, create, delete, and SSH into GitHub Codespaces. All GitHub API interactions go through the GHRunner interface so they can be stubbed in tests.
Index¶
- func BuildCreateArgs(target config.Target) []string
- func BuildPortForwardArgs(codespaceName string, remotePort, localPort int) []string
- func DeleteCodespace(runner GHRunner, name string) error
- func DescribeCodespace(cs *Codespace, recommended bool) string
- func EnsureGHAuth(runner GHRunner) error
- func EnsureReachable(runner GHRunner, codespaceName string) error
- func GetSSHConfig(runner GHRunner, codespaceName string) (string, error)
- func ListAllRepos(runner GHRunner) ([]string, error)
- func MatchesTarget(cs *Codespace, t *config.Target) bool
- func PortLabel(port Port) string
- func RequireCommand(name string) error
- func UniqueRepos(codespaces []Codespace) []string
- type Codespace
- func ChooseCodespace(codespaces []Codespace, t *config.Target) (*Codespace, error)
- func CreateCodespace(runner GHRunner, target config.Target) (*Codespace, error)
- func CreateCodespaceInteractive(runner GHRunner, target config.Target) (*Codespace, error)
- func FilterByRepo(codespaces []Codespace, repo string) []Codespace
- func FindMatching(codespaces []Codespace, t *config.Target) []Codespace
- func ListAllCodespaces(runner GHRunner) ([]Codespace, error)
- func ListAllCodespacesCtx(ctx context.Context, runner GHRunner) ([]Codespace, error)
- func ListCodespaces(runner GHRunner, repository string) ([]Codespace, error)
- type DefaultGHRunner
- func (d DefaultGHRunner) Run(args []string) (string, error)
- func (d DefaultGHRunner) RunCtx(ctx context.Context, args []string) (string, error)
- func (d DefaultGHRunner) RunInteractive(args []string) (string, error)
- func (d DefaultGHRunner) RunMerged(args []string) (string, error)
- func (d DefaultGHRunner) RunWithInput(args []string, input string) (string, error)
- type GHRunner
- type GitStatus
- type Port
- func ListPorts(runner GHRunner, codespaceName string) ([]Port, error)
- func ListPortsCtx(ctx context.Context, runner GHRunner, codespaceName string) ([]Port, error)
- type RepoField
- func (r *RepoField) UnmarshalJSON(data []byte) error
func BuildCreateArgs¶
BuildCreateArgs builds the gh codespace create command arguments.
func BuildPortForwardArgs¶
BuildPortForwardArgs builds args for `gh codespace ports forward`.
func DeleteCodespace¶
DeleteCodespace deletes a codespace by name.
func DescribeCodespace¶
DescribeCodespace returns a human-readable description.
func EnsureGHAuth¶
EnsureGHAuth verifies the user is authenticated with gh.
func EnsureReachable¶
EnsureReachable verifies the codespace SSH server is accessible. It retries with exponential backoff since the codespace may be starting up or the SSH tunnel may be slow to establish.
func GetSSHConfig¶
GetSSHConfig retrieves the OpenSSH config for a codespace. Retries once on failure since the SSH tunnel may not be ready immediately after EnsureReachable succeeds.
func ListAllRepos¶
ListAllRepos returns all repositories the user has access to.
func MatchesTarget¶
MatchesTarget checks whether a codespace matches a config target. Repository comparison is case-insensitive: GitHub repo names are, and a config that says "Acme/Demo" against an API that reports "acme/demo" used to silently create a duplicate codespace on every launch.
func PortLabel¶
PortLabel returns a compact display label for a forwarded port.
func RequireCommand¶
RequireCommand checks that a command is on PATH.
func UniqueRepos¶
UniqueRepos extracts sorted unique repository names from codespaces.
type Codespace¶
type Codespace struct {
Name string `json:"name"`
DisplayName string `json:"displayName,omitempty"`
Repository RepoField `json:"repository"`
State string `json:"state,omitempty"`
GitStatus *GitStatus `json:"gitStatus,omitempty"`
MachineName string `json:"machineName,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
LastUsedAt string `json:"lastUsedAt,omitempty"`
}
func ChooseCodespace¶
ChooseCodespace auto-selects a codespace in non-interactive mode. Returns nil if no match, errors if ambiguous.
func CreateCodespace¶
CreateCodespace creates a new codespace by POSTing directly to the GitHub REST API (`POST /repos/{owner}/{repo}/codespaces`). This bypasses the interactive prompts that `gh codespace create` emits when billing is paid by a third party or when a machine type isn't specified: prompts that fail without a terminal (e.g. from the tray/daemon). Use CreateCodespaceInteractive when running from a real TTY and prompts are desired.
func CreateCodespaceInteractive¶
CreateCodespaceInteractive creates a codespace with terminal access so gh can prompt the user if needed (e.g. machine type selection). Output is shown on the terminal in real time.
func FilterByRepo¶
FilterByRepo returns codespaces belonging to a given repository.
func FindMatching¶
FindMatching returns all codespaces matching the target.
func ListAllCodespaces¶
ListAllCodespaces returns all codespaces across all repos.
func ListAllCodespacesCtx¶
ListAllCodespacesCtx is the context-aware variant of ListAllCodespaces. The daemon poller uses this to cap how long a hung `gh codespace list` can pin the in-flight poll slot.
func ListCodespaces¶
ListCodespaces returns all codespaces for a given repository.
type DefaultGHRunner¶
DefaultGHRunner executes real gh commands.
func (DefaultGHRunner) Run¶
func (DefaultGHRunner) RunCtx¶
func (DefaultGHRunner) RunInteractive¶
func (DefaultGHRunner) RunMerged¶
func (DefaultGHRunner) RunWithInput¶
type GHRunner¶
GHRunner abstracts the GitHub CLI for testability.
type GHRunner interface {
Run(args []string) (string, error)
// RunCtx is like Run but cancels the underlying process when ctx is
// done. Used by the daemon poller to cap long-running list calls so
// a hung gh doesn't pin the in-flight poll slot.
RunCtx(ctx context.Context, args []string) (string, error)
RunMerged(args []string) (string, error)
// RunInteractive runs a command with stdin connected and output teed to
// both a capture buffer and the real terminal. Use this when the gh
// subprocess may need to prompt the user (e.g. machine-type selection).
RunInteractive(args []string) (string, error)
// RunWithInput runs a command and feeds a string to its stdin. Used for
// `gh api --input -` calls where we pipe a JSON body.
RunWithInput(args []string, input string) (string, error)
}
type GitStatus¶
type Port¶
Port is a forwarded Codespaces port as reported by `gh codespace ports`.
type Port struct {
BrowseURL string `json:"browseUrl"`
Label string `json:"label"`
SourcePort int `json:"sourcePort"`
Visibility string `json:"visibility"`
}
func ListPorts¶
ListPorts returns the forwarded ports for a codespace.
func ListPortsCtx¶
ListPortsCtx is the context-aware variant of ListPorts, so callers can cap how long a hung `gh codespace ports` blocks them.
type RepoField¶
RepoField handles the gh CLI returning repository as either a string or an object.
func (*RepoField) UnmarshalJSON¶
Generated by gomarkdoc