godoc: exclude internal packages and cmd from packages page.

Internal packages are now only included with ?m=all

Fixes golang/go#8879

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/155910044
This commit is contained in:
Hana Kim 2014-10-13 18:47:02 +02:00 коммит произвёл Brad Fitzpatrick
Родитель 0513cb08b6
Коммит 13837d25ef
5 изменённых файлов: 128 добавлений и 22 удалений

Просмотреть файл

@ -152,11 +152,49 @@ func TestWeb(t *testing.T) {
}
defer cmd.Process.Kill()
waitForServer(t, addr)
tests := []struct{ path, substr string }{
{"/", "Go is an open source programming language"},
{"/pkg/fmt/", "Package fmt implements formatted I/O"},
{"/src/fmt/", "scan_test.go"},
{"/src/fmt/print.go", "// Println formats using"},
tests := []struct {
path string
match []string
dontmatch []string
}{
{
path: "/",
match: []string{"Go is an open source programming language"},
},
{
path: "/pkg/fmt/",
match: []string{"Package fmt implements formatted I/O"},
},
{
path: "/src/fmt/",
match: []string{"scan_test.go"},
},
{
path: "/src/fmt/print.go",
match: []string{"// Println formats using"},
},
{
path: "/pkg",
match: []string{
"Standard library",
"Package fmt implements formatted I/O",
},
dontmatch: []string{
"internal/syscall",
"cmd/gc",
},
},
{
path: "/pkg/?m=all",
match: []string{
"Standard library",
"Package fmt implements formatted I/O",
"internal/syscall",
},
dontmatch: []string{
"cmd/gc",
},
},
}
for _, test := range tests {
url := fmt.Sprintf("http://%s%s", addr, test.path)
@ -170,9 +208,21 @@ func TestWeb(t *testing.T) {
if err != nil {
t.Errorf("GET %s: failed to read body: %s (response: %v)", url, err, resp)
}
if bytes.Index(body, []byte(test.substr)) < 0 {
t.Errorf("GET %s: want substring %q in body, got:\n%s",
url, test.substr, string(body))
isErr := false
for _, substr := range test.match {
if !bytes.Contains(body, []byte(substr)) {
t.Errorf("GET %s: wanted substring %q in body", url, substr)
isErr = true
}
}
for _, substr := range test.dontmatch {
if bytes.Contains(body, []byte(substr)) {
t.Errorf("GET %s: didn't want substring %q in body", url, substr)
isErr = true
}
}
if isErr {
t.Errorf("GET %s: got:\n%s", url, body)
}
}
}

Просмотреть файл

@ -194,8 +194,19 @@ package main
fs.Bind("/", mfs, "/", vfs.BindReplace)
c := NewCorpus(fs)
p := &Presentation{Corpus: c}
p.cmdHandler = handlerServer{p, c, "/cmd/", "/src/cmd"}
p.pkgHandler = handlerServer{p, c, "/pkg/", "/src"}
p.cmdHandler = handlerServer{
p: p,
c: c,
pattern: "/cmd/",
fsRoot: "/src/cmd",
}
p.pkgHandler = handlerServer{
p: p,
c: c,
pattern: "/pkg/",
fsRoot: "/src",
exclude: []string{"/src/cmd"},
}
p.initFuncMap()
p.PackageText = template.Must(template.New("PackageText").Funcs(p.FuncMap()).Parse(`{{$info := .}}{{$filtered := .IsFiltered}}{{if $filtered}}{{range .PAst}}{{range .Decls}}{{node $info .}}{{end}}{{end}}{{else}}{{with .PAst}}{{range $filename, $ast := .}}{{$filename}}:
{{node $ $ast}}{{end}}{{end}}{{end}}{{with .PDoc}}{{if $.IsMain}}COMMAND {{.Doc}}{{else}}PACKAGE {{.Doc}}{{end}}{{with .Funcs}}

Просмотреть файл

@ -280,8 +280,10 @@ type DirList struct {
// listing creates a (linear) directory listing from a directory tree.
// If skipRoot is set, the root directory itself is excluded from the list.
// If filter is set, only the directory entries whose paths match the filter
// are included.
//
func (root *Directory) listing(skipRoot bool) *DirList {
func (root *Directory) listing(skipRoot bool, filter func(string) bool) *DirList {
if root == nil {
return nil
}
@ -306,10 +308,12 @@ func (root *Directory) listing(skipRoot bool) *DirList {
}
// create list
list := make([]DirEntry, n)
i := 0
list := make([]DirEntry, 0, n)
for d := range root.iter(skipRoot) {
p := &list[i]
if filter != nil && !filter(d.Path) {
continue
}
var p DirEntry
p.Depth = d.Depth - minDepth
p.Height = maxHeight - p.Depth
// the path is relative to root.Path - remove the root.Path
@ -322,7 +326,7 @@ func (root *Directory) listing(skipRoot bool) *DirList {
p.Name = d.Name
p.HasPkg = d.HasPkg
p.Synopsis = d.Synopsis
i++
list = append(list, p)
}
return &DirList{maxHeight, list}

Просмотреть файл

@ -115,8 +115,19 @@ func NewPresentation(c *Corpus) *Presentation {
(*Presentation).SearchResultTxt,
},
}
p.cmdHandler = handlerServer{p, c, "/cmd/", "/src/cmd"}
p.pkgHandler = handlerServer{p, c, "/pkg/", "/src"}
p.cmdHandler = handlerServer{
p: p,
c: c,
pattern: "/cmd/",
fsRoot: "/src/cmd",
}
p.pkgHandler = handlerServer{
p: p,
c: c,
pattern: "/pkg/",
fsRoot: "/src",
exclude: []string{"/src/cmd"},
}
p.cmdHandler.registerWithMux(p.mux)
p.pkgHandler.registerWithMux(p.mux)
p.mux.HandleFunc("/", p.ServeFile)

Просмотреть файл

@ -38,7 +38,8 @@ 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
fsRoot string // file system root to which the pattern is mapped; e.g. "/src"
exclude []string // file system paths to exclude; e.g. "/src/cmd"
}
func (s *handlerServer) registerWithMux(mux *http.ServeMux) {
@ -66,7 +67,14 @@ func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode)
ctxt := build.Default
ctxt.IsAbsPath = pathpkg.IsAbs
ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
return h.c.fs.ReadDir(filepath.ToSlash(dir))
f, err := h.c.fs.ReadDir(filepath.ToSlash(dir))
filtered := make([]os.FileInfo, 0, len(f))
for _, i := range f {
if mode&NoFiltering != 0 || i.Name() != "internal" {
filtered = append(filtered, i)
}
}
return filtered, err
}
ctxt.OpenFile = func(name string) (r io.ReadCloser, err error) {
data, err := vfs.ReadFile(h.c.fs, filepath.ToSlash(name))
@ -188,13 +196,35 @@ func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode)
dir = h.c.newDirectory(abspath, 1)
timestamp = time.Now()
}
info.Dirs = dir.listing(true)
info.Dirs = dir.listing(true, func(path string) bool { return h.includePath(path, mode) })
info.DirTime = timestamp
info.DirFlat = mode&FlatDir != 0
return info
}
func (h *handlerServer) includePath(path string, mode PageInfoMode) (r bool) {
// if the path is under one of the exclusion paths, don't list.
for _, e := range h.exclude {
if strings.HasPrefix(path, e) {
return false
}
}
// if the path includes 'internal', don't list unless we are in the NoFiltering mode.
if mode&NoFiltering != 0 {
return true
}
if strings.Contains(path, "internal") {
for _, c := range strings.Split(path, string(os.PathSeparator)) {
if c == "internal" {
return false
}
}
}
return true
}
type funcsByName []*doc.Func
func (s funcsByName) Len() int { return len(s) }