dmitri.shuralyov.com/app/changes

Update import paths.
dmitshur committed 6 years ago commit 30f9fab1751529ac3d77ad7bab604a70079e3b6d
Showing partial commit. Full Commit
Collapse all
commits.go
@@ -1,12 +1,12 @@
package changesapp
package changes

import (
	"strings"

	"dmitri.shuralyov.com/changes"
	"dmitri.shuralyov.com/changes/app/component"
	"dmitri.shuralyov.com/app/changes/component"
	"dmitri.shuralyov.com/service/change"
	homecomponent "github.com/shurcooL/home/component"
	"github.com/shurcooL/htmlg"
	"golang.org/x/net/html"
	"golang.org/x/net/html/atom"
)
@@ -32,11 +32,11 @@ func (cs Commits) Render() []*html.Node {
	}
	return []*html.Node{htmlg.DivClass("list-entry-border", nodes...)}
}

type Commit struct {
	changes.Commit
	change.Commit
}

func (c Commit) Render() []*html.Node {
	div := &html.Node{
		Type: html.ElementNode, Data: atom.Div.String(),
display.go
@@ -1,17 +1,17 @@
package changesapp
package changes

import (
	"bytes"
	"fmt"
	"html/template"
	"sort"
	"strings"
	"time"

	"dmitri.shuralyov.com/changes"
	"dmitri.shuralyov.com/changes/app/component"
	"dmitri.shuralyov.com/app/changes/component"
	"dmitri.shuralyov.com/service/change"
	"github.com/shurcooL/highlight_diff"
	"github.com/shurcooL/htmlg"
	"github.com/shurcooL/users"
	"github.com/sourcegraph/annotate"
	"golang.org/x/net/html"
@@ -25,41 +25,41 @@ type timelineItem struct {
	TimelineItem interface{}
}

func (i timelineItem) TemplateName() string {
	switch i.TimelineItem.(type) {
	case changes.Comment:
	case change.Comment:
		return "comment"
	case changes.Review:
	case change.Review:
		return "review"
	case changes.TimelineItem:
	case change.TimelineItem:
		return "event"
	default:
		panic(fmt.Errorf("unknown item type %T", i.TimelineItem))
	}
}

func (i timelineItem) CreatedAt() time.Time {
	switch i := i.TimelineItem.(type) {
	case changes.Comment:
	case change.Comment:
		return i.CreatedAt
	case changes.Review:
	case change.Review:
		return i.CreatedAt
	case changes.TimelineItem:
	case change.TimelineItem:
		return i.CreatedAt
	default:
		panic(fmt.Errorf("unknown item type %T", i))
	}
}

func (i timelineItem) ID() uint64 {
	switch i := i.TimelineItem.(type) {
	case changes.Comment:
	case change.Comment:
		return i.ID
	case changes.Review:
	case change.Review:
		return i.ID
	case changes.TimelineItem:
	case change.TimelineItem:
		return i.ID
	default:
		panic(fmt.Errorf("unknown item type %T", i))
	}
}
doc.go
@@ -1,2 +1,2 @@
// Package changesapp is a web frontend for a changes service.
package changesapp
// Package changes is a web frontend for a change tracking service.
package changes
errorhandler.go
@@ -1,6 +1,6 @@
package changesapp
package changes

import (
	"context"
	"errors"
	"fmt"
main.go
@@ -1,6 +1,6 @@
package changesapp
package changes

import (
	"bytes"
	"context"
	"encoding/json"
@@ -15,14 +15,14 @@ import (
	"sort"
	"strconv"
	"strings"
	"time"

	"dmitri.shuralyov.com/changes"
	"dmitri.shuralyov.com/changes/app/assets"
	"dmitri.shuralyov.com/changes/app/common"
	"dmitri.shuralyov.com/changes/app/component"
	"dmitri.shuralyov.com/app/changes/assets"
	"dmitri.shuralyov.com/app/changes/common"
	"dmitri.shuralyov.com/app/changes/component"
	"dmitri.shuralyov.com/service/change"
	"github.com/dustin/go-humanize"
	"github.com/shurcooL/github_flavored_markdown"
	"github.com/shurcooL/htmlg"
	"github.com/shurcooL/httperror"
	"github.com/shurcooL/httpfs/html/vfstemplate"
@@ -34,11 +34,11 @@ import (
	"github.com/shurcooL/users"
	"golang.org/x/net/html"
	"sourcegraph.com/sourcegraph/go-diff/diff"
)

// TODO: Find a better way for changesapp to be able to ensure registration of a top-level route:
// TODO: Find a better way for changes to be able to ensure registration of a top-level route:
//
// 	emojisHandler := httpgzip.FileServer(emojis.Assets, httpgzip.FileServerOptions{ServeError: httpgzip.Detailed})
// 	http.Handle("/emojis/", http.StripPrefix("/emojis", emojisHandler))
//
// So that it can depend on it.
@@ -50,18 +50,18 @@ import (
//
// In order to serve HTTP requests, the returned http.Handler expects each incoming
// request to have 2 parameters provided to it via RepoSpecContextKey and BaseURIContextKey
// context keys. For example:
//
// 	changesApp := changesapp.New(...)
// 	changesApp := changes.New(...)
//
// 	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// 		req = req.WithContext(context.WithValue(req.Context(), changesapp.RepoSpecContextKey, string(...)))
// 		req = req.WithContext(context.WithValue(req.Context(), changesapp.BaseURIContextKey, string(...)))
// 		req = req.WithContext(context.WithValue(req.Context(), changes.RepoSpecContextKey, string(...)))
// 		req = req.WithContext(context.WithValue(req.Context(), changes.BaseURIContextKey, string(...)))
// 		changesApp.ServeHTTP(w, req)
// 	})
func New(service changes.Service, users users.Service, opt Options) http.Handler {
func New(service change.Service, users users.Service, opt Options) http.Handler {
	static, err := loadTemplates(common.State{}, opt.BodyPre)
	if err != nil {
		log.Fatalln("loadTemplates failed:", err)
	}
	h := handler{
@@ -98,14 +98,14 @@ type Options struct {

	// BodyTop provides components to include on top of <body> of page rendered for req. It can be nil.
	BodyTop func(*http.Request, common.State) ([]htmlg.Component, error)
}

// handler handles all requests to changesapp. It acts like a request multiplexer,
// handler handles all requests to changes. It acts like a request multiplexer,
// choosing from various endpoints and parsing the repository ID from URL.
type handler struct {
	is changes.Service
	is change.Service
	us users.Service // May be nil if there's no users service.

	assetsFileServer http.Handler
	gfmFileServer    http.Handler

@@ -115,14 +115,14 @@ type handler struct {
	Options
}

func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) error {
	if _, ok := req.Context().Value(RepoSpecContextKey).(string); !ok {
		return fmt.Errorf("request to %v doesn't have changesapp.RepoSpecContextKey context key set", req.URL.Path)
		return fmt.Errorf("request to %v doesn't have changes.RepoSpecContextKey context key set", req.URL.Path)
	}
	if _, ok := req.Context().Value(BaseURIContextKey).(string); !ok {
		return fmt.Errorf("request to %v doesn't have changesapp.BaseURIContextKey context key set", req.URL.Path)
		return fmt.Errorf("request to %v doesn't have changes.BaseURIContextKey context key set", req.URL.Path)
	}

	// Handle "/assets/gfm/...".
	if strings.HasPrefix(req.URL.Path, "/assets/gfm/") {
		req = stripPrefix(req, len("/assets/gfm"))
@@ -192,19 +192,19 @@ func (h *handler) ChangesHandler(w http.ResponseWriter, req *http.Request) error
	}
	filter, err := stateFilter(req.URL.Query())
	if err != nil {
		return httperror.BadRequest{Err: err}
	}
	is, err := h.is.List(req.Context(), state.RepoSpec, changes.ListOptions{Filter: filter})
	is, err := h.is.List(req.Context(), state.RepoSpec, change.ListOptions{Filter: filter})
	if err != nil {
		return err
	}
	openCount, err := h.is.Count(req.Context(), state.RepoSpec, changes.ListOptions{Filter: changes.FilterOpen})
	openCount, err := h.is.Count(req.Context(), state.RepoSpec, change.ListOptions{Filter: change.FilterOpen})
	if err != nil {
		return fmt.Errorf("changes.Count(open): %v", err)
	}
	closedCount, err := h.is.Count(req.Context(), state.RepoSpec, changes.ListOptions{Filter: changes.FilterClosedMerged})
	closedCount, err := h.is.Count(req.Context(), state.RepoSpec, change.ListOptions{Filter: change.FilterClosedMerged})
	if err != nil {
		return fmt.Errorf("changes.Count(closed): %v", err)
	}
	var es []component.ChangeEntry
	for _, i := range is {
@@ -235,25 +235,25 @@ const (
	stateQueryKey = "state"
)

// stateFilter parses the change state filter from query,
// returning an error if the value is unsupported.
func stateFilter(query url.Values) (changes.StateFilter, error) {
func stateFilter(query url.Values) (change.StateFilter, error) {
	selectedTabName := query.Get(stateQueryKey)
	switch selectedTabName {
	case "":
		return changes.FilterOpen, nil
		return change.FilterOpen, nil
	case "closed":
		return changes.FilterClosedMerged, nil
		return change.FilterClosedMerged, nil
	case "all":
		return changes.FilterAll, nil
		return change.FilterAll, nil
	default:
		return "", fmt.Errorf("unsupported state filter value: %q", selectedTabName)
	}
}

func (s state) augmentUnread(ctx context.Context, es []component.ChangeEntry, is changes.Service, notificationsService notifications.Service) []component.ChangeEntry {
func (s state) augmentUnread(ctx context.Context, es []component.ChangeEntry, is change.Service, notificationsService notifications.Service) []component.ChangeEntry {
	if notificationsService == nil {
		return es
	}

	tt, ok := is.(interface {
@@ -307,23 +307,23 @@ func (h *handler) MockHandler(w http.ResponseWriter, req *http.Request) error {
		return fmt.Errorf("loadTemplates: %v", err)
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	err = t.ExecuteTemplate(w, "review-mock", struct {
		state
		Review changes.Review
		Review change.Review
	}{
		state: st,
		Review: changes.Review{
		Review: change.Review{
			ID:        0,
			User:      users.User{Login: "Eric Grosse", AvatarURL: "https://lh6.googleusercontent.com/-_sdEtv2PRxk/AAAAAAAAAAI/AAAAAAAAAAA/aE1Q66Cuvb4/s100-p/photo.jpg"},
			CreatedAt: time.Now().UTC(),
			Edited:    nil,
			State:     changes.Approved,
			State:     change.Approved,
			Body:      "",
			Reactions: []reactions.Reaction{},
			Editable:  true,
			Comments: []changes.InlineComment{
			Comments: []change.InlineComment{
				{
					File: "rpc/keyserver/server.go",
					Line: 26,
					Body: "Ok by me, but how was this chosen?",
				},
@@ -446,13 +446,13 @@ func (h *handler) ChangeFilesHandler(w http.ResponseWriter, req *http.Request, c
		}
		if next := i + 1; next < len(cs) {
			commit.NextSHA = cs[next].SHA
		}
	}
	var opt *changes.GetDiffOptions
	var opt *change.GetDiffOptions
	if commitID != "" {
		opt = &changes.GetDiffOptions{Commit: commitID}
		opt = &change.GetDiffOptions{Commit: commitID}
	}
	rawDiff, err := h.is.GetDiff(req.Context(), state.RepoSpec, state.ChangeID, opt)
	if err != nil {
		return err
	}
@@ -481,11 +481,11 @@ func (h *handler) ChangeFilesHandler(w http.ResponseWriter, req *http.Request, c
	return err
}

// commitIndex returns the index of commit with SHA equal to commitID,
// or -1 if not found.
func commitIndex(cs []changes.Commit, commitID string) int {
func commitIndex(cs []change.Commit, commitID string) int {
	for i := range cs {
		if cs[i].SHA == commitID {
			return i
		}
	}
@@ -543,11 +543,11 @@ type state struct {
	BodyTop           template.HTML

	common.State

	Changes  component.Changes
	Change   changes.Change
	Change   change.Change
	Timeline []timelineItem
}

func (s state) Tabnav(selected string) template.HTML {
	// Render the tabnav.
@@ -622,12 +622,12 @@ func loadTemplates(state common.State, bodyPre string) (*template.Template, erro
		},

		"render": func(c htmlg.Component) template.HTML {
			return template.HTML(htmlg.Render(c.Render()...))
		},
		"event":            func(e changes.TimelineItem) htmlg.Component { return component.Event{Event: e} },
		"changeStateBadge": func(c changes.Change) htmlg.Component { return component.ChangeStateBadge{Change: c} },
		"event":            func(e change.TimelineItem) htmlg.Component { return component.Event{Event: e} },
		"changeStateBadge": func(c change.Change) htmlg.Component { return component.ChangeStateBadge{Change: c} },
		"time":             func(t time.Time) htmlg.Component { return component.Time{Time: t} },
		"user":             func(u users.User) htmlg.Component { return component.User{User: u} },
		"avatar":           func(u users.User) htmlg.Component { return component.Avatar{User: u, Size: 48} },
	})
	t, err := vfstemplate.ParseGlob(assets.Assets, t, "/assets/*.tmpl")
@@ -642,11 +642,11 @@ func loadTemplates(state common.State, bodyPre string) (*template.Template, erro
type contextKey struct {
	name string
}

func (k *contextKey) String() string {
	return "dmitri.shuralyov.com/changes/app context value " + k.name
	return "dmitri.shuralyov.com/app/changes context value " + k.name
}

// stripPrefix returns request r with prefix of length prefixLen stripped from r.URL.Path.
// prefixLen must not be longer than len(r.URL.Path), otherwise stripPrefix panics.
// If r.URL.Path is empty after the prefix is stripped, the path is changed to "/".