Merge "veyron/services/mgmt: Fix broken tests with a hack."
diff --git a/lib/cmdline/cmdline.go b/lib/cmdline/cmdline.go
index 74245f2..ae6fa1b 100644
--- a/lib/cmdline/cmdline.go
+++ b/lib/cmdline/cmdline.go
@@ -308,7 +308,7 @@
 	}
 	for _, topic := range cmd.Topics {
 		// Title-case required for godoc to recognize this as a section header.
-		header := strings.Title(namePath(cmd) + " " + topic.Name + " (Help Topic)")
+		header := strings.Title(namePath(cmd)+" "+topic.Name) + " - help topic"
 		lineBreak(w, style)
 		fmt.Fprintf(w, "%s\n\n", header)
 		printLong(w, topic.Long)
diff --git a/lib/cmdline/cmdline_test.go b/lib/cmdline/cmdline_test.go
index 255f1d5..370d478 100644
--- a/lib/cmdline/cmdline_test.go
+++ b/lib/cmdline/cmdline_test.go
@@ -802,7 +802,7 @@
 The echoopt flags are:
    -n=false: Do not output trailing newline
 ================================================================================
-Toplevelprog Echoprog Topic3 (Help Topic)
+Toplevelprog Echoprog Topic3 - help topic
 
 Help topic 3 long.
 ================================================================================
@@ -829,11 +829,11 @@
 The help flags are:
    -style=text: The formatting style for help output, either "text" or "godoc".
 ================================================================================
-Toplevelprog Topic1 (Help Topic)
+Toplevelprog Topic1 - help topic
 
 Help topic 1 long.
 ================================================================================
-Toplevelprog Topic2 (Help Topic)
+Toplevelprog Topic2 - help topic
 
 Help topic 2 long.
 `,
@@ -932,7 +932,7 @@
 The help flags are:
    -style=text: The formatting style for help output, either "text" or "godoc".
 ================================================================================
-Toplevelprog Echoprog Topic3 (Help Topic)
+Toplevelprog Echoprog Topic3 - help topic
 
 Help topic 3 long.
 `,
diff --git a/runtimes/google/ipc/debug_test.go b/runtimes/google/ipc/debug_test.go
index f18f175..11968e0 100644
--- a/runtimes/google/ipc/debug_test.go
+++ b/runtimes/google/ipc/debug_test.go
@@ -63,34 +63,6 @@
 			t.Errorf("unexpected value: Got %v, want %v", value, want)
 		}
 	}
-	// Call Glob on __debug
-	{
-		addr := naming.JoinAddressName(ep.String(), "__debug")
-		call, err := client.StartCall(ctx, addr, "Glob", []interface{}{"*"}, veyron2.NoResolveOpt(true))
-		if err != nil {
-			t.Fatalf("client.StartCall failed: %v", err)
-		}
-		results := []string{}
-		for {
-			var me types.MountEntry
-			if err := call.Recv(&me); err != nil {
-				break
-			}
-			results = append(results, me.Name)
-		}
-		if ferr := call.Finish(&err); ferr != nil {
-			t.Fatalf("call.Finish failed: %v", ferr)
-		}
-		sort.Strings(results)
-		want := []string{
-			"logs",
-			"pprof",
-			"stats",
-		}
-		if !reflect.DeepEqual(want, results) {
-			t.Errorf("unexpected results. Got %v, want %v", results, want)
-		}
-	}
 	// Call Value on __debug/stats/testing/foo
 	{
 		foo := stats.NewString("testing/foo")
@@ -111,6 +83,39 @@
 			t.Errorf("unexpected result: Got %v, want %v", value, want)
 		}
 	}
+
+	// Call Glob
+	testcases := []struct {
+		name, pattern string
+		expected      []string
+	}{
+		{"", "*", []string{}},
+		{"", "__*", []string{"__debug"}},
+		{"", "__*/*", []string{"__debug/logs", "__debug/pprof", "__debug/stats"}},
+		{"__debug", "*", []string{"logs", "pprof", "stats"}},
+	}
+	for _, tc := range testcases {
+		addr := naming.JoinAddressName(ep.String(), "//"+tc.name)
+		call, err := client.StartCall(ctx, addr, "Glob", []interface{}{tc.pattern})
+		if err != nil {
+			t.Fatalf("client.StartCall failed: %v", err)
+		}
+		results := []string{}
+		for {
+			var me types.MountEntry
+			if err := call.Recv(&me); err != nil {
+				break
+			}
+			results = append(results, me.Name)
+		}
+		if ferr := call.Finish(&err); ferr != nil {
+			t.Fatalf("call.Finish failed: %v", ferr)
+		}
+		sort.Strings(results)
+		if !reflect.DeepEqual(tc.expected, results) {
+			t.Errorf("unexpected results. Got %v, want %v", results, tc.expected)
+		}
+	}
 }
 
 type testObject struct {
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 36bda51..4a651ca 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -9,6 +9,7 @@
 	"sync"
 	"time"
 
+	"veyron.io/veyron/veyron/lib/glob"
 	"veyron.io/veyron/veyron/lib/netstate"
 	"veyron.io/veyron/veyron/runtimes/google/lib/publisher"
 	inaming "veyron.io/veyron/veyron/runtimes/google/naming"
@@ -26,6 +27,7 @@
 	"veyron.io/veyron/veyron2/ipc/stream"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/security"
+	mttypes "veyron.io/veyron/veyron2/services/mounttable/types"
 	"veyron.io/veyron/veyron2/verror"
 	"veyron.io/veyron/veyron2/vlog"
 	"veyron.io/veyron/veyron2/vom"
@@ -340,6 +342,7 @@
 			s.proxyListenLoop(ln, ep, proxy)
 			s.active.Done()
 		}(pln, pep, listenSpec.Proxy)
+		s.listeners[pln] = nil
 		s.publisher.AddServer(s.publishEP(pep), s.servesMountTable)
 	} else {
 		s.publisher.AddServer(s.publishEP(ep), s.servesMountTable)
@@ -521,6 +524,7 @@
 	// flows will continue until they terminate naturally.
 	nListeners := len(s.listeners)
 	errCh := make(chan error, nListeners)
+
 	for ln, dhcpl := range s.listeners {
 		go func(ln stream.Listener) {
 			errCh <- ln.Close()
@@ -807,6 +811,9 @@
 // and dispatch suffix are also returned.
 func (fs *flowServer) lookup(name, method string) (ipc.Invoker, security.Authorizer, string, verror.E) {
 	name = strings.TrimLeft(name, "/")
+	if method == "Glob" && len(name) == 0 {
+		return ipc.ReflectInvoker(&globInvoker{fs}), &acceptAllAuthorizer{}, name, nil
+	}
 	disp := fs.disp
 	if name == ipc.DebugKeyword || strings.HasPrefix(name, ipc.DebugKeyword+"/") {
 		name = strings.TrimPrefix(name, ipc.DebugKeyword)
@@ -822,7 +829,98 @@
 			return invoker, auth, name, nil
 		}
 	}
-	return nil, nil, "", verror.NoExistf(fmt.Sprintf("ipc: dispatcher not found for %q", name))
+	return nil, nil, "", verror.NoExistf("ipc: invoker not found for %q", name)
+}
+
+type acceptAllAuthorizer struct{}
+
+func (acceptAllAuthorizer) Authorize(security.Context) error {
+	return nil
+}
+
+type globInvoker struct {
+	fs *flowServer
+}
+
+// Glob matches the pattern against internal object names if the double-
+// underscore prefix is explicitly part of the pattern. Otherwise, it invokes
+// the service's Glob method.
+func (i *globInvoker) Glob(call ipc.ServerCall, pattern string) error {
+	g, err := glob.Parse(pattern)
+	if err != nil {
+		return err
+	}
+	if strings.HasPrefix(pattern, "__") {
+		var err error
+		// Match against internal object names.
+		internalLeaves := []string{ipc.DebugKeyword}
+		for _, leaf := range internalLeaves {
+			if ok, _, left := g.MatchInitialSegment(leaf); ok {
+				if ierr := i.invokeGlob(call, i.fs.debugDisp, leaf, left.String()); ierr != nil {
+					err = ierr
+				}
+			}
+		}
+		return err
+	}
+	// Invoke the service's method.
+	return i.invokeGlob(call, i.fs.disp, "", pattern)
+}
+
+func (i *globInvoker) invokeGlob(call ipc.ServerCall, d ipc.Dispatcher, prefix, pattern string) error {
+	if d == nil {
+		return nil
+	}
+	invoker, auth, err := d.Lookup("", "Glob")
+	if err != nil {
+		return err
+	}
+	if invoker == nil {
+		return verror.NoExistf("ipc: invoker not found for Glob")
+	}
+
+	argptrs, label, err := invoker.Prepare("Glob", 1)
+	i.fs.label = label
+	if err != nil {
+		return verror.Makef(verror.ErrorID(err), "%s", err)
+	}
+	if err := i.fs.authorize(auth); err != nil {
+		return errNotAuthorized(fmt.Errorf("%q not authorized for method %q: %v", i.fs.RemoteID(), i.fs.Method(), err))
+	}
+	leafCall := &localServerCall{call, prefix}
+	argptrs[0] = &pattern
+	results, err := invoker.Invoke("Glob", leafCall, argptrs)
+	if err != nil {
+		return err
+	}
+	if len(results) != 1 {
+		return verror.BadArgf("unexpected number of results. Got %d, want 1", len(results))
+	}
+	res := results[0]
+	if res == nil {
+		return nil
+	}
+	err, ok := res.(error)
+	if !ok {
+		return verror.BadArgf("unexpected result type. Got %T, want error", res)
+	}
+	return err
+}
+
+// An ipc.ServerCall that prepends a prefix to all the names in the streamed
+// MountEntry objects.
+type localServerCall struct {
+	ipc.ServerCall
+	prefix string
+}
+
+func (c *localServerCall) Send(v interface{}) error {
+	me, ok := v.(mttypes.MountEntry)
+	if !ok {
+		return verror.BadArgf("unexpected stream type. Got %T, want MountEntry", v)
+	}
+	me.Name = naming.Join(c.prefix, me.Name)
+	return c.ServerCall.Send(me)
 }
 
 func (fs *flowServer) authorize(auth security.Authorizer) error {
diff --git a/services/mgmt/debug/server_test.go b/services/mgmt/debug/server_test.go
index 0c981d5..120a481 100644
--- a/services/mgmt/debug/server_test.go
+++ b/services/mgmt/debug/server_test.go
@@ -216,6 +216,7 @@
 		}
 		sort.Strings(results)
 		expected = []string{
+			"",
 			"logs",
 			"logs/test.INFO",
 			"pprof",
diff --git a/services/mgmt/lib/toplevelglob/invoker.go b/services/mgmt/lib/toplevelglob/invoker.go
index 439d129..fd605a4 100644
--- a/services/mgmt/lib/toplevelglob/invoker.go
+++ b/services/mgmt/lib/toplevelglob/invoker.go
@@ -28,6 +28,9 @@
 	if err != nil {
 		return err
 	}
+	if g.Len() == 0 {
+		call.Send(types.MountEntry{Name: ""})
+	}
 	for _, leaf := range i.leaves {
 		if ok, _, left := g.MatchInitialSegment(leaf); ok {
 			if err := i.leafGlob(call, leaf, left.String()); err != nil {
diff --git a/services/mgmt/node/impl/impl_test.go b/services/mgmt/node/impl/impl_test.go
index bed59c0..1ca4db6 100644
--- a/services/mgmt/node/impl/impl_test.go
+++ b/services/mgmt/node/impl/impl_test.go
@@ -951,6 +951,7 @@
 	}
 	sort.Strings(results)
 	expected := []string{
+		"",
 		"apps",
 		"nm",
 	}
diff --git a/services/wsprd/app/app.go b/services/wsprd/app/app.go
index afa3c18..d09051e 100644
--- a/services/wsprd/app/app.go
+++ b/services/wsprd/app/app.go
@@ -93,6 +93,9 @@
 	// The runtime to use to create new clients.
 	rt veyron2.Runtime
 
+	// The ipc.ListenSpec to use with server.Listen
+	listenSpec *ipc.ListenSpec
+
 	// Used to generate unique ids for requests initiated by the proxy.
 	// These ids will be even so they don't collide with the ids generated
 	// by the client.
@@ -128,7 +131,7 @@
 // javascript server. veyronProxyEP is an endpoint for the veyron proxy to serve through.  It can't be empty.
 // opts are any options that should be passed to the rt.New(), such as the mounttable root.
 func NewController(writerCreator func(id int64) lib.ClientWriter,
-	veyronProxyEP string, opts ...veyron2.ROpt) (*Controller, error) {
+	listenSpec *ipc.ListenSpec, opts ...veyron2.ROpt) (*Controller, error) {
 	r, err := rt.New(opts...)
 	if err != nil {
 		return nil, err
@@ -143,7 +146,7 @@
 		logger:        r.Logger(),
 		client:        client,
 		writerCreator: writerCreator,
-		veyronProxyEP: veyronProxyEP,
+		listenSpec:    listenSpec,
 		idStore:       identity.NewJSPublicIDHandles(),
 	}
 	controller.setup()
@@ -266,6 +269,7 @@
 	c.logger.VI(0).Info("Cleaning up websocket")
 	c.Lock()
 	defer c.Unlock()
+
 	for _, stream := range c.outstandingStreams {
 		stream.end()
 	}
@@ -409,7 +413,7 @@
 	if server, ok := c.servers[serverId]; ok {
 		return server, nil
 	}
-	server, err := server.NewServer(serverId, c.veyronProxyEP, c)
+	server, err := server.NewServer(serverId, c.listenSpec, c)
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/wsprd/app/app_test.go b/services/wsprd/app/app_test.go
index ae62d84..5e4abd0 100644
--- a/services/wsprd/app/app_test.go
+++ b/services/wsprd/app/app_test.go
@@ -5,6 +5,7 @@
 	"fmt"
 	"reflect"
 	"testing"
+
 	"veyron.io/veyron/veyron/services/wsprd/lib"
 	"veyron.io/veyron/veyron/services/wsprd/lib/testwriter"
 	"veyron.io/veyron/veyron/services/wsprd/signature"
@@ -19,6 +20,7 @@
 	vom_wiretype "veyron.io/veyron/veyron2/vom/wiretype"
 	"veyron.io/veyron/veyron2/wiretype"
 
+	"veyron.io/veyron/veyron/profiles"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/proxy"
 	mounttable "veyron.io/veyron/veyron/services/mounttable/lib"
 )
@@ -151,7 +153,9 @@
 		return
 	}
 	defer s.Stop()
-	controller, err := NewController(nil, "mockVeyronProxyEP")
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "mockVeyronProxyEP"
+	controller, err := NewController(nil, &spec)
 
 	if err != nil {
 		t.Errorf("Failed to create controller: %v", err)
@@ -185,7 +189,9 @@
 	}
 	defer s.Stop()
 
-	controller, err := NewController(nil, "mockVeyronProxyEP")
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "mockVeyronProxyEP"
+	controller, err := NewController(nil, &spec)
 
 	if err != nil {
 		t.Errorf("unable to create controller: %v", err)
@@ -304,8 +310,10 @@
 	writerCreator := func(int64) lib.ClientWriter {
 		return &writer
 	}
-	controller, err := NewController(writerCreator, "/"+proxyEndpoint,
-		veyron2.NamespaceRoots{"/" + endpoint.String()})
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "/" + proxyEndpoint
+	controller, err := NewController(writerCreator, &spec, veyron2.NamespaceRoots{"/" + endpoint.String()})
+
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/wsprd/ipc/server/server.go b/services/wsprd/ipc/server/server.go
index 3f4c73d..55a21c5 100644
--- a/services/wsprd/ipc/server/server.go
+++ b/services/wsprd/ipc/server/server.go
@@ -7,15 +7,15 @@
 	"fmt"
 	"sync"
 
+	vsecurity "veyron.io/veyron/veyron/security"
+	"veyron.io/veyron/veyron/services/wsprd/lib"
+	"veyron.io/veyron/veyron/services/wsprd/signature"
+
 	"veyron.io/veyron/veyron2"
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/verror"
 	"veyron.io/veyron/veyron2/vlog"
-
-	vsecurity "veyron.io/veyron/veyron/security"
-	"veyron.io/veyron/veyron/services/wsprd/lib"
-	"veyron.io/veyron/veyron/services/wsprd/signature"
 )
 
 type Flow struct {
@@ -94,6 +94,9 @@
 type Server struct {
 	mu sync.Mutex
 
+	// The ipc.ListenSpec to use with server.Listen
+	listenSpec *ipc.ListenSpec
+
 	// The server that handles the ipc layer.  Listen on this server is
 	// lazily started.
 	server ipc.Server
@@ -109,20 +112,17 @@
 	id     uint64
 	helper ServerHelper
 
-	// The proxy to listen through.
-	veyronProxy string
-
 	// The set of outstanding server requests.
 	outstandingServerRequests map[int64]chan *serverRPCReply
 
 	outstandingAuthRequests map[int64]chan error
 }
 
-func NewServer(id uint64, veyronProxy string, helper ServerHelper) (*Server, error) {
+func NewServer(id uint64, listenSpec *ipc.ListenSpec, helper ServerHelper) (*Server, error) {
 	server := &Server{
 		id:                        id,
 		helper:                    helper,
-		veyronProxy:               veyronProxy,
+		listenSpec:                listenSpec,
 		outstandingServerRequests: make(map[int64]chan *serverRPCReply),
 		outstandingAuthRequests:   make(map[int64]chan error),
 	}
@@ -252,8 +252,7 @@
 	}
 
 	if s.endpoint == "" {
-		endpoint, err := s.server.Listen("veyron", s.veyronProxy)
-
+		endpoint, err := s.server.ListenX(s.listenSpec)
 		if err != nil {
 			return "", err
 		}
diff --git a/services/wsprd/wspr.go b/services/wsprd/wspr.go
index 7bab7ce..c169046 100644
--- a/services/wsprd/wspr.go
+++ b/services/wsprd/wspr.go
@@ -6,17 +6,17 @@
 	"veyron.io/veyron/veyron/lib/signals"
 	"veyron.io/veyron/veyron/services/wsprd/wspr"
 	"veyron.io/veyron/veyron2/rt"
+	// TODO(cnicolaou,benj): figure out how to support roaming as a chrome plugi
+	"veyron.io/veyron/veyron/profiles/roaming"
 )
 
 func main() {
-	port := flag.Int("port", 8124, "Port to listen on.")
-	veyronProxy := flag.String("vproxy", "", "The endpoint for the veyron proxy to publish on. This must be set.")
 	identd := flag.String("identd", "", "The endpoint for the identd server.  This must be set.")
 	flag.Parse()
 
 	rt.Init()
 
-	proxy := wspr.NewWSPR(*port, *veyronProxy, *identd)
+	proxy := wspr.NewWSPR(*roaming.ListenSpec, *identd)
 	defer proxy.Shutdown()
 	go func() {
 		proxy.Run()
diff --git a/services/wsprd/wspr/pipe.go b/services/wsprd/wspr/pipe.go
index f4e9894..85f993d 100644
--- a/services/wsprd/wspr/pipe.go
+++ b/services/wsprd/wspr/pipe.go
@@ -129,7 +129,7 @@
 		// TODO(bjornick): Send an error to the client when all of the identity stuff is set up.
 	}
 
-	pipe.controller, err = app.NewController(creator, wspr.veyronProxyEP, veyron2.RuntimeID(id))
+	pipe.controller, err = app.NewController(creator, &wspr.listenSpec, veyron2.RuntimeID(id))
 
 	if err != nil {
 		wspr.rt.Logger().Errorf("Could not create controller: %v", err)
diff --git a/services/wsprd/wspr/wspr.go b/services/wsprd/wspr/wspr.go
index 727807d..3a62cd6 100644
--- a/services/wsprd/wspr/wspr.go
+++ b/services/wsprd/wspr/wspr.go
@@ -21,17 +21,20 @@
 	"fmt"
 	"io"
 	"log"
+	"net"
 	"net/http"
 	_ "net/http/pprof"
 	"sync"
 	"time"
 
-	veyron_identity "veyron.io/veyron/veyron/services/identity"
-	"veyron.io/veyron/veyron/services/wsprd/identity"
 	"veyron.io/veyron/veyron2"
+	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/vlog"
+
+	veyron_identity "veyron.io/veyron/veyron/services/identity"
+	"veyron.io/veyron/veyron/services/wsprd/identity"
 )
 
 const (
@@ -48,9 +51,8 @@
 	tlsCert        *tls.Certificate
 	rt             veyron2.Runtime
 	logger         vlog.Logger
-	port           int
+	listenSpec     ipc.ListenSpec
 	identdEP       string
-	veyronProxyEP  string
 	idManager      *identity.IDManager
 	blesserService veyron_identity.OAuthBlesser
 	pipes          map[*http.Request]*pipe
@@ -91,8 +93,12 @@
 	// registered patterns, not just the URL with Path == "/".'
 	// (http://golang.org/pkg/net/http/#ServeMux)
 	http.Handle("/", http.NotFoundHandler())
-	ctx.logger.VI(1).Infof("Listening on port %d.", ctx.port)
-	httpErr := http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", ctx.port), nil)
+	_, port, err := net.SplitHostPort(ctx.listenSpec.Address)
+	if err != nil {
+		log.Fatal("Failed to extra port from %q", ctx.listenSpec.Address)
+	}
+	ctx.logger.VI(1).Infof("Listening on port %d.", port)
+	httpErr := http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", port), nil)
 	if httpErr != nil {
 		log.Fatalf("Failed to HTTP serve: %s", httpErr)
 	}
@@ -109,8 +115,8 @@
 }
 
 // Creates a new WebSocket Proxy object.
-func NewWSPR(port int, veyronProxyEP, identdEP string, opts ...veyron2.ROpt) *WSPR {
-	if veyronProxyEP == "" {
+func NewWSPR(listenSpec ipc.ListenSpec, identdEP string, opts ...veyron2.ROpt) *WSPR {
+	if listenSpec.Proxy == "" {
 		log.Fatalf("a veyron proxy must be set")
 	}
 	if identdEP == "" {
@@ -128,13 +134,12 @@
 		log.Fatalf("identity.NewIDManager failed: %s", err)
 	}
 
-	return &WSPR{port: port,
-		veyronProxyEP: veyronProxyEP,
-		identdEP:      identdEP,
-		rt:            newrt,
-		logger:        newrt.Logger(),
-		idManager:     idManager,
-		pipes:         map[*http.Request]*pipe{},
+	return &WSPR{listenSpec: listenSpec,
+		identdEP:  identdEP,
+		rt:        newrt,
+		logger:    newrt.Logger(),
+		idManager: idManager,
+		pipes:     map[*http.Request]*pipe{},
 	}
 }
 
diff --git a/services/wsprd/wspr/wspr_test.go b/services/wsprd/wspr/wspr_test.go
index 8981d74..ffeb1fc 100644
--- a/services/wsprd/wspr/wspr_test.go
+++ b/services/wsprd/wspr/wspr_test.go
@@ -13,6 +13,8 @@
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/vdl/vdlutil"
+
+	"veyron.io/veyron/veyron/profiles"
 )
 
 // BEGIN MOCK BLESSER SERVICE
@@ -53,7 +55,9 @@
 // END MOCK BLESSER SERVICE
 
 func setup(t *testing.T) (*WSPR, func()) {
-	wspr := NewWSPR(0, "/mock/proxy", "/mock/identd")
+	spec := *profiles.LocalListenSpec
+	spec.Proxy = "/mock/proxy"
+	wspr := NewWSPR(spec, "/mock/identd")
 	providerId := wspr.rt.Identity()
 
 	wspr.blesserService = newMockBlesserService(providerId)
diff --git a/tools/application/doc.go b/tools/application/doc.go
new file mode 100644
index 0000000..5c8f11f
--- /dev/null
+++ b/tools/application/doc.go
@@ -0,0 +1,85 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The application tool facilitates interaction with the veyron application
+repository.
+
+Usage:
+   application <command>
+
+The application commands are:
+   match       Shows the first matching envelope that matches the given profiles.
+   put         Add the given envelope to the application for the given profiles.
+   remove      removes the application envelope for the given profile.
+   edit        edits the application envelope for the given profile.
+   help        Display help for commands or topics
+Run "application help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Application Match
+
+Shows the first matching envelope that matches the given profiles.
+
+Usage:
+   application match <application> <profiles>
+
+<application> is the full name of the application.
+<profiles> is a comma-separated list of profiles.
+
+Application Put
+
+Add the given envelope to the application for the given profiles.
+
+Usage:
+   application put <application> <profiles> <envelope>
+
+<application> is the full name of the application.
+<profiles> is a comma-separated list of profiles.
+<envelope> is the file that contains a JSON-encoded envelope.
+
+Application Remove
+
+removes the application envelope for the given profile.
+
+Usage:
+   application remove <application> <profile>
+
+<application> is the full name of the application.
+<profile> is a profile.
+
+Application Edit
+
+edits the application envelope for the given profile.
+
+Usage:
+   application edit <application> <profile>
+
+<application> is the full name of the application.
+<profile> is a profile.
+
+Application Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   application help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/application/main.go b/tools/application/main.go
index 2bcd6f3..568f32e 100644
--- a/tools/application/main.go
+++ b/tools/application/main.go
@@ -1,85 +1,12 @@
-// Below is the output from $(application help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The application tool facilitates interaction with the veyron application
-repository.
-
-Usage:
-   application <command>
-
-The application commands are:
-   match       Shows the first matching envelope that matches the given profiles.
-   put         Add the given envelope to the application for the given profiles.
-   remove      removes the application envelope for the given profile.
-   edit        edits the application envelope for the given profile.
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Application Match
-
-Shows the first matching envelope that matches the given profiles.
-
-Usage:
-   application match <application> <profiles>
-
-<application> is the full name of the application.
-<profiles> is a comma-separated list of profiles.
-
-Application Put
-
-Add the given envelope to the application for the given profiles.
-
-Usage:
-   application put <application> <profiles> <envelope>
-
-<application> is the full name of the application.
-<profiles> is a comma-separated list of profiles.
-<envelope> is the file that contains a JSON-encoded envelope.
-
-Application Remove
-
-removes the application envelope for the given profile.
-
-Usage:
-   application remove <application> <profile>
-
-<application> is the full name of the application.
-<profile> is a profile.
-
-Application Edit
-
-edits the application envelope for the given profile.
-
-Usage:
-   application edit <application> <profile>
-
-<application> is the full name of the application.
-<profile> is a profile.
-
-Application Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   application help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/binary/doc.go b/tools/binary/doc.go
new file mode 100644
index 0000000..04afd49
--- /dev/null
+++ b/tools/binary/doc.go
@@ -0,0 +1,73 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The binary tool facilitates interaction with the veyron binary repository.
+
+Usage:
+   binary <command>
+
+The binary commands are:
+   delete      Delete binary
+   download    Download binary
+   upload      Upload binary
+   help        Display help for commands or topics
+Run "binary help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Binary Delete
+
+Delete connects to the binary repository and deletes the specified binary
+
+Usage:
+   binary delete <von>
+
+<von> is the veyron object name of the binary to delete
+
+Binary Download
+
+Download connects to the binary repository, downloads the specified binary, and
+writes it to a file.
+
+Usage:
+   binary download <von> <filename>
+
+<von> is the veyron object name of the binary to download
+<filename> is the name of the file where the binary will be written
+
+Binary Upload
+
+Upload connects to the binary repository and uploads the binary of the specified
+file. When successful, it writes the name of the new binary to stdout.
+
+Usage:
+   binary upload <von> <filename>
+
+<von> is the veyron object name of the binary to upload
+<filename> is the name of the file to upload
+
+Binary Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   binary help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/binary/main.go b/tools/binary/main.go
index a206d11..3edd674 100644
--- a/tools/binary/main.go
+++ b/tools/binary/main.go
@@ -1,73 +1,12 @@
-// Below is the output from $(binary help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The binary tool facilitates interaction with the veyron binary repository.
-
-Usage:
-   binary <command>
-
-The binary commands are:
-   delete      Delete binary
-   download    Download binary
-   upload      Upload binary
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Binary Delete
-
-Delete connects to the binary repository and deletes the specified binary
-
-Usage:
-   binary delete <von>
-
-<von> is the veyron object name of the binary to delete
-
-Binary Download
-
-Download connects to the binary repository, downloads the specified binary, and
-writes it to a file.
-
-Usage:
-   binary download <von> <filename>
-
-<von> is the veyron object name of the binary to download
-<filename> is the name of the file where the binary will be written
-
-Binary Upload
-
-Upload connects to the binary repository and uploads the binary of the specified
-file. When successful, it writes the name of the new binary to stdout.
-
-Usage:
-   binary upload <von> <filename>
-
-<von> is the veyron object name of the binary to upload
-<filename> is the name of the file to upload
-
-Binary Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   binary help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/build/doc.go b/tools/build/doc.go
new file mode 100644
index 0000000..9d7fc7e
--- /dev/null
+++ b/tools/build/doc.go
@@ -0,0 +1,61 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The build tool tool facilitates interaction with the veyron build server.
+
+Usage:
+   build <command>
+
+The build commands are:
+   build       Build veyron Go packages
+   help        Display help for commands or topics
+Run "build help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Build Build
+
+Build veyron Go packages using a remote build server. The command
+collects all source code files that are not part of the Go standard
+library that the target packages depend on, sends them to a build
+server, and receives the built binaries.
+
+Usage:
+   build build [flags] <name> <packages>
+
+<name> is a veyron object name of a build server
+<packages> is a list of packages to build, specified as arguments for
+each command. The format is similar to the go tool.  In its simplest
+form each package is an import path; e.g. "veyron/tools/build". A
+package that ends with "..." does a wildcard match against all
+packages with that prefix.
+
+The build flags are:
+   -arch=amd64: Target architecture.
+   -os=linux: Target operating system.
+
+Build Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   build help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/build/main.go b/tools/build/main.go
index 696e982..c89bbd0 100644
--- a/tools/build/main.go
+++ b/tools/build/main.go
@@ -1,61 +1,12 @@
-// Below is the output from $(build help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The build tool tool facilitates interaction with the veyron build server.
-
-Usage:
-   build <command>
-
-The build commands are:
-   build       Build veyron Go packages
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Build Build
-
-Build veyron Go packages using a remote build server. The command
-collects all source code files that are not part of the Go standard
-library that the target packages depend on, sends them to a build
-server, and receives the built binaries.
-
-Usage:
-   build build [flags] <name> <packages>
-
-<name> is a veyron object name of a build server
-<packages> is a list of packages to build, specified as arguments for
-each command. The format is similar to the go tool.  In its simplest
-form each package is an import path; e.g. "veyron/tools/build". A
-package that ends with "..." does a wildcard match against all
-packages with that prefix.
-
-The build flags are:
-   -arch=amd64: Target architecture.
-   -os=linux: Target operating system.
-
-Build Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   build help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/debug/doc.go b/tools/debug/doc.go
new file mode 100644
index 0000000..e611553
--- /dev/null
+++ b/tools/debug/doc.go
@@ -0,0 +1,162 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+Command-line tool for interacting with the debug server.
+
+Usage:
+   debug <command>
+
+The debug commands are:
+   glob        Returns all matching entries from the namespace
+   logs        Accesses log files
+   stats       Accesses stats
+   pprof       Accesses profiling data
+   help        Display help for commands or topics
+Run "debug help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Debug Glob
+
+Returns all matching entries from the namespace.
+
+Usage:
+   debug glob <pattern> ...
+
+<pattern> is a glob pattern to match.
+
+Debug Logs
+
+Accesses log files
+
+Usage:
+   debug logs <command>
+
+The logs commands are:
+   read        Reads the content of a log file object.
+   size        Returns the size of the a log file object
+
+Debug Logs Read
+
+Reads the content of a log file object.
+
+Usage:
+   debug logs read [flags] <name>
+
+<name> is the name of the log file object.
+
+The read flags are:
+   -f=false: When true, read will wait for new log entries when it reaches the end of the file.
+   -n=-1: The number of log entries to read.
+   -o=0: The position, in bytes, from which to start reading the log file.
+   -v=false: When true, read will be more verbose.
+
+Debug Logs Size
+
+Returns the size of the a log file object.
+
+Usage:
+   debug logs size <name>
+
+<name> is the name of the log file object.
+
+Debug Stats
+
+Accesses stats
+
+Usage:
+   debug stats <command>
+
+The stats commands are:
+   value       Returns the value of the a stats object
+   watchglob   Returns a stream of all matching entries and their values
+
+Debug Stats Value
+
+Returns the value of the a stats object.
+
+Usage:
+   debug stats value [flags] <name>
+
+<name> is the name of the stats object.
+
+The value flags are:
+   -raw=false: When true, the command will display the raw value of the object.
+   -type=false: When true, the type of the values will be displayed.
+
+Debug Stats Watchglob
+
+Returns a stream of all matching entries and their values
+
+Usage:
+   debug stats watchglob [flags] <pattern> ...
+
+<pattern> is a glob pattern to match.
+
+The watchglob flags are:
+   -raw=false: When true, the command will display the raw value of the object.
+   -type=false: When true, the type of the values will be displayed.
+
+Debug Pprof
+
+Accesses profiling data
+
+Usage:
+   debug pprof <command>
+
+The pprof commands are:
+   run         Runs the pprof tool
+   proxy       Runs an http proxy to a pprof object
+
+Debug Pprof Run
+
+Runs the pprof tool
+
+Usage:
+   debug pprof run [flags] <name> <profile> [passthru args] ...
+
+<name> is the name of the pprof object.
+<profile> the name of the profile to use.
+
+All the [passthru args] are passed to the pprof tool directly, e.g.
+
+$ debug pprof run a/b/c heap --text --lines
+$ debug pprof run a/b/c profile -gv
+
+The run flags are:
+   -pprofcmd=veyron go tool pprof: The pprof command to use.
+
+Debug Pprof Proxy
+
+Runs an http proxy to a pprof object
+
+Usage:
+   debug pprof proxy <name>
+
+<name> is the name of the pprof object.
+
+Debug Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   debug help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/debug/main.go b/tools/debug/main.go
index bc021ef..ffa2f5b 100644
--- a/tools/debug/main.go
+++ b/tools/debug/main.go
@@ -1,4 +1,12 @@
-// A command-line tool to interface with the debug server.
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
+
 package main
 
 import (
diff --git a/tools/identity/doc.go b/tools/identity/doc.go
new file mode 100644
index 0000000..ed0b8e2
--- /dev/null
+++ b/tools/identity/doc.go
@@ -0,0 +1,119 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The identity tool helps create and manage keys and blessings that are used for
+identification in veyron.
+
+Usage:
+   identity <command>
+
+The identity commands are:
+   print       Print out information about the provided identity
+   generate    Generate an identity with a newly minted private key
+   bless       Bless another identity with your own
+   seekblessing Seek a blessing from the default veyron identity provider
+   help        Display help for commands or topics
+Run "identity help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Identity Print
+
+Print dumps out information about the identity encoded in the provided file,
+or if no filename is provided, then the identity that would be used by binaries
+started in the same environment.
+
+Usage:
+   identity print [<file>]
+
+<file> is the path to a file containing a base64-encoded, VOM encoded identity,
+typically obtained from this tool. - is used for STDIN and an empty string
+implies the identity encoded in the environment.
+
+Identity Generate
+
+Generate a new private key and create an identity that binds <name> to
+this key.
+
+Since the generated identity has a newly minted key, it will be typically
+unusable at other veyron services as those services have placed no trust
+in this key. In such cases, you likely want to seek a blessing for this
+generated identity using the 'bless' command.
+
+Usage:
+   identity generate [<name>]
+
+<name> is the name to bind the newly minted private key to. If not specified,
+a name will be generated based on the hostname of the machine and the name of
+the user running this command.
+
+Identity Bless
+
+Bless uses the identity of the tool (either from an environment variable or
+explicitly specified using --with) to bless another identity encoded in a
+file (or STDIN). No caveats are applied to this blessing other than expiration,
+which is specified with --for.
+
+The output consists of a base64-vom encoded security.PrivateID or security.PublicID,
+depending on what was provided as input.
+
+For example, if the tool has an identity veyron/user/device, then
+bless /tmp/blessee batman
+will generate a blessing with the name veyron/user/device/batman
+
+The identity of the tool can be specified with the --with flag:
+bless --with /tmp/id /tmp/blessee batman
+
+Usage:
+   identity bless [flags] <file> <name>
+
+<file> is the name of the file containing a base64-vom encoded security.PublicID
+or security.PrivateID
+
+<name> is the name to use for the blessing.
+
+The bless flags are:
+   -for=8760h0m0s: Expiry time of blessing (defaults to 1 year)
+   -with=: Path to file containing identity to bless with (or - for STDIN)
+
+Identity Seekblessing
+
+Seeks a blessing from a default, hardcoded Veyron identity provider which
+requires the caller to first authenticate with Google using OAuth. Simply
+run the command to see what happens.
+
+The blessing is sought for the identity that this tool is using. An alternative
+can be provided with the --for flag.
+
+Usage:
+   identity seekblessing [flags]
+
+The seekblessing flags are:
+   -for=: Path to file containing identity to bless (or - for STDIN)
+   -from=https://proxy.envyor.com:8125/google: URL to use to begin the seek blessings process
+
+Identity Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   identity help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/identity/main.go b/tools/identity/main.go
index 4585fd5..24c8569 100644
--- a/tools/identity/main.go
+++ b/tools/identity/main.go
@@ -1,120 +1,14 @@
-// Below is the output from $(identity help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise "go run" will pick up the
+//    initially empty *.go file, and fail.
+// 4) Since "go run" ignores build directives, we must manually filter out
+//    main_*.go for different platforms.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run `echo *.go | tr ' ' '\n' | grep -v main_darwin.go` help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The identity tool helps create and manage keys and blessings that are used for
-identification in veyron.
-
-Usage:
-   identity <command>
-
-The identity commands are:
-   print       Print out information about the provided identity
-   generate    Generate an identity with a newly minted private key
-   bless       Bless another identity with your own
-   seekblessing Seek a blessing from the default veyron identity provider
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Identity Print
-
-Print dumps out information about the identity encoded in the provided file,
-or if no filename is provided, then the identity that would be used by binaries
-started in the same environment.
-
-Usage:
-   identity print [<file>]
-
-<file> is the path to a file containing a base64-encoded, VOM encoded identity,
-typically obtained from this tool. - is used for STDIN and an empty string
-implies the identity encoded in the environment.
-
-Identity Generate
-
-Generate a new private key and create an identity that binds <name> to
-this key.
-
-Since the generated identity has a newly minted key, it will be typically
-unusable at other veyron services as those services have placed no trust
-in this key. In such cases, you likely want to seek a blessing for this
-generated identity using the 'bless' command.
-
-Usage:
-   identity generate [<name>]
-
-<name> is the name to bind the newly minted private key to. If not specified,
-a name will be generated based on the hostname of the machine and the name of
-the user running this command.
-
-Identity Bless
-
-Bless uses the identity of the tool (either from an environment variable or
-explicitly specified using --with) to bless another identity encoded in a
-file (or STDIN). No caveats are applied to this blessing other than expiration,
-which is specified with --for.
-
-The output consists of a base64-vom encoded security.PrivateID or security.PublicID,
-depending on what was provided as input.
-
-For example, if the tool has an identity veyron/user/device, then
-bless /tmp/blessee batman
-will generate a blessing with the name veyron/user/device/batman
-
-The identity of the tool can be specified with the --with flag:
-bless --with /tmp/id /tmp/blessee batman
-
-Usage:
-   identity bless [flags] <file> <name>
-
-<file> is the name of the file containing a base64-vom encoded security.PublicID
-or security.PrivateID
-
-<name> is the name to use for the blessing.
-
-The bless flags are:
-   -for=8760h0m0s: Expiry time of blessing (defaults to 1 year)
-   -with=: Path to file containing identity to bless with (or - for STDIN)
-
-Identity Seekblessing
-
-Seeks a blessing from a default, hardcoded Veyron identity provider which
-requires the caller to first authenticate with Google using OAuth. Simply
-run the command to see what happens.
-
-The blessing is sought for the identity that this tool is using. An alternative
-can be provided with the --for flag.
-
-Usage:
-   identity seekblessing [flags]
-
-The seekblessing flags are:
-   -clientid=761523829214-4ms7bae18ef47j6590u9ncs19ffuo7b3.apps.googleusercontent.com: OAuth client ID used to make OAuth request for an authorization code
-   -for=: Path to file containing identity to bless (or - for STDIN)
-   -from=/proxy.envyor.com:8101/identity/veyron-test/google: Object name of Veyron service running the identity.OAuthBlesser service to seek blessings from
-
-Identity Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   identity help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/mounttable/doc.go b/tools/mounttable/doc.go
new file mode 100644
index 0000000..fc63e5a
--- /dev/null
+++ b/tools/mounttable/doc.go
@@ -0,0 +1,85 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The mounttable tool facilitates interaction with a Veyron mount table.
+
+Usage:
+   mounttable <command>
+
+The mounttable commands are:
+   glob        returns all matching entries in the mount table
+   mount       Mounts a server <name> onto a mount table
+   unmount     removes server <name> from the mount table
+   resolvestep takes the next step in resolving a name.
+   help        Display help for commands or topics
+Run "mounttable help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Mounttable Glob
+
+returns all matching entries in the mount table
+
+Usage:
+   mounttable glob <mount name> <pattern>
+
+<mount name> is a mount name on a mount table.
+<pattern> is a glob pattern that is matched against all the entries below the
+specified mount name.
+
+Mounttable Mount
+
+Mounts a server <name> onto a mount table
+
+Usage:
+   mounttable mount <mount name> <name> <ttl>
+
+<mount name> is a mount name on a mount table.
+<name> is the rooted object name of the server.
+<ttl> is the TTL of the new entry. It is a decimal number followed by a unit
+suffix (s, m, h). A value of 0s represents an infinite duration.
+
+Mounttable Unmount
+
+removes server <name> from the mount table
+
+Usage:
+   mounttable unmount <mount name> <name>
+
+<mount name> is a mount name on a mount table.
+<name> is the rooted object name of the server.
+
+Mounttable Resolvestep
+
+takes the next step in resolving a name.
+
+Usage:
+   mounttable resolvestep <mount name>
+
+<mount name> is a mount name on a mount table.
+
+Mounttable Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   mounttable help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/mounttable/main.go b/tools/mounttable/main.go
index 80216f1..741e62f 100644
--- a/tools/mounttable/main.go
+++ b/tools/mounttable/main.go
@@ -1,85 +1,12 @@
-// Below is the output from $(mounttable help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The mounttable tool facilitates interaction with a Veyron mount table.
-
-Usage:
-   mounttable <command>
-
-The mounttable commands are:
-   glob        returns all matching entries in the mount table
-   mount       Mounts a server <name> onto a mount table
-   unmount     removes server <name> from the mount table
-   resolvestep takes the next step in resolving a name.
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Mounttable Glob
-
-returns all matching entries in the mount table
-
-Usage:
-   mounttable glob <mount name> <pattern>
-
-<mount name> is a mount name on a mount table.
-<pattern> is a glob pattern that is matched against all the entries below the
-specified mount name.
-
-Mounttable Mount
-
-Mounts a server <name> onto a mount table
-
-Usage:
-   mounttable mount <mount name> <name> <ttl>
-
-<mount name> is a mount name on a mount table.
-<name> is the rooted object name of the server.
-<ttl> is the TTL of the new entry. It is a decimal number followed by a unit
-suffix (s, m, h). A value of 0s represents an infinite duration.
-
-Mounttable Unmount
-
-removes server <name> from the mount table
-
-Usage:
-   mounttable unmount <mount name> <name>
-
-<mount name> is a mount name on a mount table.
-<name> is the rooted object name of the server.
-
-Mounttable Resolvestep
-
-takes the next step in resolving a name.
-
-Usage:
-   mounttable resolvestep <mount name>
-
-<mount name> is a mount name on a mount table.
-
-Mounttable Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   mounttable help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/namespace/doc.go b/tools/namespace/doc.go
new file mode 100644
index 0000000..addc28d
--- /dev/null
+++ b/tools/namespace/doc.go
@@ -0,0 +1,108 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The namespace tool facilitates interaction with the Veyron namespace.
+
+The namespace roots are set from environment variables that have a name
+starting with NAMESPACE_ROOT, e.g. NAMESPACE_ROOT, NAMESPACE_ROOT_2,
+NAMESPACE_ROOT_GOOGLE, etc.
+
+Usage:
+   namespace <command>
+
+The namespace commands are:
+   glob        Returns all matching entries from the namespace
+   mount       Adds a server to the namespace
+   unmount     Removes a server from the namespace
+   resolve     Translates a object name to its object address(es)
+   resolvetomt Finds the address of the mounttable that holds an object name
+   unresolve   Returns the rooted object names for the given object name
+   help        Display help for commands or topics
+Run "namespace help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Namespace Glob
+
+Returns all matching entries from the namespace.
+
+Usage:
+   namespace glob <pattern>
+
+<pattern> is a glob pattern that is matched against all the names below the
+specified mount name.
+
+Namespace Mount
+
+Adds server <server> to the namespace with name <name>.
+
+Usage:
+   namespace mount <name> <server> <ttl>
+
+<name> is the name to add to the namespace.
+<server> is the object address of the server to add.
+<ttl> is the TTL of the new entry. It is a decimal number followed by a unit
+suffix (s, m, h). A value of 0s represents an infinite duration.
+
+Namespace Unmount
+
+Removes server <server> with name <name> from the namespace.
+
+Usage:
+   namespace unmount <name> <server>
+
+<name> is the name to remove from the namespace.
+<server> is the object address of the server to remove.
+
+Namespace Resolve
+
+Translates a object name to its object address(es).
+
+Usage:
+   namespace resolve <name>
+
+<name> is the name to resolve.
+
+Namespace Resolvetomt
+
+Finds the address of the mounttable that holds an object name.
+
+Usage:
+   namespace resolvetomt <name>
+
+<name> is the name to resolve.
+
+Namespace Unresolve
+
+Returns the rooted object names for the given object name.
+
+Usage:
+   namespace unresolve <name>
+
+<name> is the object name to unresolve.
+
+Namespace Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   namespace help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/namespace/main.go b/tools/namespace/main.go
index babf6ca..9ed1881 100644
--- a/tools/namespace/main.go
+++ b/tools/namespace/main.go
@@ -1,108 +1,12 @@
-// Below is the output from $(namespace help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The namespace tool facilitates interaction with the Veyron namespace.
-
-The namespace roots are set from environment variables that have a name
-starting with NAMESPACE_ROOT, e.g. NAMESPACE_ROOT, NAMESPACE_ROOT_2,
-NAMESPACE_ROOT_GOOGLE, etc.
-
-Usage:
-   namespace <command>
-
-The namespace commands are:
-   glob        Returns all matching entries from the namespace
-   mount       Adds a server to the namespace
-   unmount     Removes a server from the namespace
-   resolve     Translates a object name to its object address(es)
-   resolvetomt Finds the address of the mounttable that holds an object name
-   unresolve   Returns the rooted object names for the given object name
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Namespace Glob
-
-Returns all matching entries from the namespace.
-
-Usage:
-   namespace glob <pattern>
-
-<pattern> is a glob pattern that is matched against all the names below the
-specified mount name.
-
-Namespace Mount
-
-Adds server <server> to the namespace with name <name>.
-
-Usage:
-   namespace mount <name> <server> <ttl>
-
-<name> is the name to add to the namespace.
-<server> is the object address of the server to add.
-<ttl> is the TTL of the new entry. It is a decimal number followed by a unit
-suffix (s, m, h). A value of 0s represents an infinite duration.
-
-Namespace Unmount
-
-Removes server <server> with name <name> from the namespace.
-
-Usage:
-   namespace unmount <name> <server>
-
-<name> is the name to remove from the namespace.
-<server> is the object address of the server to remove.
-
-Namespace Resolve
-
-Translates a object name to its object address(es).
-
-Usage:
-   namespace resolve <name>
-
-<name> is the name to resolve.
-
-Namespace Resolvetomt
-
-Finds the address of the mounttable that holds an object name.
-
-Usage:
-   namespace resolvetomt <name>
-
-<name> is the name to resolve.
-
-Namespace Unresolve
-
-Returns the rooted object names for the given object name.
-
-Usage:
-   namespace unresolve <name>
-
-<name> is the object name to unresolve.
-
-Namespace Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   namespace help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/profile/doc.go b/tools/profile/doc.go
new file mode 100644
index 0000000..6a71540
--- /dev/null
+++ b/tools/profile/doc.go
@@ -0,0 +1,89 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The profile tool facilitates interaction with the veyron profile repository.
+
+Usage:
+   profile <command>
+
+The profile commands are:
+   label       Shows a human-readable profile key for the profile.
+   description Shows a human-readable profile description for the profile.
+   spec        Shows the specification of the profile.
+   put         Sets a placeholder specification for the profile.
+   remove      removes the profile specification for the profile.
+   help        Display help for commands or topics
+Run "profile help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Profile Label
+
+Shows a human-readable profile key for the profile.
+
+Usage:
+   profile label <profile>
+
+<profile> is the full name of the profile.
+
+Profile Description
+
+Shows a human-readable profile description for the profile.
+
+Usage:
+   profile description <profile>
+
+<profile> is the full name of the profile.
+
+Profile Spec
+
+Shows the specification of the profile.
+
+Usage:
+   profile spec <profile>
+
+<profile> is the full name of the profile.
+
+Profile Put
+
+Sets a placeholder specification for the profile.
+
+Usage:
+   profile put <profile>
+
+<profile> is the full name of the profile.
+
+Profile Remove
+
+removes the profile specification for the profile.
+
+Usage:
+   profile remove <profile>
+
+<profile> is the full name of the profile.
+
+Profile Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   profile help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/profile/main.go b/tools/profile/main.go
index f6cf6d2..2af525d 100644
--- a/tools/profile/main.go
+++ b/tools/profile/main.go
@@ -1,89 +1,12 @@
-// Below is the output from $(profile help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The profile tool facilitates interaction with the veyron profile repository.
-
-Usage:
-   profile <command>
-
-The profile commands are:
-   label       Shows a human-readable profile key for the profile.
-   description Shows a human-readable profile description for the profile.
-   spec        Shows the specification of the profile.
-   put         Sets a placeholder specification for the profile.
-   remove      removes the profile specification for the profile.
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Profile Label
-
-Shows a human-readable profile key for the profile.
-
-Usage:
-   profile label <profile>
-
-<profile> is the full name of the profile.
-
-Profile Description
-
-Shows a human-readable profile description for the profile.
-
-Usage:
-   profile description <profile>
-
-<profile> is the full name of the profile.
-
-Profile Spec
-
-Shows the specification of the profile.
-
-Usage:
-   profile spec <profile>
-
-<profile> is the full name of the profile.
-
-Profile Put
-
-Sets a placeholder specification for the profile.
-
-Usage:
-   profile put <profile>
-
-<profile> is the full name of the profile.
-
-Profile Remove
-
-removes the profile specification for the profile.
-
-Usage:
-   profile remove <profile>
-
-<profile> is the full name of the profile.
-
-Profile Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   profile help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (
diff --git a/tools/vrpc/doc.go b/tools/vrpc/doc.go
new file mode 100644
index 0000000..a2cb64e
--- /dev/null
+++ b/tools/vrpc/doc.go
@@ -0,0 +1,74 @@
+// This file was auto-generated via go generate.
+// DO NOT UPDATE MANUALLY
+
+/*
+The vrpc tool facilitates interaction with Veyron RPC servers. In particular,
+it can be used to 1) find out what API a Veyron RPC server exports and
+2) send requests to a Veyron RPC server.
+
+Usage:
+   vrpc <command>
+
+The vrpc commands are:
+   describe    Describe the API of an Veyron RPC server
+   invoke      Invoke a method of an Veyron RPC server
+   help        Display help for commands or topics
+Run "vrpc help [command]" for command usage.
+
+The global flags are:
+   -alsologtostderr=true: log to standard error as well as files
+   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
+   -log_dir=: if non-empty, write log files to this directory
+   -logtostderr=false: log to standard error instead of files
+   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
+   -stderrthreshold=2: logs at or above this threshold go to stderr
+   -v=0: log level for V logs
+   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+   -vv=0: log level for V logs
+
+Vrpc Describe
+
+Describe connects to the Veyron RPC server identified by <server>, finds out what
+its API is, and outputs a succint summary of this API to the standard output.
+
+Usage:
+   vrpc describe <server>
+
+<server> identifies the Veyron RPC server. It can either be the object address of
+the server or an Object name in which case the vrpc will use Veyron's name
+resolution to match this name to an end-point.
+
+Vrpc Invoke
+
+Invoke connects to the Veyron RPC server identified by <server>, invokes the method
+identified by <method>, supplying the arguments identified by <args>, and outputs
+the results of the invocation to the standard output.
+
+Usage:
+   vrpc invoke <server> <method> <args>
+
+<server> identifies the Veyron RPC server. It can either be the object address of
+the server or an Object name in which case the vrpc will use Veyron's name
+resolution to match this name to an end-point.
+
+<method> identifies the name of the method to be invoked.
+
+<args> identifies the arguments of the method to be invoked. It should be a list
+of values in a VOM JSON format that can be reflected to the correct type
+using Go's reflection.
+
+Vrpc Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
+
+Usage:
+   vrpc help [flags] [command/topic ...]
+
+[command/topic ...] optionally identifies a specific sub-command or help topic.
+
+The help flags are:
+   -style=text: The formatting style for help output, either "text" or "godoc".
+*/
+package main
diff --git a/tools/vrpc/main.go b/tools/vrpc/main.go
index 23c91af..46a30c8 100644
--- a/tools/vrpc/main.go
+++ b/tools/vrpc/main.go
@@ -1,74 +1,12 @@
-// Below is the output from $(vrpc help -style=godoc ...)
+// The following enables go generate to generate the doc.go file.
+// Things to look out for:
+// 1) go:generate evaluates double-quoted strings into a single argument.
+// 2) go:generate performs $NAME expansion, so the bash cmd can't contain '$'.
+// 3) We generate into a *.tmp file first, otherwise go run will pick up the
+//    initially empty *.go file, and fail.
+//
+//go:generate bash -c "{ echo -e '// This file was auto-generated via go generate.\n// DO NOT UPDATE MANUALLY\n\n/*' && veyron go run *.go help -style=godoc ... && echo -e '*/\npackage main'; } > ./doc.go.tmp && mv ./doc.go.tmp ./doc.go"
 
-/*
-The vrpc tool facilitates interaction with Veyron RPC servers. In particular,
-it can be used to 1) find out what API a Veyron RPC server exports and
-2) send requests to a Veyron RPC server.
-
-Usage:
-   vrpc <command>
-
-The vrpc commands are:
-   describe    Describe the API of an Veyron RPC server
-   invoke      Invoke a method of an Veyron RPC server
-   help        Display help for commands
-
-The global flags are:
-   -alsologtostderr=true: log to standard error as well as files
-   -log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
-   -log_dir=: if non-empty, write log files to this directory
-   -logtostderr=false: log to standard error instead of files
-   -max_stack_buf_size=4292608: max size in bytes of the buffer to use for logging stack traces
-   -stderrthreshold=2: logs at or above this threshold go to stderr
-   -v=0: log level for V logs
-   -vmodule=: comma-separated list of pattern=N settings for file-filtered logging
-   -vv=0: log level for V logs
-
-Vrpc Describe
-
-Describe connects to the Veyron RPC server identified by <server>, finds out what
-its API is, and outputs a succint summary of this API to the standard output.
-
-Usage:
-   vrpc describe <server>
-
-<server> identifies the Veyron RPC server. It can either be the object address of
-the server or an Object name in which case the vrpc will use Veyron's name
-resolution to match this name to an end-point.
-
-Vrpc Invoke
-
-Invoke connects to the Veyron RPC server identified by <server>, invokes the method
-identified by <method>, supplying the arguments identified by <args>, and outputs
-the results of the invocation to the standard output.
-
-Usage:
-   vrpc invoke <server> <method> <args>
-
-<server> identifies the Veyron RPC server. It can either be the object address of
-the server or an Object name in which case the vrpc will use Veyron's name
-resolution to match this name to an end-point.
-
-<method> identifies the name of the method to be invoked.
-
-<args> identifies the arguments of the method to be invoked. It should be a list
-of values in a VOM JSON format that can be reflected to the correct type
-using Go's reflection.
-
-Vrpc Help
-
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
-
-Usage:
-   vrpc help [flags] [command ...]
-
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
-
-The help flags are:
-   -style=text: The formatting style for help output, either "text" or "godoc".
-*/
 package main
 
 import (