github

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package github provides an HTTP client for the GitHub API.

Overview

This package fetches repository metrics from GitHub (https://api.github.com) for metadata enrichment. It provides data used by Nebraska ranking and brittle detection features.

Usage

client, err := github.NewClient(token, 24 * time.Hour)
if err != nil {
    log.Fatal(err)
}

metrics, err := client.Fetch(ctx, "pallets", "flask", false)
if err != nil {
    log.Fatal(err)
}

fmt.Println("Stars:", metrics.Stars)
fmt.Println("Contributors:", metrics.Contributors)

Authentication

A GitHub personal access token is optional but recommended to avoid rate limits. Without a token, the client is limited to 60 requests/hour. With a token, the limit is 5000 requests/hour.

RepoMetrics

[Fetch] returns an integrations.RepoMetrics containing:

  • Stars: Stargazer count
  • Owner: Repository owner login
  • Contributors: Top 5 contributors with commit counts
  • LastCommitAt: Most recent push date
  • LastReleaseAt: Most recent release date
  • Archived: Whether the repository is archived
  • License, Language, Topics: Additional metadata

Caching

Responses are cached to reduce API calls. The cache TTL is set when creating the client. Pass refresh=true to bypass the cache.

URL Extraction

ExtractURL parses GitHub repository URLs from package metadata, handling various URL formats (with/without .git, trailing slashes, etc.).

[SearchPackageRepo] searches GitHub code for manifest files containing a package name, useful for finding repository URLs when not provided by the package registry.

Index

Constants

View Source
const DefaultClientID = "Ov23liyPM58WU6hMeP7E"

DefaultClientID is the OAuth App Client ID for Stacktower. This is public and safe to commit - only the Client Secret must be kept private. The Device Flow doesn't require a secret, only the Client ID.

To use your own OAuth App, set GITHUB_CLIENT_ID env var.

Variables

This section is empty.

Functions

func DetectLanguageFromManifest added in v1.0.0

func DetectLanguageFromManifest(path string) string

DetectLanguageFromManifest determines the language from a manifest filename.

func ExtractURL

func ExtractURL(urls map[string]string, homepage string) (owner, repo string, ok bool)

ExtractURL extracts GitHub repository owner and name from package URLs.

This function searches through urls map and homepage for GitHub URLs. It looks for patterns like "https://github.com/owner/repo".

Parameters:

  • urls: Map of URL keys to URL values from package metadata (may be nil)
  • homepage: Fallback homepage URL (may be empty)

Returns:

  • owner: Repository owner username (empty if not found)
  • repo: Repository name (empty if not found)
  • ok: true if a GitHub URL was found, false otherwise

This function is safe for concurrent use.

func ParseRepoRef added in v1.0.0

func ParseRepoRef(ref string) (owner, repo string, err error)

ParseRepoRef parses an "owner/repo" string and validates both parts. Returns owner, repo, and any validation error.

func ValidateOwner added in v1.0.0

func ValidateOwner(owner string) error

ValidateOwner validates a GitHub username or organization name.

func ValidateRepo added in v1.0.0

func ValidateRepo(repo string) error

ValidateRepo validates a GitHub repository name.

func ValidateRepoRef added in v1.0.0

func ValidateRepoRef(owner, repo string) error

ValidateRepoRef validates both owner and repo parameters.

Types

type Client

type Client struct {
	*integrations.Client
	// contains filtered or unexported fields
}

Client provides access to the GitHub API for repository metadata enrichment. It handles HTTP requests with caching, automatic retries, and optional authentication.

All methods are safe for concurrent use by multiple goroutines.

func NewClient

func NewClient(backend cache.Cache, token string, cacheTTL time.Duration) *Client

NewClient creates a GitHub API client with optional authentication.

Parameters:

  • backend: Cache backend for HTTP response caching (use storage.NullBackend{} for no caching)
  • token: GitHub personal access token (empty string for unauthenticated)
  • cacheTTL: How long responses are cached (typical: 1-24 hours)

Rate limits:

  • Unauthenticated: 60 requests/hour per IP
  • Authenticated: 5,000 requests/hour per token

Authentication is strongly recommended for production use to avoid rate limiting. The returned Client is safe for concurrent use.

func (*Client) Fetch

func (c *Client) Fetch(ctx context.Context, owner, repo string, refresh bool) (*integrations.RepoMetrics, error)

Fetch retrieves repository metrics (stars, maintainers, activity) from GitHub.

Parameters:

  • owner: Repository owner username (e.g., "pallets")
  • repo: Repository name (e.g., "flask")
  • refresh: If true, bypass cache and fetch fresh data

The method performs up to 3 API calls:

  1. Repository metadata (required)
  2. Latest release data (optional, silently ignored if no releases)
  3. Contributors list (optional, top 5, silently ignored on failure)

If refresh is true, the cache is bypassed and a fresh API call is made. If refresh is false, cached data is returned if available and not expired.

Returns:

The returned RepoMetrics pointer is never nil if err is nil. This method is safe for concurrent use.

func (*Client) SearchPackageRepo

func (c *Client) SearchPackageRepo(ctx context.Context, pkgName, manifestFile string) (owner, repo string, ok bool)

SearchPackageRepo searches GitHub code for a manifest file containing a package name.

This is useful for finding repository URLs when package metadata doesn't include them.

Parameters:

  • pkgName: Package name to search for (exact match in manifest file)
  • manifestFile: Manifest filename to search in (e.g., "package.json", "Gemfile")

Example:

owner, repo, ok := client.SearchPackageRepo(ctx, "fastapi", "pyproject.toml")

Returns:

  • owner: Repository owner username (empty if not found)
  • repo: Repository name (empty if not found)
  • ok: true if a match was found, false otherwise

Search results are always cached (refresh=false) to conserve GitHub API quota. This method is safe for concurrent use.

type CodeSearchResult added in v1.0.0

type CodeSearchResult struct {
	Name    string   `json:"name"`
	Path    string   `json:"path"`
	Matches []string `json:"matches,omitempty"`
}

CodeSearchResult represents a code search match.

type ContentClient added in v1.0.0

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

ContentClient provides access to GitHub repository content. Use this for fetching files, listing directories, and user operations.

func NewContentClient added in v1.0.0

func NewContentClient(token string) *ContentClient

NewContentClient creates a new content client with the given access token.

func (*ContentClient) DetectManifests added in v1.0.0

func (c *ContentClient) DetectManifests(ctx context.Context, owner, repo string, patterns map[string]string) ([]ManifestFile, error)

DetectManifests finds manifest files in a repository's root directory. The patterns map filename -> language name (e.g., "go.mod" -> "go"). Use deps.SupportedManifests(languages) to get patterns from the deps package.

func (*ContentClient) FetchFile added in v1.0.0

func (c *ContentClient) FetchFile(ctx context.Context, owner, repo, path string) (*FileContent, error)

FetchFile retrieves the content of a file from a repository. The content is returned as a string (decoded from base64).

func (*ContentClient) FetchFileRaw added in v1.0.0

func (c *ContentClient) FetchFileRaw(ctx context.Context, owner, repo, path string) (string, error)

FetchFileRaw retrieves the raw content of a file from a repository. This is more efficient for large files as it doesn't use base64 encoding.

func (*ContentClient) FetchUser added in v1.0.0

func (c *ContentClient) FetchUser(ctx context.Context) (*User, error)

FetchUser retrieves the authenticated user's info.

func (*ContentClient) FetchUserRepos added in v1.0.0

func (c *ContentClient) FetchUserRepos(ctx context.Context) ([]Repo, error)

FetchUserRepos retrieves all of the authenticated user's repositories. This includes private repos if the OAuth token has the 'repo' scope. Results are paginated automatically to retrieve all repos.

func (*ContentClient) GetRepoInfo added in v1.0.0

func (c *ContentClient) GetRepoInfo(ctx context.Context, owner, repo string) (*RepoInfo, error)

GetRepoInfo retrieves repository metadata.

func (*ContentClient) GetTree added in v1.0.0

func (c *ContentClient) GetTree(ctx context.Context, owner, repo, branch string) ([]TreeEntry, error)

GetTree retrieves the full file tree of a repository.

func (*ContentClient) ListContents added in v1.0.0

func (c *ContentClient) ListContents(ctx context.Context, owner, repo, path string) ([]ContentItem, error)

ListContents lists files and directories in a repository path.

func (*ContentClient) ScanReposForManifests added in v1.0.0

func (c *ContentClient) ScanReposForManifests(ctx context.Context, manifestPatterns map[string]string, publicOnly bool) ([]RepoWithManifests, error)

ScanReposForManifests fetches repos and detects manifests in parallel. It returns repos sorted by UpdatedAt (most recent first). The manifestPatterns map should be filename -> language (use deps.SupportedManifests). Set publicOnly=true to filter out private repos.

func (*ContentClient) SearchCode added in v1.0.0

func (c *ContentClient) SearchCode(ctx context.Context, owner, repo, query string) ([]CodeSearchResult, error)

SearchCode searches for code in a repository. Query follows GitHub code search syntax: https://docs.github.com/en/search-github/searching-on-github/searching-code

type ContentItem added in v1.0.0

type ContentItem struct {
	Name string `json:"name"`
	Path string `json:"path"`
	Type string `json:"type"` // "file" or "dir"
	Size int    `json:"size"`
}

ContentItem represents an item in a repository directory listing.

type DeviceCodeResponse added in v1.0.0

type DeviceCodeResponse struct {
	DeviceCode      string `json:"device_code"`
	UserCode        string `json:"user_code"`
	VerificationURI string `json:"verification_uri"`
	ExpiresIn       int    `json:"expires_in"`
	Interval        int    `json:"interval"`
}

DeviceCodeResponse contains the response from requesting a device code.

type FileContent added in v1.0.0

type FileContent struct {
	Path    string `json:"path"`
	Size    int    `json:"size"`
	Content string `json:"content"`
}

FileContent represents the content of a file.

type ManifestFile added in v1.0.0

type ManifestFile struct {
	Path     string `json:"path"`
	Language string `json:"language"`
	Name     string `json:"name"`
}

ManifestFile represents a detected manifest file.

type OAuthClient added in v1.0.0

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

OAuthClient handles GitHub OAuth operations.

func NewOAuthClient added in v1.0.0

func NewOAuthClient(config OAuthConfig) *OAuthClient

NewOAuthClient creates a new OAuth client.

func (*OAuthClient) AuthorizationURL added in v1.0.0

func (c *OAuthClient) AuthorizationURL(state string) string

AuthorizationURL returns the GitHub OAuth authorization URL.

func (*OAuthClient) ExchangeCode added in v1.0.0

func (c *OAuthClient) ExchangeCode(code string) (*OAuthToken, error)

ExchangeCode exchanges an authorization code for an access token.

func (*OAuthClient) PollForToken added in v1.0.0

func (c *OAuthClient) PollForToken(ctx context.Context, deviceCode string, interval int) (*OAuthToken, error)

PollForToken polls GitHub for the access token after user authorization. It respects the interval from the device code response. Returns the token when authorized, or an error if expired/denied.

func (*OAuthClient) RequestDeviceCode added in v1.0.0

func (c *OAuthClient) RequestDeviceCode(ctx context.Context) (*DeviceCodeResponse, error)

RequestDeviceCode initiates the device authorization flow. The user must visit the VerificationURI and enter the UserCode.

type OAuthConfig added in v1.0.0

type OAuthConfig struct {
	ClientID     string
	ClientSecret string
	RedirectURI  string
}

OAuthConfig holds OAuth configuration.

type OAuthToken added in v1.0.0

type OAuthToken struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	Scope       string `json:"scope"`
}

OAuthToken represents an OAuth access token response.

type Repo added in v1.0.0

type Repo struct {
	ID            int64  `json:"id"`
	Name          string `json:"name"`
	FullName      string `json:"full_name"`
	Description   string `json:"description"`
	Private       bool   `json:"private"`
	DefaultBranch string `json:"default_branch"`
	Language      string `json:"language"`
	UpdatedAt     string `json:"updated_at"`
}

Repo represents a GitHub repository.

type RepoInfo added in v1.0.0

type RepoInfo struct {
	Name          string   `json:"name"`
	FullName      string   `json:"full_name"`
	Description   string   `json:"description"`
	Language      string   `json:"language"`
	DefaultBranch string   `json:"default_branch"`
	Stars         int      `json:"stars"`
	Forks         int      `json:"forks"`
	OpenIssues    int      `json:"open_issues"`
	License       string   `json:"license"`
	Topics        []string `json:"topics"`
	Archived      bool     `json:"archived"`
}

RepoInfo contains repository metadata.

type RepoWithManifests added in v1.0.0

type RepoWithManifests struct {
	Repo      Repo           `json:"repo"`
	Manifests []ManifestFile `json:"manifests,omitempty"`
}

RepoWithManifests holds a repo and its detected manifest files.

type TreeEntry added in v1.0.0

type TreeEntry struct {
	Path string `json:"path"`
	Type string `json:"type"` // "blob" or "tree"
	Size int    `json:"size,omitempty"`
}

TreeEntry represents a file or directory in the repository tree.

type User added in v1.0.0

type User struct {
	ID        int64  `json:"id"`
	Login     string `json:"login"`
	Name      string `json:"name"`
	AvatarURL string `json:"avatar_url"`
	Email     string `json:"email"`
}

User represents a GitHub user.

Jump to

Keyboard shortcuts

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