Commit d7a0e0e6 authored by Robert Griesemer's avatar Robert Griesemer

godoc: app engine configuration and updated documentation

Also: Fixed an error message in zip.go.

R=r, dsymonds
CC=golang-dev
https://golang.org/cl/4816053
parent 1bd4b637
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file contains configuration information used by
// godoc when running on app engine. Adjust as needed
// (typically when the .zip file changes).
package main
const (
// zipFilename is the name of the .zip file
// containing the file system served by godoc.
zipFilename = "go.zip"
// zipGoroot is the path of the goroot directory
// in the .zip file.
zipGoroot = "/home/username/go"
)
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// To run godoc under app engine, substitute main.go with
// this file (appinit.go), provide a .zip file containing
// the file system to serve, and adjust the configuration
// parameters in appconfig.go accordingly.
//
// The current app engine SDK may be based on an older Go
// release version. To correct for version skew, copy newer
// packages into the alt directory (e.g. alt/strings) and
// adjust the imports in the godoc source files (e.g. from
// `import "strings"` to `import "alt/strings"`). Both old
// and new packages may be used simultaneously as long as
// there is no package global state that needs to be shared.
//
// The directory structure should look as follows:
//
// godoc // directory containing the app engine app
// alt // alternative packages directory to
// // correct for version skew
// strings // never version of the strings package
// ... //
// app.yaml // app engine control file
// go.zip // zip file containing the file system to serve
// godoc // contains godoc sources
// appinit.go // this file instead of godoc/main.go
// appconfig.go // godoc for app engine configuration
// ... //
//
// To run app the engine emulator locally:
//
// dev_appserver.py -a 0 godoc
//
// godoc is the top-level "goroot" directory.
// The godoc home page is served at: <hostname>:8080 and localhost:8080.
package main
import (
"alt/archive/zip"
"http"
"log"
"os"
)
func serveError(w http.ResponseWriter, r *http.Request, relpath string, err os.Error) {
contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
w.WriteHeader(http.StatusNotFound)
servePage(w, "File "+relpath, "", "", contents)
}
func init() {
log.Println("initializing godoc ...")
*goroot = path.Join("/", zipGoroot) // fsHttp paths are relative to '/'
// read .zip file and set up file systems
const zipfile = zipFilename
rc, err := zip.OpenReader(zipfile)
if err != nil {
log.Fatalf("%s: %s\n", zipfile, err)
}
fs = NewZipFS(rc)
fsHttp = NewHttpZipFS(rc, *goroot)
// initialize http handlers
initHandlers()
readTemplates()
registerPublicHandlers(http.DefaultServeMux)
// initialize default directory tree with corresponding timestamp.
initFSTree()
// initialize directory trees for user-defined file systems (-path flag).
initDirTrees()
// create search index
// TODO(gri) Disabled for now as it takes too long. Find a solution for this.
/*
*indexEnabled = true
go indexer()
*/
log.Println("godoc initialization complete")
}
......@@ -97,10 +97,9 @@ may be provided with the -filter flag; if it exists, only directories
on those paths are considered. If -filter_minutes is set, the filter_file is
updated regularly by walking the entire directory tree.
When godoc runs as a web server, it creates a search index from all .go files
under -goroot (excluding files starting with .). The index is created at startup
and is automatically updated every time the -sync command terminates with exit
status 0, indicating that files have changed.
When godoc runs as a web server and -index is set, a search index is maintained.
The index is created at startup and is automatically updated every time the
-sync command terminates with exit status 0, indicating that files have changed.
If the sync exit status is 1, godoc assumes that it succeeded without errors
but that no files changed; the index is not updated in this case.
......@@ -109,5 +108,23 @@ In all other cases, sync is assumed to have failed and godoc backs off running
sync exponentially (up to 1 day). As soon as sync succeeds again (exit status 0
or 1), the normal sync rhythm is re-established.
The index contains both identifier and full text search information (searchable
via regular expressions). The maximum number of full text search results shown
can be set with the -maxresults flag; if set to 0, no full text results are
shown, and only an identifier index but no full text search index is created.
By default, godoc serves files from the file system of the underlying OS.
Instead, a .zip file may be provided via the -zip flag, which contains
the file system to serve. The file paths stored in the .zip file must use
slash ('/') as path separator; and they must be unrooted. $GOROOT (or -goroot)
must be set to the .zip file directory path containing the Go root directory.
For instance, for a .zip file created by the command:
zip go.zip $HOME/go
one may run godoc as follows:
godoc -http=:6060 -zip=go.zip -goroot=$HOME/go
*/
package documentation
......@@ -38,6 +38,7 @@ import (
"io"
"log"
"os"
"path"
"path/filepath"
"regexp"
"runtime"
......@@ -228,23 +229,22 @@ func main() {
log.Fatalf("negative tabwidth %d", *tabwidth)
}
// Clean goroot: normalize path separator.
*goroot = filepath.Clean(*goroot)
// Determine file system to use.
// TODO(gri) - fs and fsHttp should really be the same. Try to unify.
// - fsHttp doesn't need to be set up in command-line mode,
// same is true for the http handlers in initHandlers.
if *zipfile == "" {
// use file system of underlying OS
*goroot = filepath.Clean(*goroot) // normalize path separator
fs = OS
fsHttp = http.Dir(*goroot)
} else {
// use file system specified via .zip file
// use file system specified via .zip file (path separator must be '/')
rc, err := zip.OpenReader(*zipfile)
if err != nil {
log.Fatalf("%s: %s\n", *zipfile, err)
}
*goroot = path.Join("/", *goroot) // fsHttp paths are relative to '/'
fs = NewZipFS(rc)
fsHttp = NewHttpZipFS(rc, *goroot)
}
......
......@@ -83,7 +83,8 @@ func zipPath(name string) string {
func (fs *zipFS) stat(abspath string) (int, zipFI, os.Error) {
i, exact := fs.list.lookup(abspath)
if i < 0 {
return -1, zipFI{}, fmt.Errorf("file not found: %s", abspath)
// abspath has leading '/' stripped - print it explicitly
return -1, zipFI{}, fmt.Errorf("file not found: /%s", abspath)
}
_, name := path.Split(abspath)
var file *zip.File
......
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