ghclient

package
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

SPDX-License-Identifier: MIT

SPDX-License-Identifier: MIT Package ghclient wraps go-github with commit, repository-activity, and PR discovery strategies and normalizes read-only evidence into model types.

SPDX-License-Identifier: MIT

SPDX-License-Identifier: MIT

SPDX-License-Identifier: MIT

SPDX-License-Identifier: MIT

SPDX-License-Identifier: MIT

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client retrieves GitHub evidence. PR collection calls own independent budgets.

func New

func New(token, baseURL string, perPage int, opts ...Option) (*Client, error)

New builds a Client. token may be empty (unauthenticated, heavily rate limited). baseURL, when set, targets a GitHub Enterprise instance and must be the API root (e.g. "https://ghe.example.com/api/v3/"). perPage is clamped to the API's 1-100 range.

Options are applied before the HTTP client is constructed, because WithRequestBudget installs a transport that everything else must be layered on top of.

func (*Client) Collect

func (c *Client) Collect(ctx context.Context, q model.Query) (model.Result, error)

Collect runs a query using its scope and returns the normalized result.

func (*Client) CollectActivity added in v1.1.0

func (c *Client) CollectActivity(ctx context.Context, q model.ActivityQuery) (res model.ActivityResult, err error)

CollectActivity gathers a repository's activity for a window: the commits, the aggregate change set between the window's boundary states, the correlations between them, and what the whole thing cost.

Budget and quota stops return evidence plus a disclosure, without an error. Other failures return the evidence gathered so far alongside the error.

func (*Client) CollectPRInbox added in v1.2.0

func (c *Client) CollectPRInbox(ctx context.Context, q model.PRInboxQuery) (model.PRInboxResult, error)

CollectPRInbox gathers current personal work without an activity window.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/skaphos/sting/config"
	"github.com/skaphos/sting/ghclient"
)

func main() {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodGet {
			http.Error(w, "read-only", http.StatusMethodNotAllowed)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprint(w, `[]`)
	}))
	defer server.Close()
	cfg := config.Default()
	q, err := cfg.ResolvePRInbox(config.PRInboxRequest{User: "octocat", Scope: "repos", Repos: []string{"acme/api"}})
	if err != nil {
		panic(err)
	}
	client, err := ghclient.New("", server.URL+"/", 100)
	if err != nil {
		panic(err)
	}
	result, err := client.CollectPRInbox(context.Background(), q)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.Workflow, result.Count)
}
Output:
pr-inbox 0

func (*Client) CollectPRs added in v1.2.0

func (c *Client) CollectPRs(ctx context.Context, q model.PRQuery) (model.PRResult, error)

CollectPRs gathers historical activity under a private, per-query request budget.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"time"

	"github.com/skaphos/sting/config"
	"github.com/skaphos/sting/ghclient"
)

func main() {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodGet {
			http.Error(w, "read-only", http.StatusMethodNotAllowed)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprint(w, `{"total_count":0,"items":[]}`)
	}))
	defer server.Close()
	cfg := config.Default()
	q, err := cfg.ResolvePRs(config.PRRequest{Author: "octocat", TimeBasis: "created"}, time.Date(2026, 8, 25, 0, 0, 0, 0, time.UTC))
	if err != nil {
		panic(err)
	}
	client, err := ghclient.New("", server.URL+"/", 100)
	if err != nil {
		panic(err)
	}
	result, err := client.CollectPRs(context.Background(), q)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.Workflow, result.Count)
}
Output:
pr-activity 0

func (*Client) Cost added in v1.1.0

func (c *Client) Cost() model.CostReport

Cost reports what this client has consumed and the latest quota observation. It returns a zero report when the client was built without WithRequestBudget, and is safe to call at any point including after a failure — a query that stopped early must still report what it spent.

func (*Client) EstimateActivity added in v1.1.0

func (c *Client) EstimateActivity(ctx context.Context, q model.ActivityQuery) (model.CostReport, error)

EstimateActivity reports the projected cost of a query without gathering its evidence.

A per_page=1 probe uses LastPage to count the repository window (research R4). Author-filtered queries need a second probe for their separate commit view. Both probes are counted. Detail file-page counts are unknown, so enrichment assumes one page per commit and may cost more than projected.

type Option added in v1.1.0

type Option func(*Client)

Option configures a Client at construction time. New takes options variadically, so every existing three-argument call site stays source-compatible.

func WithRequestBudget added in v1.1.0

func WithRequestBudget(ceiling int) Option

WithRequestBudget caps the provider requests the client may consume and enables cost accounting.

A ceiling of 0 disables the cap but still accounts: accounting is never optional, only enforcement is, so an intentional uncapped run can still report what it spent. Negative ceilings are treated as 0.

Enforcement happens in the transport, which means it covers every request the client makes — pagination and retries included — without any call site needing to know about it.

Jump to

Keyboard shortcuts

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