forked from tangled.org/core
this repo has no description

appview: state: add RepoCompare{,Diff} handlers

Changed files
+197
appview
pages
templates
repo
compare
state
+28
appview/pages/pages.go
···
return p.executePlain("repo/pulls/fragments/pullNewComment", w, params)
}
+
type RepoCompareParams struct {
+
LoggedInUser *oauth.User
+
RepoInfo repoinfo.RepoInfo
+
Forks []db.Repo
+
Branches []types.Branch
+
Tags []*types.TagReference
+
+
Active string
+
}
+
+
func (p *Pages) RepoCompare(w io.Writer, params RepoCompareParams) error {
+
params.Active = "overview"
+
return p.executeRepo("repo/compare/new", w, params)
+
}
+
+
type RepoCompareDiffParams struct {
+
LoggedInUser *oauth.User
+
RepoInfo repoinfo.RepoInfo
+
FormatPatch types.RepoFormatPatchResponse
+
+
Active string
+
}
+
+
func (p *Pages) RepoCompareDiff(w io.Writer, params RepoCompareDiffParams) error {
+
params.Active = "overview"
+
return p.executeRepo("repo/compare/new", w, params)
+
}
+
func (p *Pages) Static() http.Handler {
if p.dev {
return http.StripPrefix("/static/", http.FileServer(http.Dir("appview/pages/static")))
+74
appview/pages/templates/repo/compare/new.html
···
+
{{ define "title" }}new comparison{{ end }}
+
+
{{ define "repoContent" }}
+
<h2 class="font-bold text-sm mb-4 uppercase dark:text-white">
+
Compare changes
+
</h2>
+
<p>Choose any two refs to compare.</p>
+
+
<div class="flex items-center gap-2 py-4">
+
<div>
+
base:
+
<select
+
class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"
+
>
+
<optgroup
+
label="branches ({{ len .Branches }})"
+
class="bold text-sm"
+
>
+
{{ range .Branches }}
+
<option
+
value="{{ .Reference.Name }}"
+
class="py-1"
+
{{ if .IsDefault }}
+
selected
+
{{ end }}
+
>
+
{{ .Reference.Name }}
+
</option>
+
{{ end }}
+
</optgroup>
+
<optgroup label="tags ({{ len .Tags }})" class="bold text-sm">
+
{{ range .Tags }}
+
<option value="{{ .Reference.Name }}" class="py-1">
+
{{ .Reference.Name }}
+
</option>
+
{{ else }}
+
<option class="py-1" disabled>no tags found</option>
+
{{ end }}
+
</optgroup>
+
</select>
+
</div>
+
{{ i "arrow-left" "w-4 h-4" }}
+
<div>
+
compare:
+
<select
+
class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"
+
>
+
<optgroup
+
label="branches ({{ len .Branches }})"
+
class="bold text-sm"
+
>
+
{{ range .Branches }}
+
<option value="{{ .Reference.Name }}" class="py-1">
+
{{ .Reference.Name }}
+
</option>
+
{{ end }}
+
</optgroup>
+
<optgroup label="tags ({{ len .Tags }})" class="bold text-sm">
+
{{ range .Tags }}
+
<option value="{{ .Reference.Name }}" class="py-1">
+
{{ .Reference.Name }}
+
</option>
+
{{ else }}
+
<option class="py-1" disabled>no tags found</option>
+
{{ end }}
+
</optgroup>
+
</select>
+
</div>
+
</div>
+
{{ end }}
+
+
{{ define "repoAfter" }}
+
<div id="compare-diff"></div>
+
{{ end }}
+84
appview/state/repo.go
···
return
+
+
func (s *State) RepoCompare(w http.ResponseWriter, r *http.Request) {
+
user := s.oauth.GetUser(r)
+
f, err := s.fullyResolvedRepo(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
+
return
+
}
+
+
us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
+
if err != nil {
+
log.Printf("failed to create unsigned client for %s", f.Knot)
+
s.pages.Error503(w)
+
return
+
}
+
+
branches, err := us.Branches(f.OwnerDid(), f.RepoName)
+
if err != nil {
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
+
log.Println("failed to reach knotserver", err)
+
return
+
}
+
+
tags, err := us.Tags(f.OwnerDid(), f.RepoName)
+
if err != nil {
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
+
log.Println("failed to reach knotserver", err)
+
return
+
}
+
+
forks, err := db.GetForksByDid(s.db, user.Did)
+
if err != nil {
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
+
log.Println("failed to get forks", err)
+
return
+
}
+
+
s.pages.RepoCompare(w, pages.RepoCompareParams{
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
+
Forks: forks,
+
Branches: branches.Branches,
+
Tags: tags.Tags,
+
})
+
}
+
+
func (s *State) RepoCompareDiff(w http.ResponseWriter, r *http.Request) {
+
f, err := s.fullyResolvedRepo(r)
+
if err != nil {
+
log.Println("failed to get repo and knot", err)
+
return
+
}
+
user := s.oauth.GetUser(r)
+
+
rest := chi.URLParam(r, "*") // master...feature/xyz
+
parts := strings.SplitN(rest, "...", 2)
+
if len(parts) != 2 {
+
s.pages.Notice(w, "compare-error", "Invalid ref format.")
+
return
+
}
+
+
ref1 := parts[0]
+
ref2 := parts[1]
+
+
us, err := knotclient.NewUnsignedClient(f.Knot, s.config.Core.Dev)
+
if err != nil {
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
+
log.Println("failed to reach knotserver", err)
+
return
+
}
+
+
formatPatch, err := us.Compare(f.OwnerDid(), f.RepoName, ref1, ref2)
+
if err != nil {
+
s.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.")
+
log.Println("failed to compare", err)
+
return
+
}
+
+
s.pages.RepoCompareDiff(w, pages.RepoCompareDiffParams{
+
LoggedInUser: user,
+
RepoInfo: f.RepoInfo(s, user),
+
FormatPatch: *formatPatch,
+
})
+
}
+11
appview/state/router.go
···
})
})
+
r.Route("/compare", func(r chi.Router) {
+
r.Get("/", s.RepoCompare)
+
+
// we have to wildcard here since we want to support GitHub's compare syntax
+
// /compare/{ref1}...{ref2}
+
// for example:
+
// /compare/master...some/feature
+
// /compare/master...example.com:another/feature <- this is a fork
+
r.Get("/*", s.RepoCompareDiff)
+
})
+
r.Route("/pulls", func(r chi.Router) {
r.Get("/", s.RepoPulls)
r.With(middleware.AuthMiddleware(s.oauth)).Route("/new", func(r chi.Router) {