Commit fa462f37 authored by Robert Griesemer's avatar Robert Griesemer

godoc: show (some) line numbers for remote search

- show build version
- use build goroot when possible

R=rsc
CC=golang-dev
https://golang.org/cl/656043
parent b0c6bba8
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
<li class="blank">&nbsp;</li> <li class="blank">&nbsp;</li>
<li class="navhead">Last update</li> <li class="navhead">Last update</li>
<li>{Timestamp|time}</li> <li>{Timestamp|time}</li>
<li>Build version {Version|html}</li>
</ul> </ul>
</div> </div>
......
...@@ -21,7 +21,7 @@ package {Pak.Name} ...@@ -21,7 +21,7 @@ package {Pak.Name}
{.repeated section Files} {.repeated section Files}
{.repeated section Groups} {.repeated section Groups}
{.repeated section Infos} {.repeated section Infos}
{File.Path|url-src} {File.Path|url-src}:{@|infoLine}
{.end} {.end}
{.end} {.end}
{.end} {.end}
...@@ -36,7 +36,7 @@ package {Pak.Name} ...@@ -36,7 +36,7 @@ package {Pak.Name}
{.repeated section Files} {.repeated section Files}
{.repeated section Groups} {.repeated section Groups}
{.repeated section Infos} {.repeated section Infos}
{File.Path|url-src} {File.Path|url-src}:{@|infoLine}
{.end} {.end}
{.end} {.end}
{.end} {.end}
......
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
"log" "log"
"os" "os"
pathutil "path" pathutil "path"
"runtime"
"strings" "strings"
"sync" "sync"
"template" "template"
...@@ -78,7 +79,7 @@ var ( ...@@ -78,7 +79,7 @@ var (
verbose = flag.Bool("v", false, "verbose mode") verbose = flag.Bool("v", false, "verbose mode")
// file system roots // file system roots
goroot string goroot = flag.String("goroot", runtime.GOROOT(), "Go root directory")
path = flag.String("path", "", "additional package directories (colon-separated)") path = flag.String("path", "", "additional package directories (colon-separated)")
// layout control // layout control
...@@ -95,20 +96,11 @@ var ( ...@@ -95,20 +96,11 @@ var (
) )
func init() {
goroot = os.Getenv("GOROOT")
if goroot == "" {
goroot = pathutil.Join(os.Getenv("HOME"), "go")
}
flag.StringVar(&goroot, "goroot", goroot, "Go root directory")
}
func initHandlers() { func initHandlers() {
fsMap.Init(*path) fsMap.Init(*path)
fileServer = http.FileServer(goroot, "") fileServer = http.FileServer(*goroot, "")
cmdHandler = httpHandler{"/cmd/", pathutil.Join(goroot, "src/cmd"), false} cmdHandler = httpHandler{"/cmd/", pathutil.Join(*goroot, "src/cmd"), false}
pkgHandler = httpHandler{"/pkg/", pathutil.Join(goroot, "src/pkg"), true} pkgHandler = httpHandler{"/pkg/", pathutil.Join(*goroot, "src/pkg"), true}
} }
...@@ -205,9 +197,9 @@ func absolutePath(path, defaultRoot string) string { ...@@ -205,9 +197,9 @@ func absolutePath(path, defaultRoot string) string {
func relativePath(path string) string { func relativePath(path string) string {
relpath := fsMap.ToRelative(path) relpath := fsMap.ToRelative(path)
if relpath == "" && strings.HasPrefix(path, goroot+"/") { if relpath == "" && strings.HasPrefix(path, *goroot+"/") {
// no user-defined mapping found; use default mapping // no user-defined mapping found; use default mapping
relpath = path[len(goroot)+1:] relpath = path[len(*goroot)+1:]
} }
// Only if path is an invalid absolute path is relpath == "" // Only if path is an invalid absolute path is relpath == ""
// at this point. This should never happen since absolute paths // at this point. This should never happen since absolute paths
...@@ -746,17 +738,18 @@ func infoKindFmt(w io.Writer, x interface{}, format string) { ...@@ -746,17 +738,18 @@ func infoKindFmt(w io.Writer, x interface{}, format string) {
// Template formatter for "infoLine" format. // Template formatter for "infoLine" format.
func infoLineFmt(w io.Writer, x interface{}, format string) { func infoLineFmt(w io.Writer, x interface{}, format string) {
// TODO(gri) The code below won't work when invoked
// as part of a command-line search where
// there is no index (and thus Snippets).
// At the moment, the search.txt template
// is not using this formatter and cannot
// show line numbers.
info := x.(SpotInfo) info := x.(SpotInfo)
line := info.Lori() line := info.Lori()
if info.IsIndex() { if info.IsIndex() {
index, _ := searchIndex.get() index, _ := searchIndex.get()
if index != nil {
line = index.(*Index).Snippet(line).Line line = index.(*Index).Snippet(line).Line
} else {
// no line information available because
// we don't have an index
// TODO(gri) Fix this for remote search
line = 0
}
} }
fmt.Fprintf(w, "%d", line) fmt.Fprintf(w, "%d", line)
} }
...@@ -839,7 +832,7 @@ var fmap = template.FormatterMap{ ...@@ -839,7 +832,7 @@ var fmap = template.FormatterMap{
func readTemplate(name string) *template.Template { func readTemplate(name string) *template.Template {
path := pathutil.Join(goroot, "lib/godoc/"+name) path := pathutil.Join(*goroot, "lib/godoc/"+name)
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)
if err != nil { if err != nil {
log.Exitf("ReadFile %s: %v", path, err) log.Exitf("ReadFile %s: %v", path, err)
...@@ -885,6 +878,7 @@ func servePage(c *http.Conn, title, query string, content []byte) { ...@@ -885,6 +878,7 @@ func servePage(c *http.Conn, title, query string, content []byte) {
PkgRoots []string PkgRoots []string
Timestamp uint64 // int64 to be compatible with os.Dir.Mtime_ns Timestamp uint64 // int64 to be compatible with os.Dir.Mtime_ns
Query string Query string
Version string
Menu []byte Menu []byte
Content []byte Content []byte
} }
...@@ -895,6 +889,7 @@ func servePage(c *http.Conn, title, query string, content []byte) { ...@@ -895,6 +889,7 @@ func servePage(c *http.Conn, title, query string, content []byte) {
PkgRoots: fsMap.PrefixList(), PkgRoots: fsMap.PrefixList(),
Timestamp: uint64(ts) * 1e9, // timestamp in ns Timestamp: uint64(ts) * 1e9, // timestamp in ns
Query: query, Query: query,
Version: runtime.Version(),
Menu: nil, Menu: nil,
Content: content, Content: content,
} }
...@@ -1088,12 +1083,12 @@ func serveDirectory(c *http.Conn, r *http.Request, abspath, relpath string) { ...@@ -1088,12 +1083,12 @@ func serveDirectory(c *http.Conn, r *http.Request, abspath, relpath string) {
func serveFile(c *http.Conn, r *http.Request) { func serveFile(c *http.Conn, r *http.Request) {
relpath := r.URL.Path[1:] // serveFile URL paths start with '/' relpath := r.URL.Path[1:] // serveFile URL paths start with '/'
abspath := absolutePath(relpath, goroot) abspath := absolutePath(relpath, *goroot)
// pick off special cases and hand the rest to the standard file server // pick off special cases and hand the rest to the standard file server
switch r.URL.Path { switch r.URL.Path {
case "/": case "/":
serveHTMLDoc(c, r, pathutil.Join(goroot, "doc/root.html"), "doc/root.html") serveHTMLDoc(c, r, pathutil.Join(*goroot, "doc/root.html"), "doc/root.html")
return return
case "/doc/root.html": case "/doc/root.html":
...@@ -1372,7 +1367,7 @@ func indexer() { ...@@ -1372,7 +1367,7 @@ func indexer() {
// from the sync goroutine, but this solution is // from the sync goroutine, but this solution is
// more decoupled, trivial, and works well enough) // more decoupled, trivial, and works well enough)
start := time.Nanoseconds() start := time.Nanoseconds()
index := NewIndex(goroot) index := NewIndex(*goroot)
stop := time.Nanoseconds() stop := time.Nanoseconds()
searchIndex.set(index) searchIndex.set(index)
if *verbose { if *verbose {
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"os" "os"
pathutil "path" pathutil "path"
"rpc" "rpc"
"runtime"
"time" "time"
) )
...@@ -80,7 +81,7 @@ func exec(c *http.Conn, args []string) (status int) { ...@@ -80,7 +81,7 @@ func exec(c *http.Conn, args []string) (status int) {
if *verbose { if *verbose {
log.Stderrf("executing %v", args) log.Stderrf("executing %v", args)
} }
pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds) pid, err := os.ForkExec(bin, args, os.Environ(), *goroot, fds)
defer r.Close() defer r.Close()
w.Close() w.Close()
if err != nil { if err != nil {
...@@ -127,7 +128,7 @@ func dosync(c *http.Conn, r *http.Request) { ...@@ -127,7 +128,7 @@ func dosync(c *http.Conn, r *http.Request) {
// TODO(gri): The directory tree may be temporarily out-of-sync. // TODO(gri): The directory tree may be temporarily out-of-sync.
// Consider keeping separate time stamps so the web- // Consider keeping separate time stamps so the web-
// page can indicate this discrepancy. // page can indicate this discrepancy.
fsTree.set(newDirectory(goroot, maxDirDepth)) fsTree.set(newDirectory(*goroot, maxDirDepth))
fallthrough fallthrough
case 1: case 1:
// sync failed because no files changed; // sync failed because no files changed;
...@@ -208,8 +209,9 @@ func main() { ...@@ -208,8 +209,9 @@ func main() {
var handler http.Handler = http.DefaultServeMux var handler http.Handler = http.DefaultServeMux
if *verbose { if *verbose {
log.Stderrf("Go Documentation Server\n") log.Stderrf("Go Documentation Server\n")
log.Stderrf("version = %s\n", runtime.Version())
log.Stderrf("address = %s\n", *httpAddr) log.Stderrf("address = %s\n", *httpAddr)
log.Stderrf("goroot = %s\n", goroot) log.Stderrf("goroot = %s\n", *goroot)
log.Stderrf("tabwidth = %d\n", *tabwidth) log.Stderrf("tabwidth = %d\n", *tabwidth)
if !fsMap.IsEmpty() { if !fsMap.IsEmpty() {
log.Stderr("user-defined mapping:") log.Stderr("user-defined mapping:")
...@@ -228,7 +230,7 @@ func main() { ...@@ -228,7 +230,7 @@ func main() {
// 1) set timestamp right away so that the indexer is kicked on // 1) set timestamp right away so that the indexer is kicked on
fsTree.set(nil) fsTree.set(nil)
// 2) compute initial directory tree in a goroutine so that launch is quick // 2) compute initial directory tree in a goroutine so that launch is quick
go func() { fsTree.set(newDirectory(goroot, maxDirDepth)) }() go func() { fsTree.set(newDirectory(*goroot, maxDirDepth)) }()
// Start sync goroutine, if enabled. // Start sync goroutine, if enabled.
if *syncCmd != "" && *syncMin > 0 { if *syncCmd != "" && *syncMin > 0 {
......
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