From 77725e02cc964f980465b158bb86c4061e6bfcca Mon Sep 17 00:00:00 2001 From: tjp Date: Tue, 14 Nov 2023 21:53:09 -0700 Subject: support for nex protocol --- go.mod | 2 +- go.sum | 4 +-- nex.go | 83 +++++++++++++++++++++++++++++++++++++++++++ templates.go | 9 +++++ templates/branch_list.nex.txt | 8 +++++ templates/diff.nex.txt | 1 + templates/diffstat.nex.txt | 1 + templates/ref.nex.txt | 48 +++++++++++++++++++++++++ templates/repo_home.nex.txt | 28 +++++++++++++++ templates/repo_root.nex.txt | 6 ++++ templates/tag_list.nex.txt | 8 +++++ templates/tree.nex.txt | 8 +++++ 12 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 nex.go create mode 100644 templates/branch_list.nex.txt create mode 100644 templates/diff.nex.txt create mode 100644 templates/diffstat.nex.txt create mode 100644 templates/ref.nex.txt create mode 100644 templates/repo_home.nex.txt create mode 100644 templates/repo_root.nex.txt create mode 100644 templates/tag_list.nex.txt create mode 100644 templates/tree.nex.txt diff --git a/go.mod b/go.mod index 2f87967..f1f3b38 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module tildegit.org/tjp/syw go 1.21.0 -require tildegit.org/tjp/sliderule v1.6.0 +require tildegit.org/tjp/sliderule v1.6.1 require ( github.com/go-kit/log v0.2.1 // indirect diff --git a/go.sum b/go.sum index dbe3f84..5a554b3 100644 --- a/go.sum +++ b/go.sum @@ -10,5 +10,5 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -tildegit.org/tjp/sliderule v1.6.0 h1:/dROwqvbwUOf7qem88/m83og0Tr5PczvuAUzGj5JCVw= -tildegit.org/tjp/sliderule v1.6.0/go.mod h1:opdo8E25iS9X9pNismM8U7pCH8XO0PdRIIhdADn8Uik= +tildegit.org/tjp/sliderule v1.6.1 h1:/w0fiD17wS5NnNmpxWdLu9hOX8/CmhjMV1vMwMBMuao= +tildegit.org/tjp/sliderule v1.6.1/go.mod h1:opdo8E25iS9X9pNismM8U7pCH8XO0PdRIIhdADn8Uik= diff --git a/nex.go b/nex.go new file mode 100644 index 0000000..eab3def --- /dev/null +++ b/nex.go @@ -0,0 +1,83 @@ +package syw + +import ( + "context" + "text/template" + + "tildegit.org/tjp/sliderule" + "tildegit.org/tjp/sliderule/nex" +) + +// NexRouter builds a router that will handle requests into a directory of git repositories. +// +// The routes it defines are: +// +// / listing of the repositories in the directory +// /:repository/ overview of the repository +// /:repository/branches/ list of branches/heads +// /:repository/tags/ listing of tags +// /:repository/refs/:ref/ overview of a ref +// /:repository/refs/:ref/tree/*path listing of directories, raw files +// /:repository/diffstat/:fromref/:toref diffstat between two refs +// /:repository/diff/:fromref/:toref diff between two refs +// +// The overrides argument can provide templates to define the behavior of nearly all of the above +// routes. All of them have default implementations so the argument can even be nil, but otherwise +// the template names used are: +// +// repo_root.nex.txt at / +// repo_home.nex.txt at /:repository/ +// branch_list.nex.txt at /:repository/branches +// tag_list.nex.txt at /:repository/tags +// ref.nex.txt at /:repository/refs/:ref/ +// tree.nex.txt for directories requested under /:repository/refs/:ref/tree/*path +// (file paths return the raw files without any template involved) +// diffstat.nex.txt the plaintext diffstat at /:repository/diffstat/:fromref/:toref +// diff.nex.txt the plaintext diff at /:repository/diff/:fromref/:toref +// +// Most of the templates above are rendered with an object with 3 fields: +// +// Ctx: the context.Context from the request +// Repo: a *syw.Repository object corresponding to /:repository +// Params: a map[string]string of the route parameters +// +// The only exception is repo_root.nex.txt, which is rendered with an object containing a single name +// "Repos", a slice of the string repository names. +func NexRouter(repodir string, overrides *template.Template) *sliderule.Router { + tmpl, err := addTemplates(nexTemplate, overrides) + if err != nil { + panic(err) + } + + repoRouter := &sliderule.Router{} + repoRouter.Use(assignRepo(repodir)) + repoRouter.Route("/", repoRouteHandler(nexProto, tmpl, "repo_home.nex.txt")) + repoRouter.Route("/branches/", repoRouteHandler(nexProto, tmpl, "branch_list.nex.txt")) + repoRouter.Route("/tags/", repoRouteHandler(nexProto, tmpl, "tag_list.nex.txt")) + repoRouter.Route("/refs/:ref/", repoRouteHandler(nexProto, tmpl, "ref.nex.txt")) + repoRouter.Route("/refs/:ref/tree/*path", treePathHandler(nexProto, tmpl, "tree.nex.txt")) + repoRouter.Route("/diffstat/:fromref/:toref", repoRouteHandler(nexProto, tmpl, "diffstat.nex.txt")) + repoRouter.Route("/diff/:fromref/:toref", repoRouteHandler(nexProto, tmpl, "diff.nex.txt")) + + router := &sliderule.Router{} + router.Route("/", rootDirHandler(nexProto, repodir, tmpl, "repo_root.nex.txt")) + router.Mount("/:"+reponamekey, repoRouter) + + return router +} + +type nexProtocol struct{ sliderule.ServerProtocol } + +func (nexProtocol) TemplateBaseData(_ context.Context, _ *sliderule.Request) map[string]any { + return map[string]any{} +} + +func (nexProtocol) TemplateRepoData(ctx context.Context, request *sliderule.Request) map[string]any { + return map[string]any{ + "Ctx": ctx, + "Repo": ctx.Value(repokey), + "Params": sliderule.RouteParams(ctx), + } +} + +var nexProto = nexProtocol{nex.ServerProtocol} diff --git a/templates.go b/templates.go index f5f25af..24f8733 100644 --- a/templates.go +++ b/templates.go @@ -17,6 +17,15 @@ var ( )) ) +var ( + //go:embed templates/*.nex.txt + nexTemplateFS embed.FS + nexTemplate = template.Must(template.ParseFS( + nexTemplateFS, + "templates/*.nex.txt", + )) +) + var ( //go:embed templates/*.gph templates/*.gph.txt gopherTemplateFS embed.FS diff --git a/templates/branch_list.nex.txt b/templates/branch_list.nex.txt new file mode 100644 index 0000000..1e8abf8 --- /dev/null +++ b/templates/branch_list.nex.txt @@ -0,0 +1,8 @@ +{{.Repo.Name}} Branches βŒ₯ +{{range .Repo.NameBytes}}-{{end}}----------- + +{{ range .Repo.Refs .Ctx -}} +{{ if .IsBranch -}} +=> ../refs/{{.Hash}}/ {{.ShortName}} +{{ end -}} +{{ end -}} diff --git a/templates/diff.nex.txt b/templates/diff.nex.txt new file mode 100644 index 0000000..f2b795b --- /dev/null +++ b/templates/diff.nex.txt @@ -0,0 +1 @@ +{{.Repo.Diff .Ctx .Params.fromref .Params.toref}} diff --git a/templates/diffstat.nex.txt b/templates/diffstat.nex.txt new file mode 100644 index 0000000..a51e06b --- /dev/null +++ b/templates/diffstat.nex.txt @@ -0,0 +1 @@ +{{.Repo.Diffstat .Ctx .Params.fromref .Params.toref}} diff --git a/templates/ref.nex.txt b/templates/ref.nex.txt new file mode 100644 index 0000000..d76fa24 --- /dev/null +++ b/templates/ref.nex.txt @@ -0,0 +1,48 @@ +{{ with .Repo.Commit .Ctx .Params.ref -}} +{{.Repo.Name}} {{slice .Hash 0 8}} +{{ range .Repo.NameBytes }}-{{end}}--------- + +{{.ShortMessage}} + +{{ with .RestOfMessage -}} +{{ if ne . "" -}} +{{.}} + +{{ end -}} +{{ end -}} +=> ../../ πŸ—‚οΈ Repository +=> ./tree/ πŸ“„ Files +{{ if ne .Parents nil -}} +=> ../../diff/{{.Hash}}^/{{.Hash}} πŸ”© Full Diff +{{ else -}} +=> ../../diff/4b825dc642cb6eb9a060e54bf8d69288fbee4904/{{.Hash}} πŸ”© Full Diff +{{ end -}} +{{ range .Parents -}} +=> ../{{.}}/ πŸ‘€ Parent {{slice . 0 8}} +{{ end -}} +{{ range .Repo.Refs $.Ctx -}} +{{ if .IsTag -}} +{{ if eq $.Params.ref .Hash -}} +=> ../{{.Hash}}/ 🏷️ {{.ShortName}} +{{ end -}} +{{ end -}} +{{ end }} + +Authored +-------- +{{.AuthorName}}<{{.AuthorEmail}}> +{{.AuthorDate.Format "Mon Jan _2 15:04:05 MST 2006"}} + +Committed +--------- +{{.CommitterName}}<{{.CommitterEmail}}> +{{.CommitDate.Format "Mon Jan _2 15:04:05 MST 2006"}} + +{{ if eq .Parents nil -}} +{{$.Repo.Diffstat $.Ctx "4b825dc642cb6eb9a060e54bf8d69288fbee4904" $.Params.ref}} +{{ else -}} +{{ with index .Parents 0 -}} +{{$.Repo.Diffstat $.Ctx . $.Params.ref}} +{{ end -}} +{{ end -}} +{{ end -}} diff --git a/templates/repo_home.nex.txt b/templates/repo_home.nex.txt new file mode 100644 index 0000000..86cca62 --- /dev/null +++ b/templates/repo_home.nex.txt @@ -0,0 +1,28 @@ +{{.Repo.Name}} +{{ range .Repo.NameBytes }}={{end}} + +{{.Repo.Description}} + +=> ./branches/ βŒ₯ Branches +=> ./tags/ 🏷️Tags +=> ./refs/HEAD/tree/ πŸ“„ Files + +Latest Commits +-------------- + +{{ with .Repo.Commits .Ctx "HEAD" 5 -}} +{{ range . -}} +=> ./refs/{{.Hash}}/ {{.ShortMessage}} +{{ end -}} +{{ if len . | eq 0 -}} +(no commits to show) +{{ end -}} +{{ end }} + +{{ with .Repo.Readme .Ctx "HEAD" -}} +{{ if len .RawContents | ne 0 -}} +== {{.Filename}} == + +{{.RawContents}} +{{ end -}} +{{ end }} diff --git a/templates/repo_root.nex.txt b/templates/repo_root.nex.txt new file mode 100644 index 0000000..d4ee0b0 --- /dev/null +++ b/templates/repo_root.nex.txt @@ -0,0 +1,6 @@ +Repositories +============ + +{{ range .Repos -}} +=> ./{{.}}/ +{{ end }} diff --git a/templates/tag_list.nex.txt b/templates/tag_list.nex.txt new file mode 100644 index 0000000..df087b2 --- /dev/null +++ b/templates/tag_list.nex.txt @@ -0,0 +1,8 @@ +{{.Repo.Name}} Tags 🏷️ +{{range .Repo.NameBytes}}-{{end}}------- + +{{ range .Repo.Refs .Ctx -}} +{{ if .IsTag -}} +=> ../refs/{{.Hash}}/ {{.ShortName}} +{{ end -}} +{{ end -}} diff --git a/templates/tree.nex.txt b/templates/tree.nex.txt new file mode 100644 index 0000000..676113b --- /dev/null +++ b/templates/tree.nex.txt @@ -0,0 +1,8 @@ +{{ with .Repo.Commit .Ctx .Params.ref -}} +{{slice .Hash 0 8}}:{{ if ne $.Params.path "" }}{{$.Params.path}}{{ else }}/{{ end }} + +{{ end -}} +=> ../ {{ if ne .Params.path "" }}../{{ else }}Commit{{ end }} +{{ range .Repo.Tree .Ctx .Params.ref .Params.path -}} +=> ./{{.Path}}{{if eq .Type "tree"}}/{{end}} {{if eq .Type "blob"}}πŸ“„{{else if eq .Type "tree"}}πŸ“‚{{end}} {{.Path}} +{{ end -}} -- cgit v1.2.3