go-gh

repository·trunk·Indexed 19 days ago

https://github.com/cli/go-gh

A Go library for building GitHub CLI extensions that adhere to native conventions for authentication, repository context, and output formatting. It provides utilities to execute gh commands via Exec, ExecContext, and ExecInteractive, as well as an authenticated REST API client via api.DefaultRESTClient().

Tokens
1.2K
Snippets
5
Records
6
Agent score
15%

What's inside go-gh

  1. Use go-gh to author GitHub CLI extensions

    trunk

    go-gh is a collection of Go modules designed to simplify the creation of GitHub CLI extensions. By using this library, your extension will automatically follow standard GitHub CLI conventions:

    • Repository Context: repository.Current() respects the GH_REPO environment variable and falls back to git remote configuration.
    • Authentication: GitHub API requests use the same authentication mechanism as the gh CLI, utilizing GH_TOKEN and GH_HOST environment variables or the user's stored OAuth token.
    • Terminal Capabilities: Terminal features are determined by standard environment variables like GH_FORCE_TTY, NO_COLOR, and CLICOLOR.
    • Output Formatting: Table generation (tableprinter) and Go template output (template) use the same engines as the gh CLI.
    • Browser Integration: The browser module uses the user's preferred web browser.
  2. Execute gh commands and use the REST API in Go

    trunk

    You can interact with GitHub in two primary ways using go-gh:

    1. Shelling out to gh: Use gh.Exec to run standard GitHub CLI commands and capture their output. This is useful for leveraging existing CLI functionality.
    2. Using the REST API: Use api.DefaultRESTClient() to obtain an authenticated client for making direct requests to the GitHub API. This provides more granular control over data retrieval.
    package main
    
    import (
    	"fmt"
    	"log"
    	"github.com/cli/go-gh/v2"
    	"github.com/cli/go-gh/v2/pkg/api"
    )
    
    func main() {
    	// These examples assume `gh` is installed and has been authenticated.
    
    	// Shell out to a gh command and read its output.
    	issueList, _, err := gh.Exec("issue", "list", "--repo", "cli/cli", "--limit", "5")
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Println(issueList.String())
    
    	// Use an API client to retrieve repository tags.
    	client, err := api.DefaultRESTClient()
    	if err != nil {
    		log.Fatal(err)
    	}
    	response := []struct{
    		Name string
    	}{}
    	err = client.Get("repos/cli/cli/tags", &response)
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Println(response)
    }
  3. Run interactive GitHub CLI commands with ExecInteractive

    trunk

    Use ExecInteractive when you need to run a gh command that requires user input (e.g., authentication prompts or confirmation dialogs). This function connects the command's stdin, stdout, and stderr directly to the parent process's streams (os.Stdin, os.Stdout, and os.Stderr).

    ctx := context.Background()
    // This will allow the user to interact with prompts in the terminal
    err := gh.ExecInteractive(ctx, "auth", "login")
    if err != nil {
    	// handle error
    }
  4. Execute GitHub CLI commands with Exec

    trunk

    Use Exec to run a gh command in a subprocess. This function captures the standard output (stdout) and standard error (stderr) into separate bytes.Buffer instances. It is suitable for non-interactive commands where you need to inspect the output programmatically.

    stdout, stderr, err := gh.Exec("repo", "view", "cli/cli")
    if err != nil {
    	// handle error
    }
    fmt.Printf("Output: %s\n", stdout.String())
  5. Execute GitHub CLI commands with context using ExecContext

    trunk

    Use ExecContext to run a gh command with support for cancellation and timeouts via a context.Context. Like Exec, it captures stdout and stderr into bytes.Buffer instances.

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    stdout, stderr, err := gh.ExecContext(ctx, "issue", "list")
    if err != nil {
    	// handle error
    }
  6. Locate the GitHub CLI executable with Path

    trunk

    Use Path to find the absolute path of the gh executable. It first checks the GH_PATH environment variable; if that is not set, it searches the system PATH for an executable named gh.

    ghPath, err := gh.Path()
    if err != nil {
    	// handle error (e.g., gh is not installed)
    }
    fmt.Println("GH path:", ghPath)