Commit bb0c8b3b authored by Russ Cox's avatar Russ Cox

godoc: use go/build to find files in a package

Fixes #1156.
Fixes #2172.

R=gri
CC=golang-dev
https://golang.org/cl/5015044
parent 2715956f
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"runtime" "runtime"
"sort" "sort"
"strings" "strings"
"syscall"
"template" "template"
"time" "time"
) )
...@@ -815,6 +816,41 @@ type httpHandler struct { ...@@ -815,6 +816,41 @@ type httpHandler struct {
isPkg bool // true if this handler serves real package documentation (as opposed to command documentation) isPkg bool // true if this handler serves real package documentation (as opposed to command documentation)
} }
// fsReadDir implements ReadDir for the go/build package.
func fsReadDir(dir string) ([]*os.FileInfo, os.Error) {
fi, err := fs.ReadDir(dir)
if err != nil {
return nil, err
}
// Convert []FileInfo to []*os.FileInfo.
osfi := make([]*os.FileInfo, len(fi))
for i, f := range fi {
mode := uint32(syscall.S_IFREG)
if f.IsDirectory() {
mode = syscall.S_IFDIR
}
osfi[i] = &os.FileInfo{Name: f.Name(), Size: f.Size(), Mtime_ns: f.Mtime_ns(), Mode: mode}
}
return osfi, nil
}
// fsReadFile implements ReadFile for the go/build package.
func fsReadFile(dir, name string) (path string, data []byte, err os.Error) {
path = filepath.Join(dir, name)
data, err = fs.ReadFile(path)
return
}
func inList(name string, list []string) bool {
for _, l := range list {
if name == l {
return true
}
}
return false
}
// getPageInfo returns the PageInfo for a package directory abspath. If the // getPageInfo returns the PageInfo for a package directory abspath. If the
// parameter genAST is set, an AST containing only the package exports is // parameter genAST is set, an AST containing only the package exports is
// computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc) // computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc)
...@@ -824,11 +860,40 @@ type httpHandler struct { ...@@ -824,11 +860,40 @@ type httpHandler struct {
// PageInfo.Err is set to the respective error but the error is not logged. // PageInfo.Err is set to the respective error but the error is not logged.
// //
func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInfoMode) PageInfo { func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInfoMode) PageInfo {
var pkgFiles []string
// If we're showing the default package, restrict to the ones
// that would be used when building the package on this
// system. This makes sure that if there are separate
// implementations for, say, Windows vs Unix, we don't
// jumble them all together.
if pkgname == "" {
// Note: Uses current binary's GOOS/GOARCH.
// To use different pair, such as if we allowed the user
// to choose, set ctxt.GOOS and ctxt.GOARCH before
// calling ctxt.ScanDir.
ctxt := build.DefaultContext
ctxt.ReadDir = fsReadDir
ctxt.ReadFile = fsReadFile
dir, err := ctxt.ScanDir(abspath)
if err == nil {
pkgFiles = append(dir.GoFiles, dir.CgoFiles...)
}
}
// filter function to select the desired .go files // filter function to select the desired .go files
filter := func(d FileInfo) bool { filter := func(d FileInfo) bool {
// Only Go files.
if !isPkgFile(d) {
return false
}
// If we are looking at cmd documentation, only accept // If we are looking at cmd documentation, only accept
// the special fakePkgFile containing the documentation. // the special fakePkgFile containing the documentation.
return isPkgFile(d) && (h.isPkg || d.Name() == fakePkgFile) if !h.isPkg {
return d.Name() == fakePkgFile
}
// Also restrict file list to pkgFiles.
return pkgFiles == nil || inList(d.Name(), pkgFiles)
} }
// get package ASTs // get package ASTs
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment