~sircmpwn/godocs.io

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[PATCH gddo] gddo-server: Implement version picker

Details
Message ID
<20210618185855.8141-1-me@adnano.co>
DKIM signature
pass
Download raw message
Patch: +60 -21
---
This patch implements support for specifying which version of a package
to display documentation for. The documentation for that version will be
fetched on demand if it is not already available.

 gddo-server/assets/templates/doc.gmi       |  2 +-
 gddo-server/assets/templates/doc.html      |  2 +-
 gddo-server/assets/templates/versions.html | 17 +++++++++++++++++
 gddo-server/crawl.go                       | 12 ++++++++----
 gddo-server/gemini.go                      | 17 ++++++++++++-----
 gddo-server/http.go                        | 20 +++++++++++++++-----
 gddo-server/server.go                      |  8 ++++----
 gddo-server/template.go                    |  3 ++-
 8 files changed, 60 insertions(+), 21 deletions(-)
 create mode 100644 gddo-server/assets/templates/versions.html

diff --git a/gddo-server/assets/templates/doc.gmi b/gddo-server/assets/templates/doc.gmi
index ccb2d4f..4f89eb4 100644
--- a/gddo-server/assets/templates/doc.gmi
+++ b/gddo-server/assets/templates/doc.gmi
@@ -85,7 +85,7 @@ import "{{.ImportPath}}"
{{- if .Name}}
## Details

* Version {{.Version}}
=> ?versions Version {{.Version}}
* Published {{.CommitTime.Format "Jan 2, 2006"}}
{{- if .Imports}}
=> ?imports Imports {{.Imports|len}} packages{{end}}
diff --git a/gddo-server/assets/templates/doc.html b/gddo-server/assets/templates/doc.html
index 3f8831a..1888501 100644
--- a/gddo-server/assets/templates/doc.html
+++ b/gddo-server/assets/templates/doc.html
@@ -105,7 +105,7 @@

  <div id="x-pkginfo">
    <p>{{if or .Imports $.ImportCount}}{{if .IsCommand}}Command{{else}}Package{{end}} {{.PageName}} {{if .Imports}}imports <a href="?imports">{{.Imports|len}} packages</a> (<a href="?import-graph">graph</a>){{end}}{{if and .Imports $.ImportCount}} and {{end}}{{if $.ImportCount}}is imported by <a href="?importers">{{$.ImportCount}} packages</a>{{end}}.{{end}}</p>
    <p>Version {{.Version}}
    <p>Version <a href="?versions">{{.Version}}</a>
    <span class="text-muted">|</span>
    Published <span title="{{.CommitTime.Format "2006-01-02T15:04:05Z"}}">{{.CommitTime.Format "Jan 2, 2006"}}</span>
    <span class="text-muted">|</span> GOOS={{.GOOS}}
diff --git a/gddo-server/assets/templates/versions.html b/gddo-server/assets/templates/versions.html
new file mode 100644
index 0000000..e468719
--- /dev/null
+++ b/gddo-server/assets/templates/versions.html
@@ -0,0 +1,17 @@
{{define "Head"}}<title>{{.PageName}} versions - godocs.io</title><meta name="robots" content="NOINDEX, NOFOLLOW">{{end}}

{{define "ROOT"}}
  <table class="table table-condensed">
  <thead><tr><th>Path</th><th>Synopsis</th></tr></thead>
  <tbody>{{range .}}<tr><td><a rel="noopener nofollow" href="/{{.ImportPath}}">{{.ImportPath}}</a></td><td>{{.Synopsis}}</td></tr>
  {{end}}</tbody>
  </table>
{{end}}

{{define "Body"}}
  {{template "ProjectNav" $}}
  <h3>Versions of {{.PageName}}</h3>
  <ul>{{range .Package.Versions}}
    <li><a href="/{{$.Package.ImportPath}}@{{.}}">{{.}}</a></li>{{end}}
  </ul>
{{end}}
diff --git a/gddo-server/crawl.go b/gddo-server/crawl.go
index bf66d4b..f59c461 100644
--- a/gddo-server/crawl.go
+++ b/gddo-server/crawl.go
@@ -37,7 +37,7 @@ func (v byVersion) Less(i, j int) bool { return semver.Compare(v[i], v[j]) > 0 }
func (v byVersion) Swap(i, j int)      { v[i], v[j] = v[j], v[i] }

// crawl fetches package documentation and updates the database.
func (s *Server) crawl(ctx context.Context, modulePath string) (database.Module, error) {
func (s *Server) crawl(ctx context.Context, modulePath, version string) (database.Module, error) {
	start := time.Now().UTC()

	if blocked, err := s.db.IsBlocked(ctx, modulePath); err != nil {
@@ -68,7 +68,7 @@ func (s *Server) crawl(ctx context.Context, modulePath string) (database.Module,
	if err != nil {
		return database.Module{}, err
	}
	if ok && mod.Version == latest {
	if ok && version == "latest" && mod.Version == latest {
		// Update last crawl time
		mod.Updated = start
		if err := s.db.PutModule(ctx, mod); err != nil {
@@ -77,8 +77,12 @@ func (s *Server) crawl(ctx context.Context, modulePath string) (database.Module,
		return mod, nil
	}

	if version == "latest" {
		version = latest
	}

	// Add packages to the database
	src, err := source.Get(ctx, s.proxyClient, modulePath, latest)
	src, err := source.Get(ctx, s.proxyClient, modulePath, version)
	if err != nil {
		return database.Module{}, err
	}
@@ -107,7 +111,7 @@ func (s *Server) crawl(ctx context.Context, modulePath string) (database.Module,
	mod = database.Module{
		ModulePath: modulePath,
		SeriesPath: seriesPath,
		Version:    src.Version,
		Version:    latest,
		Versions:   versions,
		Updated:    start,
	}
diff --git a/gddo-server/gemini.go b/gddo-server/gemini.go
index 9dd3d50..9c725e4 100644
--- a/gddo-server/gemini.go
+++ b/gddo-server/gemini.go
@@ -58,7 +58,7 @@ func (s *Server) serveGeminiSearch(ctx context.Context, w gemini.ResponseWriter,
	}
	q = strings.TrimSpace(q)

	_, _, _, err = s.GetDoc(ctx, q)
	_, _, _, err = s.GetDoc(ctx, q, "latest")
	if err == nil || errors.Is(err, context.DeadlineExceeded) {
		w.WriteHeader(gemini.StatusRedirect, "/"+q)
		return nil
@@ -87,7 +87,14 @@ func (s *Server) serveGeminiPackage(ctx context.Context, w gemini.ResponseWriter
	}

	importPath := strings.TrimPrefix(r.URL.Path, "/")
	mod, pkg, pdoc, err := s.GetDoc(ctx, importPath)
	version := "latest"
	at := strings.Index(importPath, "@")
	if at != -1 {
		version = importPath[at+1:]
		importPath = importPath[:at]
	}

	mod, pkg, pdoc, err := s.GetDoc(ctx, importPath, version)
	if err != nil {
		return err
	}
@@ -104,7 +111,7 @@ func (s *Server) serveGeminiPackage(ctx context.Context, w gemini.ResponseWriter
	tctx := Package{
		Package:    *pdoc,
		ModulePath: mod.ModulePath,
		Version:    mod.Version,
		Version:    pkg.Version,
		Versions:   mod.Versions,
		CommitTime: pkg.CommitTime,
		Updated:    mod.Updated,
@@ -171,7 +178,7 @@ func (s *Server) serveGeminiRefresh(ctx context.Context, w gemini.ResponseWriter

	ch := make(chan error, 1)
	go func() {
		_, err := s.crawl(ctx, pkg.ModulePath)
		_, err := s.crawl(ctx, pkg.ModulePath, "latest")
		ch <- err
	}()
	select {
@@ -191,7 +198,7 @@ func (s *Server) serveGeminiStdlib(ctx context.Context, w gemini.ResponseWriter,
	if err != nil {
		return err
	} else if !ok {
		_, err = s.crawl(ctx, stdlib.ModulePath)
		_, err = s.crawl(ctx, stdlib.ModulePath, "latest")
		if err != nil {
			return err
		}
diff --git a/gddo-server/http.go b/gddo-server/http.go
index e4960fe..4e02413 100644
--- a/gddo-server/http.go
+++ b/gddo-server/http.go
@@ -90,7 +90,14 @@ func (s *Server) servePackage(resp http.ResponseWriter, req *http.Request) error
	}

	importPath := strings.TrimPrefix(req.URL.Path, "/")
	mod, pkg, pdoc, err := s.GetDoc(req.Context(), importPath)
	version := "latest"
	at := strings.Index(importPath, "@")
	if at != -1 {
		version = importPath[at+1:]
		importPath = importPath[:at]
	}

	mod, pkg, pdoc, err := s.GetDoc(req.Context(), importPath, version)
	if err != nil {
		return err
	}
@@ -112,7 +119,7 @@ func (s *Server) servePackage(resp http.ResponseWriter, req *http.Request) error
	tpkg := Package{
		Package:    *pdoc,
		ModulePath: mod.ModulePath,
		Version:    mod.Version,
		Version:    pkg.Version,
		Versions:   mod.Versions,
		CommitTime: pkg.CommitTime,
		Updated:    mod.Updated,
@@ -126,6 +133,9 @@ func (s *Server) servePackage(resp http.ResponseWriter, req *http.Request) error
	}

	switch {
	case isView(req.URL, "versions"):
		return s.templates.ExecuteHTML(resp, "versions.html", http.StatusOK, &tctx)

	case isView(req.URL, "imports"):
		imports, err := s.db.Packages(req.Context(), pdoc.Imports)
		if err != nil {
@@ -231,7 +241,7 @@ func (s *Server) serveRefresh(resp http.ResponseWriter, req *http.Request) error

	ch := make(chan error, 1)
	go func() {
		_, err := s.crawl(ctx, pkg.ModulePath)
		_, err := s.crawl(ctx, pkg.ModulePath, "latest")
		ch <- err
	}()
	select {
@@ -261,7 +271,7 @@ func (s *Server) serveStdlib(resp http.ResponseWriter, req *http.Request) error
	if err != nil {
		return err
	} else if !ok {
		_, err = s.crawl(req.Context(), stdlib.ModulePath)
		_, err = s.crawl(req.Context(), stdlib.ModulePath, "latest")
		if err != nil {
			return err
		}
@@ -289,7 +299,7 @@ func (s *Server) serveHome(resp http.ResponseWriter, req *http.Request) error {
		return s.templates.ExecuteHTML(resp, "index.html", http.StatusOK, nil)
	}

	_, _, _, err := s.GetDoc(req.Context(), q)
	_, _, _, err := s.GetDoc(req.Context(), q, "latest")
	if err == nil || errors.Is(err, context.DeadlineExceeded) {
		http.Redirect(resp, req, "/"+q, http.StatusFound)
		return nil
diff --git a/gddo-server/server.go b/gddo-server/server.go
index 73ce179..f2f81ad 100644
--- a/gddo-server/server.go
+++ b/gddo-server/server.go
@@ -66,7 +66,7 @@ func NewServer(cfg *Config) (*Server, error) {

// GetDoc gets the package documentation from the database or from the module
// proxy as needed.
func (s *Server) GetDoc(ctx context.Context, importPath string) (*database.Module, *database.Package, *doc.Package, error) {
func (s *Server) GetDoc(ctx context.Context, importPath, version string) (*database.Module, *database.Package, *doc.Package, error) {
	type result struct {
		mod *database.Module
		pkg *database.Package
@@ -77,7 +77,7 @@ func (s *Server) GetDoc(ctx context.Context, importPath string) (*database.Modul
	ch := make(chan result, 1)
	go func() {
		ctx := context.Background()
		pkg, ok, err := s.db.GetPackage(ctx, importPath, "latest")
		pkg, ok, err := s.db.GetPackage(ctx, importPath, version)
		if err != nil {
			ch <- result{nil, nil, nil, err}
			return
@@ -85,12 +85,12 @@ func (s *Server) GetDoc(ctx context.Context, importPath string) (*database.Modul
		var mod database.Module
		if !ok {
			var err error
			mod, err = s.crawl(ctx, importPath)
			mod, err = s.crawl(ctx, importPath, version)
			if err != nil {
				ch <- result{nil, nil, nil, err}
				return
			}
			pkg, ok, err = s.db.GetPackage(ctx, importPath, "latest")
			pkg, ok, err = s.db.GetPackage(ctx, importPath, version)
			if err != nil {
				ch <- result{nil, nil, nil, err}
				return
diff --git a/gddo-server/template.go b/gddo-server/template.go
index e5ca2c8..46c0fd9 100644
--- a/gddo-server/template.go
+++ b/gddo-server/template.go
@@ -450,8 +450,9 @@ func parseHTMLTemplates(m TemplateMap, dir string, cb *httputil.CacheBusters) er
		{"bot.html", "common.html", "layout.html"},
		{"doc.html", "common.html", "layout.html"},
		{"index.html", "common.html", "layout.html"},
		{"importers.html", "common.html", "layout.html"},
		{"versions.html", "common.html", "layout.html"},
		{"imports.html", "common.html", "layout.html"},
		{"importers.html", "common.html", "layout.html"},
		{"notfound.html", "common.html", "layout.html"},
		{"search.html", "common.html", "layout.html"},
		{"std.html", "common.html", "layout.html"},
-- 
2.32.0
Details
Message ID
<CC7OMW65WYSN.3LT316JPFTBRT@taiga>
In-Reply-To
<20210618185855.8141-1-me@adnano.co> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
Thanks!

To git@git.sr.ht:~sircmpwn/gddo
   df74f2d..5909268  master -> master
Reply to thread Export thread (mbox)