1
0
mirror of https://github.com/golang/go synced 2024-09-30 14:18:32 -06: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:
Brad Fitzpatrick 2013-07-19 10:27:53 +10:00
parent 40a278e5ee
commit 705bb7ffce
8 changed files with 83 additions and 56 deletions

View File

@ -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

View File

@ -21,6 +21,9 @@ import (
type Corpus struct {
fs vfs.FileSystem
// Verbose logging.
Verbose bool
// IndexEnabled controls whether indexing is enabled.
IndexEnabled bool

View File

@ -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

View File

@ -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)",

View File

@ -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:

View File

@ -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)
}

View File

@ -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
}

View File

@ -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) {