mirror of
https://github.com/golang/go
synced 2024-11-18 11:04:42 -07:00
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
This commit is contained in:
parent
40a278e5ee
commit
705bb7ffce
@ -110,14 +110,12 @@ func registerPublicHandlers(mux *http.ServeMux) {
|
||||
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 @@ func main() {
|
||||
}
|
||||
|
||||
corpus := godoc.NewCorpus(fs)
|
||||
corpus.Verbose = *verbose
|
||||
corpus.IndexEnabled = *indexEnabled
|
||||
corpus.IndexFiles = *indexFiles
|
||||
if *writeIndex {
|
||||
@ -319,8 +318,6 @@ func main() {
|
||||
|
||||
readTemplates(pres)
|
||||
|
||||
godoc.InitHandlers(pres)
|
||||
|
||||
if *writeIndex {
|
||||
// Write search index and exit.
|
||||
if *indexFiles == "" {
|
||||
@ -429,14 +426,14 @@ func main() {
|
||||
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 @@ func main() {
|
||||
// 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
|
||||
|
@ -21,6 +21,9 @@ import (
|
||||
type Corpus struct {
|
||||
fs vfs.FileSystem
|
||||
|
||||
// Verbose logging.
|
||||
Verbose bool
|
||||
|
||||
// IndexEnabled controls whether indexing is enabled.
|
||||
IndexEnabled bool
|
||||
|
||||
|
@ -29,12 +29,9 @@ import (
|
||||
"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 @@ func pkgLinkFunc(path string) string {
|
||||
// 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
|
||||
|
@ -1090,14 +1090,14 @@ func (c *Corpus) readIndex(filenames string) error {
|
||||
}
|
||||
|
||||
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)",
|
||||
|
@ -94,7 +94,7 @@ func linksFor(node ast.Node) (list []link) {
|
||||
switch m {
|
||||
case identUse:
|
||||
if n.Obj == nil && predeclared[n.Name] {
|
||||
info.path = BuiltinPkgPath
|
||||
info.path = builtinPkgPath
|
||||
}
|
||||
info.name = n.Name
|
||||
case identDef:
|
||||
|
@ -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 @@ type Presentation struct {
|
||||
// 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 @@ func NewPresentation(c *Corpus) *Presentation {
|
||||
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)
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ func (p *Presentation) HandleSearch(w http.ResponseWriter, r *http.Request) {
|
||||
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
|
||||
}
|
||||
|
@ -25,35 +25,18 @@ import (
|
||||
|
||||
"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 @@ func (s *Server) RegisterWithMux(mux *http.ServeMux) {
|
||||
// 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 @@ func (h *Server) GetPageInfo(abspath, relpath string, mode PageInfoMode) *PageIn
|
||||
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 @@ var modeNames = map[string]PageInfoMode{
|
||||
// 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 @@ func (p *Presentation) serveFile(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
FileServer.ServeHTTP(w, r)
|
||||
p.fileServer.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (p *Presentation) serveSearchDesc(w http.ResponseWriter, r *http.Request) {
|
||||
|
Loading…
Reference in New Issue
Block a user