Documentation
¶
Overview ¶
Package github implements sync mechanism to mirror GitHub issue state into a storage.DB as well as code to inspect that state and to make issue changes on GitHub. All the functionality is provided by the Client, created by New.
Index ¶
- func Scrub(req *http.Request) error
- type Client
- func (c *Client) Add(project string) error
- func (c *Client) DownloadIssue(url string) (*Issue, error)
- func (c *Client) DownloadIssueComment(url string) (*IssueComment, error)
- func (c *Client) EditIssue(issue *Issue, changes *IssueChanges) error
- func (c *Client) EditIssueComment(comment *IssueComment, changes *IssueCommentChanges) error
- func (c *Client) EnableTesting()
- func (c *Client) EventWatcher(name string) *timed.Watcher[*Event]
- func (c *Client) Events(project string, issueMin, issueMax int64) iter.Seq[*Event]
- func (c *Client) EventsAfter(t timed.DBTime, project string) iter.Seq[*Event]
- func (c *Client) LookupIssueURL(url string) (*Issue, error)
- func (c *Client) PostIssueComment(issue *Issue, changes *IssueCommentChanges) error
- func (c *Client) Sync() error
- func (c *Client) SyncProject(project string) (err error)
- func (c *Client) Testing() *TestingClient
- type Event
- type Issue
- type IssueChanges
- type IssueComment
- type IssueCommentChanges
- type IssueEvent
- type Label
- type Milestone
- type Rename
- type TestingClient
- func (tc *TestingClient) AddIssue(project string, issue *Issue)
- func (tc *TestingClient) AddIssueComment(project string, issue int64, comment *IssueComment)
- func (tc *TestingClient) AddIssueEvent(project string, issue int64, event *IssueEvent)
- func (tc *TestingClient) ClearEdits()
- func (tc *TestingClient) Edits() []*TestingEdit
- func (tc *TestingClient) LoadTxtar(file string) error
- func (tc *TestingClient) LoadTxtarData(data []byte) error
- type TestingEdit
- type User
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
A Client is a connection to GitHub state in a database and on GitHub itself.
func New ¶
New returns a new client that uses the given logger, databases, and HTTP client.
The secret database is expected to have a secret named "api.github.com" of the form "user:pass" where user is a user-name (ignored by GitHub) and pass is an API token ("ghp_...").
func (*Client) Add ¶
Add adds a GitHub project of the form "owner/repo" (for example "golang/go") to the database. It only adds the project sync metadata. The initial data fetch does not happen until [Sync] or [SyncProject] is called. Add returns an error if the project has already been added.
func (*Client) DownloadIssue ¶
DownloadIssue downloads the current issue JSON from the given URL and decodes it into an issue. Given an issue, c.DownloadIssue(issue.URL) fetches the very latest state for the issue.
func (*Client) DownloadIssueComment ¶
func (c *Client) DownloadIssueComment(url string) (*IssueComment, error)
DownloadIssueComment downloads the current comment JSON from the given URL and decodes it into an IssueComment. Given a comment, c.DownloadIssueComment(comment.URL) fetches the very latest state for the comment.
func (*Client) EditIssue ¶
func (c *Client) EditIssue(issue *Issue, changes *IssueChanges) error
EditIssue applies the changes to issue on GitHub.
func (*Client) EditIssueComment ¶
func (c *Client) EditIssueComment(comment *IssueComment, changes *IssueCommentChanges) error
EditIssueComment changes the comment on GitHub to have the new body. It is typically a good idea to use c.DownloadIssueComment first and check that the live comment body matches the one obtained from the database, to minimize race windows.
func (*Client) EnableTesting ¶
func (c *Client) EnableTesting()
EnableTesting enables testing mode, in which edits are diverted and a TestingClient is available. If the program is itself a test binary (built or run using “go test”), testing mode is enabled automatically. EnableTesting can be useful in experimental programs to make sure that no edits are applied to GitHub.
func (*Client) EventWatcher ¶
EventWatcher returns a new storage.Watcher with the given name. It picks up where any previous Watcher of the same name left off.
func (*Client) Events ¶
Events returns an iterator over issue events for the given project, limited to issues in the range issueMin ≤ issue ≤ issueMax. If issueMax < 0, there is no upper limit. The events are iterated over in (Project, Issue, API, ID) order, so "/issues" events come first, then "/issues/comments", then "/issues/events". Within a specific API, the events are ordered by increasing ID, which corresponds to increasing event time on GitHub.
func (*Client) EventsAfter ¶
EventsAfter returns an iterator over events in the given project after DBTime t, which should be e.DBTime from the most recent processed event. The events are iterated over in DBTime order, so the DBTime of the last successfully processed event can be used in a future call to EventsAfter. If project is the empty string, then events from all projects are returned.
func (*Client) LookupIssueURL ¶
LookupIssueURL looks up an issue by URL, only consulting the database (not actual GitHub).
func (*Client) PostIssueComment ¶
func (c *Client) PostIssueComment(issue *Issue, changes *IssueCommentChanges) error
PostIssueComment posts a new comment with the given body (written in Markdown) on issue.
func (*Client) SyncProject ¶
SyncProject syncs a single project.
func (*Client) Testing ¶
func (c *Client) Testing() *TestingClient
Testing returns a TestingClient, which provides access to Client functionality intended for testing. Testing only returns a non-nil TestingClient in testing mode, which is active if the current program is a test binary (that is, testing.Testing returns true) or if Client.EnableTesting has been called. Otherwise, Testing returns nil.
Each Client has only one TestingClient associated with it. Every call to Testing returns the same TestingClient.
type Event ¶
type Event struct { DBTime timed.DBTime // when event was last written Project string // project ("golang/go") Issue int64 // issue number API string // API endpoint for event: "/issues", "/issues/comments", or "/issues/events" ID int64 // ID of event; each API has a different ID space. (Project, Issue, API, ID) is assumed unique JSON []byte // JSON for the event data Typed any // Typed unmarshaling of the event data, of type *Issue, *IssueComment, or *IssueEvent }
An Event is a single GitHub issue event stored in the database.
type Issue ¶
type Issue struct { URL string `json:"url"` HTMLURL string `json:"html_url"` Number int64 `json:"number"` User User `json:"user"` Title string `json:"title"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` ClosedAt string `json:"closed_at"` Body string `json:"body"` Assignees []User `json:"assignees"` Milestone Milestone `json:"milestone"` State string `json:"state"` PullRequest *struct{} `json:"pull_request"` Locked bool ActiveLockReason string `json:"active_lock_reason"` Labels []Label `json:"labels"` }
Issue is the GitHub JSON structure for an issue creation event.
type IssueChanges ¶
type IssueChanges struct { Title string `json:"title,omitempty"` Body string `json:"body,omitempty"` State string `json:"state,omitempty"` Labels *[]string `json:"labels,omitempty"` }
An IssueChanges specifies changes to make to an issue. Fields that are the empty string or a nil pointer are ignored.
Note that Labels is the new set of all labels for the issue, not labels to add. If you are adding a single label, you need to include all the existing labels as well. Labels is a *[]string so that it can be set to new([]string) to clear the labels.
type IssueComment ¶
type IssueComment struct { URL string `json:"url"` IssueURL string `json:"issue_url"` HTMLURL string `json:"html_url"` User User `json:"user"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` Body string `json:"body"` }
IssueComment is the GitHub JSON structure for an issue comment event.
func (*IssueComment) CommentID ¶
func (x *IssueComment) CommentID() int64
CommentID returns the issue comment's numeric ID. The ID appears to be unique across all comments on GitHub, but we only assume it is unique within a single issue.
func (*IssueComment) Issue ¶
func (x *IssueComment) Issue() int64
Issue returns the issue comment's issue number.
func (*IssueComment) Project ¶
func (x *IssueComment) Project() string
Project returns the issue comment's GitHub project (for example, "golang/go").
type IssueCommentChanges ¶
type IssueCommentChanges struct {
Body string `json:"body,omitempty"`
}
type IssueEvent ¶
type IssueEvent struct { // NOTE: Issue field is not present when downloading for a specific issue, // only in the master feed for the whole repo. So do not add it here. ID int64 URL string Actor User `json:"actor"` Event string `json:"event"` Labels []Label `json:"labels"` LockReason string `json:"lock_reason"` CreatedAt string `json:"created_at"` CommitID string `json:"commit_id"` Assigner User `json:"assigner"` Assignees []User `json:"assignees"` Milestone Milestone `json:"milestone"` Rename Rename `json:"rename"` }
IssueEvent is the GitHub JSON structure for an issue metadata event.
type Label ¶
type Label struct {
Name string
}
A Label represents a project issue tracker label in GitHub JSON.
type Milestone ¶
type Milestone struct {
Title string
}
A Milestone represents a project issue milestone in GitHub JSON.
type TestingClient ¶
type TestingClient struct {
// contains filtered or unexported fields
}
A TestingClient provides access to Client functionality intended for testing.
See Client.Testing for a description of testing mode.
func (*TestingClient) AddIssue ¶
func (tc *TestingClient) AddIssue(project string, issue *Issue)
AddIssue adds the given issue to the identified project, assigning it a new issue number starting at 10⁹. AddIssue creates a new entry in the associated Client's underlying database, so other Client's using the same database will see the issue too.
NOTE: Only one TestingClient should be adding issues, since they do not coordinate in the database about ID assignment. Perhaps they should, but normally there is just one Client.
func (*TestingClient) AddIssueComment ¶
func (tc *TestingClient) AddIssueComment(project string, issue int64, comment *IssueComment)
AddIssueComment adds the given issue comment to the identified project issue, assigning it a new comment ID starting at 10¹⁰. AddIssueComment creates a new entry in the associated Client's underlying database, so other Client's using the same database will see the issue comment too.
NOTE: Only one TestingClient should be adding issues, since they do not coordinate in the database about ID assignment. Perhaps they should, but normally there is just one Client.
func (*TestingClient) AddIssueEvent ¶
func (tc *TestingClient) AddIssueEvent(project string, issue int64, event *IssueEvent)
AddIssueEvent adds the given issue event to the identified project issue, assigning it a new comment ID starting at 10¹¹. AddIssueEvent creates a new entry in the associated Client's underlying database, so other Client's using the same database will see the issue event too.
NOTE: Only one TestingClient should be adding issues, since they do not coordinate in the database about ID assignment. Perhaps they should, but normally there is just one Client.
func (*TestingClient) ClearEdits ¶
func (tc *TestingClient) ClearEdits()
ClearEdits clears the list of edits that are meant to be applied
func (*TestingClient) Edits ¶
func (tc *TestingClient) Edits() []*TestingEdit
Edits returns a list of all the edits that have been applied using Client methods (for example Client.EditIssue, Client.EditIssueComment, Client.PostIssueComment). These edits have not been applied on GitHub, only diverted into the TestingClient.
See Client.Testing for a description of testing mode.
NOTE: These edits are not applied to the underlying database, since they are also not applied to the underlying database when using a real connection to GitHub; instead we wait for the next sync to download GitHub's view of the edits. See Client.EditIssue.
func (*TestingClient) LoadTxtar ¶
func (tc *TestingClient) LoadTxtar(file string) error
LoadTxtar loads issue histories from the named txtar file, writing them to the database using TestingClient.AddIssue, TestingClient.AddIssueComment, and TestingClient.AddIssueEvent.
The file should contain a txtar archive (see golang.org/x/tools/txtar). Each file in the archive should be named “project#n” (for example “golang/go#123”) and contain an issue history in the format printed by the rsc.io/github/issue command. See the file ../testdata/rsctmp.txt for an example.
To download a specific set of issues into a new file, you can use a script like:
go install rsc.io/github/issue@latest project=golang/go (for i in 1 2 3 4 5 do echo "-- $project#$i --" issue -p $project $i done) > testdata/proj.txt
func (*TestingClient) LoadTxtarData ¶
func (tc *TestingClient) LoadTxtarData(data []byte) error
LoadTxtarData loads issue histories from the txtar file content data. See [LoadTxtar] for a description of the format.
type TestingEdit ¶
type TestingEdit struct { Project string Issue int64 Comment int64 IssueChanges *IssueChanges IssueCommentChanges *IssueCommentChanges }
A TestingEdit is a diverted edit, which was logged instead of actually applied on GitHub.
func (*TestingEdit) String ¶
func (e *TestingEdit) String() string
String returns a basic string representation of the edit.