godoc: remove the last of the global variables, unexport Server
The exported Server becomes handlerServer, and part of Presentation
now. Presentation is also now an http.Handler with its own
internal mux (a detail, which might go away).
main.go becomes ever simpler.
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/11505043
diff --git a/cmd/godoc/main.go b/cmd/godoc/main.go
index 521b496..148b36d 100644
--- a/cmd/godoc/main.go
+++ b/cmd/godoc/main.go
@@ -110,14 +110,12 @@
if pres == nil {
panic("nil Presentation")
}
- godoc.CmdHandler.RegisterWithMux(mux)
- godoc.PkgHandler.RegisterWithMux(mux)
mux.HandleFunc("/doc/codewalk/", codewalk)
- mux.Handle("/doc/play/", godoc.FileServer)
+ mux.Handle("/doc/play/", pres.FileServer())
mux.HandleFunc("/search", pres.HandleSearch)
- mux.Handle("/robots.txt", godoc.FileServer)
+ mux.Handle("/robots.txt", pres.FileServer())
mux.HandleFunc("/opensearch.xml", serveSearchDesc)
- mux.HandleFunc("/", pres.ServeFile)
+ mux.Handle("/", pres)
}
// ----------------------------------------------------------------------------
@@ -298,6 +296,7 @@
}
corpus := godoc.NewCorpus(fs)
+ corpus.Verbose = *verbose
corpus.IndexEnabled = *indexEnabled
corpus.IndexFiles = *indexFiles
if *writeIndex {
@@ -319,8 +318,6 @@
readTemplates(pres)
- godoc.InitHandlers(pres)
-
if *writeIndex {
// Write search index and exit.
if *indexFiles == "" {
@@ -429,14 +426,14 @@
abspath = target
relpath = bp.ImportPath
} else {
- abspath = pathpkg.Join(godoc.PkgHandler.FSRoot(), path)
+ abspath = pathpkg.Join(pres.PkgFSRoot(), path)
}
if relpath == "" {
relpath = abspath
}
var mode godoc.PageInfoMode
- if relpath == godoc.BuiltinPkgPath {
+ if relpath == "builtin" {
// the fake built-in package contains unexported identifiers
mode = godoc.NoFiltering
}
@@ -451,15 +448,15 @@
// first, try as package unless forced as command
var info *godoc.PageInfo
if !forceCmd {
- info = godoc.PkgHandler.GetPageInfo(abspath, relpath, mode)
+ info = pres.GetPkgPageInfo(abspath, relpath, mode)
}
// second, try as command unless the path is absolute
// (the go command invokes godoc w/ absolute paths; don't override)
var cinfo *godoc.PageInfo
if !filepath.IsAbs(path) {
- abspath = pathpkg.Join(godoc.CmdHandler.FSRoot(), path)
- cinfo = godoc.CmdHandler.GetPageInfo(abspath, relpath, mode)
+ abspath = pathpkg.Join(pres.CmdFSRoot(), path)
+ cinfo = pres.GetCmdPageInfo(abspath, relpath, mode)
}
// determine what to use
diff --git a/godoc/corpus.go b/godoc/corpus.go
index fb88944..af9eaee 100644
--- a/godoc/corpus.go
+++ b/godoc/corpus.go
@@ -21,6 +21,9 @@
type Corpus struct {
fs vfs.FileSystem
+ // Verbose logging.
+ Verbose bool
+
// IndexEnabled controls whether indexing is enabled.
IndexEnabled bool
diff --git a/godoc/godoc.go b/godoc/godoc.go
index ee55355..0e0bf71 100644
--- a/godoc/godoc.go
+++ b/godoc/godoc.go
@@ -29,12 +29,9 @@
"unicode/utf8"
)
-// Verbose controls logging verbosity.
-var Verbose = false
-
// Fake relative package path for built-ins. Documentation for all globals
// (not just exported ones) will be shown for packages in this directory.
-const BuiltinPkgPath = "builtin"
+const builtinPkgPath = "builtin"
// FuncMap defines template functions used in godoc templates.
//
@@ -232,7 +229,7 @@
// because of the irregular mapping under goroot
// we need to correct certain relative paths
relpath = strings.TrimPrefix(relpath, "src/pkg/")
- return PkgHandler.pattern[1:] + relpath // remove trailing '/' for relative URL
+ return "pkg/" + relpath // remove trailing '/' for relative URL
}
// n must be an ast.Node or a *doc.Note
diff --git a/godoc/index.go b/godoc/index.go
index 3040a35..5611489 100644
--- a/godoc/index.go
+++ b/godoc/index.go
@@ -1090,14 +1090,14 @@
}
func (c *Corpus) UpdateIndex() {
- if Verbose {
+ if c.Verbose {
log.Printf("updating index...")
}
start := time.Now()
index := NewIndex(c, c.fsDirnames(), c.MaxResults > 0, c.IndexThrottle)
stop := time.Now()
c.searchIndex.Set(index)
- if Verbose {
+ if c.Verbose {
secs := stop.Sub(start).Seconds()
stats := index.Stats()
log.Printf("index updated (%gs, %d bytes of source, %d files, %d lines, %d unique words, %d spots)",
diff --git a/godoc/linkify.go b/godoc/linkify.go
index ea6cbcf..0a8fb47 100644
--- a/godoc/linkify.go
+++ b/godoc/linkify.go
@@ -94,7 +94,7 @@
switch m {
case identUse:
if n.Obj == nil && predeclared[n.Name] {
- info.path = BuiltinPkgPath
+ info.path = builtinPkgPath
}
info.name = n.Name
case identDef:
diff --git a/godoc/pres.go b/godoc/pres.go
index c97aa96..3a8b99a 100644
--- a/godoc/pres.go
+++ b/godoc/pres.go
@@ -5,15 +5,23 @@
package godoc
import (
+ "net/http"
"regexp"
"sync"
"text/template"
+
+ "code.google.com/p/go.tools/godoc/vfs/httpfs"
)
// Presentation generates output from a corpus.
type Presentation struct {
Corpus *Corpus
+ mux *http.ServeMux
+ fileServer http.Handler
+ cmdHandler handlerServer
+ pkgHandler handlerServer
+
DirlistHTML,
ErrorHTML,
ExampleHTML,
@@ -36,6 +44,11 @@
// notes to render in the output.
NotesRx *regexp.Regexp
+ // AdjustPageInfoMode optionally specifies a function to
+ // modify the PageInfoMode of a request. The default chosen
+ // value is provided.
+ AdjustPageInfoMode func(req *http.Request, mode PageInfoMode) PageInfoMode
+
initFuncMapOnce sync.Once
funcMap template.FuncMap
templateFuncs template.FuncMap
@@ -46,10 +59,47 @@
if c == nil {
panic("nil Corpus")
}
- return &Presentation{
- Corpus: c,
+ p := &Presentation{
+ Corpus: c,
+ mux: http.NewServeMux(),
+ fileServer: http.FileServer(httpfs.New(c.fs)),
+
TabWidth: 4,
ShowExamples: true,
DeclLinks: true,
}
+ p.cmdHandler = handlerServer{p, c, "/cmd/", "/src/cmd"}
+ p.pkgHandler = handlerServer{p, c, "/pkg/", "/src/pkg"}
+ p.cmdHandler.registerWithMux(p.mux)
+ p.pkgHandler.registerWithMux(p.mux)
+ p.mux.HandleFunc("/", p.ServeFile)
+ return p
+}
+
+func (p *Presentation) FileServer() http.Handler {
+ return p.fileServer
+}
+
+func (p *Presentation) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ p.mux.ServeHTTP(w, r)
+}
+
+func (p *Presentation) PkgFSRoot() string {
+ return p.pkgHandler.fsRoot
+}
+
+func (p *Presentation) CmdFSRoot() string {
+ return p.cmdHandler.fsRoot
+}
+
+// TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
+// but this doesn't feel right.
+func (p *Presentation) GetPkgPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
+ return p.pkgHandler.GetPageInfo(abspath, relpath, mode)
+}
+
+// TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
+// but this doesn't feel right.
+func (p *Presentation) GetCmdPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
+ return p.cmdHandler.GetPageInfo(abspath, relpath, mode)
}
diff --git a/godoc/search.go b/godoc/search.go
index 8d5b4e3..a50de5f 100644
--- a/godoc/search.go
+++ b/godoc/search.go
@@ -78,7 +78,7 @@
query := strings.TrimSpace(r.FormValue("q"))
result := p.Corpus.Lookup(query)
- if GetPageInfoMode(r)&NoHTML != 0 {
+ if p.GetPageInfoMode(r)&NoHTML != 0 {
p.ServeText(w, applyTemplate(p.SearchText, "searchText", result))
return
}
diff --git a/godoc/server.go b/godoc/server.go
index 91b3960..b3b05d8 100644
--- a/godoc/server.go
+++ b/godoc/server.go
@@ -25,35 +25,18 @@
"code.google.com/p/go.tools/godoc/util"
"code.google.com/p/go.tools/godoc/vfs"
- "code.google.com/p/go.tools/godoc/vfs/httpfs"
)
-// TODO(bradfitz,adg): these are moved from godoc.go globals.
-// Clean this up.
-var (
- FileServer http.Handler // default file server
- CmdHandler Server
- PkgHandler Server
-)
-
-func InitHandlers(p *Presentation) {
- c := p.Corpus
- FileServer = http.FileServer(httpfs.New(c.fs))
- CmdHandler = Server{p, c, "/cmd/", "/src/cmd"}
- PkgHandler = Server{p, c, "/pkg/", "/src/pkg"}
-}
-
-// Server is a godoc server.
-type Server struct {
+// handlerServer is a migration from an old godoc http Handler type.
+// This should probably merge into something else.
+type handlerServer struct {
p *Presentation
c *Corpus // copy of p.Corpus
pattern string // url pattern; e.g. "/pkg/"
fsRoot string // file system root to which the pattern is mapped
}
-func (s *Server) FSRoot() string { return s.fsRoot }
-
-func (s *Server) RegisterWithMux(mux *http.ServeMux) {
+func (s *handlerServer) registerWithMux(mux *http.ServeMux) {
mux.Handle(s.pattern, s)
}
@@ -65,7 +48,7 @@
// directories, PageInfo.Dirs is nil. If an error occurred, PageInfo.Err is
// set to the respective error but the error is not logged.
//
-func (h *Server) GetPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
+func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
info := &PageInfo{Dirname: abspath}
// Restrict to the package files that would be used when building
@@ -194,15 +177,15 @@
return info
}
-func (h *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+func (h *handlerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if redirect(w, r) {
return
}
relpath := pathpkg.Clean(r.URL.Path[len(h.pattern):])
abspath := pathpkg.Join(h.fsRoot, relpath)
- mode := GetPageInfoMode(r)
- if relpath == BuiltinPkgPath {
+ mode := h.p.GetPageInfoMode(r)
+ if relpath == builtinPkgPath {
mode = NoFiltering
}
info := h.GetPageInfo(abspath, relpath, mode)
@@ -279,19 +262,16 @@
// GetPageInfoMode computes the PageInfoMode flags by analyzing the request
// URL form value "m". It is value is a comma-separated list of mode names
// as defined by modeNames (e.g.: m=src,text).
-func GetPageInfoMode(r *http.Request) PageInfoMode {
+func (p *Presentation) GetPageInfoMode(r *http.Request) PageInfoMode {
var mode PageInfoMode
for _, k := range strings.Split(r.FormValue("m"), ",") {
if m, found := modeNames[strings.TrimSpace(k)]; found {
mode |= m
}
}
- return AdjustPageInfoMode(r, mode)
-}
-
-// AdjustPageInfoMode allows specialized versions of godoc to adjust
-// PageInfoMode by overriding this variable.
-var AdjustPageInfoMode = func(_ *http.Request, mode PageInfoMode) PageInfoMode {
+ if p.AdjustPageInfoMode != nil {
+ mode = p.AdjustPageInfoMode(r, mode)
+ }
return mode
}
@@ -584,7 +564,7 @@
return
}
- FileServer.ServeHTTP(w, r)
+ p.fileServer.ServeHTTP(w, r)
}
func (p *Presentation) serveSearchDesc(w http.ResponseWriter, r *http.Request) {