dmitri.shuralyov.com/service/change/...

githubapi: Use github.Router for PR HTML URLs.

This allows overriding where GitHub PRs can be viewed.

Similar to https://github.com/shurcooL/issues/commit/1cc2d579af3959bb9742445861b47a65a68c1a18.
dmitshur committed 6 years ago commit fc8c6aa79f17ce892e73e9f5422bb8b24becdd14
Collapse all
githubapi/githubapi.go
@@ -7,12 +7,13 @@ import (
	"fmt"
	"log"
	"sort"
	"strings"

	"dmitri.shuralyov.com/route/github"
	"dmitri.shuralyov.com/service/change"
	"github.com/google/go-github/github"
	githubv3 "github.com/google/go-github/github"
	"github.com/shurcooL/githubql"
	"github.com/shurcooL/issues"
	"github.com/shurcooL/notifications"
	"github.com/shurcooL/reactions"
	"github.com/shurcooL/users"
@@ -20,21 +21,28 @@ import (

// NewService creates a GitHub-backed change.Service using given GitHub clients.
// It uses notifications service, if not nil. At this time it infers the current user
// from GitHub clients (their authentication info), and cannot be used to serve multiple users.
// Both GitHub clients must use same authentication info.
func NewService(clientV3 *github.Client, clientV4 *githubql.Client, notifications notifications.ExternalService) change.Service {
//
// If router is nil, github.DotCom router is used, which links to subjects on github.com.
func NewService(clientV3 *githubv3.Client, clientV4 *githubql.Client, notifications notifications.ExternalService, router github.Router) change.Service {
	if router == nil {
		router = github.DotCom{}
	}
	return service{
		clV3:          clientV3,
		clV4:          clientV4,
		rtr:           router,
		notifications: notifications,
	}
}

type service struct {
	clV3 *github.Client   // GitHub REST API v3 client.
	clV3 *githubv3.Client // GitHub REST API v3 client.
	clV4 *githubql.Client // GitHub GraphQL API v4 client.
	rtr  github.Router

	// notifications may be nil if there's no notifications service.
	notifications notifications.ExternalService
}

@@ -204,11 +212,11 @@ func (s service) ListCommits(ctx context.Context, rs string, id uint64) ([]chang
	repo, err := ghRepoSpec(rs)
	if err != nil {
		// TODO: Map to 400 Bad Request HTTP error.
		return nil, err
	}
	cs, _, err := s.clV3.PullRequests.ListCommits(ctx, repo.Owner, repo.Repo, int(id), &github.ListOptions{PerPage: 100}) // TODO: Pagination.
	cs, _, err := s.clV3.PullRequests.ListCommits(ctx, repo.Owner, repo.Repo, int(id), &githubv3.ListOptions{PerPage: 100}) // TODO: Pagination.
	if err != nil {
		return nil, err
	}
	var commits []change.Commit
	for _, c := range cs {
@@ -228,17 +236,17 @@ func (s service) GetDiff(ctx context.Context, rs string, id uint64, opt *change.
		// TODO: Map to 400 Bad Request HTTP error.
		return nil, err
	}
	switch opt {
	case nil:
		diff, _, err := s.clV3.PullRequests.GetRaw(ctx, repo.Owner, repo.Repo, int(id), github.RawOptions{Type: github.Diff})
		diff, _, err := s.clV3.PullRequests.GetRaw(ctx, repo.Owner, repo.Repo, int(id), githubv3.RawOptions{Type: githubv3.Diff})
		if err != nil {
			return nil, err
		}
		return []byte(diff), nil
	default:
		diff, _, err := s.clV3.Repositories.GetCommitRaw(ctx, repo.Owner, repo.Repo, opt.Commit, github.RawOptions{Type: github.Diff})
		diff, _, err := s.clV3.Repositories.GetCommitRaw(ctx, repo.Owner, repo.Repo, opt.Commit, githubv3.RawOptions{Type: githubv3.Diff})
		if err != nil {
			return nil, err
		}
		return []byte(diff), nil
	}
@@ -282,13 +290,17 @@ func (s service) ListTimeline(ctx context.Context, rs string, id uint64, opt *ch
						ClosedEvent struct {
							event
							Closer struct {
								Typename    string `graphql:"__typename"`
								PullRequest struct {
									State githubql.PullRequestState
									Title string
									URL   string
									State      githubql.PullRequestState
									Title      string
									Repository struct {
										Owner struct{ Login string }
										Name  string
									}
									Number uint64
								} `graphql:"...on PullRequest"`
								Commit struct {
									OID     string
									Message string
									Author  struct {
@@ -482,11 +494,11 @@ func (s service) ListTimeline(ctx context.Context, rs string, id uint64, opt *ch
				e.Payload = change.ClosedEvent{
					Closer: change.Change{
						State: ghPRState(pr.State),
						Title: pr.Title,
					},
					CloserHTMLURL: pr.URL,
					CloserHTMLURL: s.rtr.PullRequestURL(ctx, pr.Repository.Owner.Login, pr.Repository.Name, pr.Number),
				}
			case "Commit":
				c := event.ClosedEvent.Closer.Commit
				e.Payload = change.ClosedEvent{
					Closer: change.Commit{
@@ -790,11 +802,11 @@ func ghUser(user *githubqlUser) users.User {
		AvatarURL: user.AvatarURL,
		HTMLURL:   user.URL,
	}
}

func ghV3UserOrGitUser(user *github.User, gitUser github.CommitAuthor) users.User {
func ghV3UserOrGitUser(user *githubv3.User, gitUser githubv3.CommitAuthor) users.User {
	if user == nil {
		return users.User{
			Name:      *gitUser.Name,
			Email:     *gitUser.Email,
			AvatarURL: "https://secure.gravatar.com/avatar?d=mm&f=y&s=96", // TODO: Use email.