Previously running "go tool vet" said
vet: invalid command: want .cfg file (this reduced version of vet is
intended to be run only by the 'go vet' command)
With this change it says:
vet: invoking "go tool vet" directly is unsupported; use "go vet"
Updates golang/go#28869
Change-Id: I603ab2f75bb52d860e5cd7466e89d051dfbf3f08
Reviewed-on: https://go-review.googlesource.com/c/152217
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
For clarity and performance reasons, we want the fast path of goimports
to be purely syntactic. Packages whose import paths don't match their
package names make this harder. Before this CL, we parsed each imported
package to get its real package name. Now, we make named imports for
such packages, and on subsequent runs we don't have to do the extra
work.
A package name matches its import path if the name is the last segment
of the path, or the next-to-last before a version suffix vNN. gopkg.in
style .vNN suffixes are considered mismatching.
The previous attempt (CL 145699) failed because I assumed we'd be able
to find all packages from scratch. That's not true if the import path is
completely unrelated to the package name. To avoid that problem, rather
than removing and re-adding mismatched imports, we just literally add
names to them.
Fixesgolang/go#28428
Change-Id: I93bd820f5956162ae9c99afa73bdcfc570a2e7b4
Reviewed-on: https://go-review.googlesource.com/c/152000
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Redesign fixImports to have a clearer workflow, and hopefully create
clear places to plug in go/packages. This change is mostly
performance/functionality neutral, but does clean up some corner cases.
The new flow centers around the pass type, which encapsulates the
process of loading information about the current code, adding possible
new imports, and trying to apply them. I'm hoping that it's easy to
understand what's happening just by reading fixImports, and that new
sources of information (e.g. a network service) fit well into that flow.
Where possible, I left the functions near where they were extracted in
hopes of making review easier, but it's probably not going to be easy.
Sorry. I might move them into a more reasonable order in a followup CL.
Notable modifications:
- The stdlib cache is restructured to match pass' internal storage.
- Sibling imports with conflicting names are considered.
- Package name lookups are batched, hopefully making it easier to plug
in go/packages.
Questions that might be worth answering:
- Should findImportGoPath really scan $GOROOT? Unless the user is working
on a development copy, it's totally redundant with the cache.
- What is the best way to combine candidates from multiple sources?
Right now the first one wins, and findStdlibCandidates relies on that
to get crypto/rand ahead of math/rand.
- In the third pass, should it assume sibling imports or should it
actually go load the exports? It didn't load them before, but that seems
arbitrary.
Change-Id: Ie4ad0b69bfbe9b16883f2b0517b1278575c9f540
Reviewed-on: https://go-review.googlesource.com/c/150339
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
It used to rewrite golang.org/x/* imports to golang_org/x/*.
But https://golang.org/cl/147443 renamed golang_org/x to internal/x,
which broke the ability to run "go generate" in net/http, which runs
this command.
Given that net/http (and Go itself) is the only caller of cmd/bundle
or the -underscore flag, repurpose it to instead rewrite the
golang.org/x imports to internal/x, like CL 147443. But we keep its
name out of laziness and to minimize the number of cross-repo changes
needed.
Change-Id: I310ce8b45812a26c8b3522eaf407fffff138b1be
Reviewed-on: https://go-review.googlesource.com/c/152097
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This CL updates the importer to match the original code in the std lib
but for the necessary changes to make the code work in x/tools and
with older versions of the std lib.
Notably, it brings over changes from:
https://go-review.googlesource.com/c/152078https://go-review.googlesource.com/c/152077https://golang.org/cl/151997https://golang.org/cl/151557https://golang.org/cl/149957
including test fixes (we want tests to run when gccgo is available,
not just when all go tools are gccgo-based), bug fixes (primarily
related to aliases), performance enhancements, and new code to read
the V3 export data emitted by the most recent gccgo.
Change-Id: I2d34bace23769e62795599b93db8295169076594
Reviewed-on: https://go-review.googlesource.com/c/151717
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This support is not perfect, but should produce more accurate results than
the previous behavior, which is to silently drop those files.
Change-Id: Ia00c042bf303e9ec0fb1cbd579c0fccb29073de0
Reviewed-on: https://go-review.googlesource.com/c/151999
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
The expectation langauge is LL(1) but the scanner does not support true
lookahead
This change adds a true LL(1) token stream and rewrites the parser in terms of
it.
Also clean up the error handling and use the behaviour to fix all the broken
edge cases, and then change the tests to cover the now correct behaviour.
Change-Id: If3d602cda490ed2f4732efce400eb8eabce8a8ec
Reviewed-on: https://go-review.googlesource.com/c/151998
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
When I tried to use the Emacs instructions, I found there was no go-mode-autoloads available. Searching, I found: https://github.com/dominikh/go-mode.el/issues/222
Removing the (require) line solved my problem.
I don't know what the add-to-list invocation was supposed to do, so I propose removing it too.
Change-Id: I027654dd2c634f0747dcefee71f413866049a608
GitHub-Last-Rev: 7d43dabf6a46210eaaa849900c13cd52001878cb
GitHub-Pull-Request: golang/tools#57
Reviewed-on: https://go-review.googlesource.com/c/151680
Reviewed-by: Dominik Honnef <dominik@honnef.co>
This allows for multi-line comments where a new line is allowed between
expectations.
It also allows trailing new lines and commas in expectation lists.
Change-Id: I714f8ad483a0238281f26ceb74ce9e73d922af69
Reviewed-on: https://go-review.googlesource.com/c/151718
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Our tests compare import graphs from go/packages to expected graphs,
and one of the test cases imports math/bits. But in tip math/bits
picked up a dependency on unsafe, which means the expected graph
is different when run against a Go version >= go1.11. Remove that edge
before comparing against the expected graph to work around the breakage.
Change-Id: Ic586a75ba530741d251df9f87d0817a8e37d92ea
Reviewed-on: https://go-review.googlesource.com/c/151657
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Currently, stress logs are named "/tmp/go-stress-" plus a random
number. This makes it really annoying to tease apart failures from
different stress runs.
This CL changes the default prefix to
"/tmp/go-stress-<ISO 8601 date/time>-<random number>"
where the date/time part is when the stress command started. This
naming clusters logs by stress invocation, making it easy to tease
apart invocations, even if there are multiple stresses running
concurrently or they are run back-to-back.
This also provides a flag to override this prefix.
Change-Id: I043e5ee7168ba6db4e2355e39b147071edbc6864
Reviewed-on: https://go-review.googlesource.com/c/150047
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
The LSP specification doesn't have a Score field, so we must provide
sortText to the protocol in order to maintain the correct order.
Change-Id: I075849f520c21a0465dfb2060c598d8bae5f876b
Reviewed-on: https://go-review.googlesource.com/c/151237
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This CL moves gorename TODOs from -help output
to a comment in the code.
Fixesgolang/go#25824
Change-Id: I60e843804ebf1e374882ea3424e4ab749d038c1f
Reviewed-on: https://go-review.googlesource.com/c/150937
Run-TryBot: Yury Smolsky <yury@smolsky.by>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
When running go list for a file= query, the go/packages code previously ran "go list ." command in the directory of the provided file. This was necessary for compatibility with the fallback, but caused problems when running file= queries for files in the module cache. We now use absolute directory paths (supported in Go >=1.11) in the non-fallback case and retain the previous behavior in the fallback case.
Change-Id: I3a9feaaeda12e068ec3d510b5f78437482c65b4c
Reviewed-on: https://go-review.googlesource.com/c/148199
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This is needed because testing.TB does not have a "Run" method for sub
tests, and the signature of the function it takes needs to match the
testing parameter.
Change-Id: I9201dd75891ed1bda300a4247fe7eac1e25bd30d
Reviewed-on: https://go-review.googlesource.com/c/150857
Run-TryBot: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Pass in parameters to the driver in stdin rather than through argv.
This allows us to more easily route parameters to the driver and add
more parameters without breaking users. The driver doesn't need to
have the same interface as go list, because it's unlikely the driver interface
will converge with the go list interface.
We still pass in the query "words" to the driver in the argv, because
that's as good a place as any, but there's no "list" command.
Question: should we add a "command" option to the driverRequest struct?
Change-Id: Ifdbb3f84b6bfd04259f5ab63e756341d7f69de9b
Reviewed-on: https://go-review.googlesource.com/c/150337
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Also, trigger signature help on completion of a function (the "(" as a
trigger character doesn't work if it's part of a completion).
Change-Id: I952cb875fa72a741d7952178f85e20f9efa3ebff
Reviewed-on: https://go-review.googlesource.com/c/150638
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
If signature help is enabled, we should not offer parameter suggestions.
If signature help is not enabled, the user should be able to tab
through parameter completions.
Change-Id: I10990ef4aefb306ddbf51ed14cc1110065eba655
Reviewed-on: https://go-review.googlesource.com/c/150637
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Add typepos field to json output of describe command. This field shows where
type of current (under cursor) identifier is defined. This will help code editors
implement command 'Go to type definition'.
Implements [#27308](https://github.com/golang/go/issues/27308)
Change-Id: I4e02ddbdc03fecec98135b8996f9562a88a9cfb8
GitHub-Last-Rev: be47e397a293a96d3d39776d6090d861e7904a24
GitHub-Pull-Request: golang/tools#50
Reviewed-on: https://go-review.googlesource.com/c/140379
Reviewed-by: Alan Donovan <adonovan@google.com>
If a file ends with an empty newline, go/token treats the newline as the
final character of the previous line. VSCode, however, treats this as a
final line with no characters. We handle this by determining if the file
we are formatting ends with a newline character and updating the
protocol ranges accordingly.
Change-Id: Id8be0fd776ae65c8f0f937f3e718825e407cb217
Reviewed-on: https://go-review.googlesource.com/c/150338
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This makes our internal version of go to definition be tested with the
same test data that godef now uses
Change-Id: I04e488b6b9b2d891181f202ea1125b823a079c50
Reviewed-on: https://go-review.googlesource.com/c/150045
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
It is impossible to reconstruct a line and column correctly from export data, so
we have to attempt to find open and process the file in order to guess what the
original pos was when we have one that originated in export data.
This occurs in any time in go to definition when the target is not in the same
pacakge as the source.
Change-Id: Ib2ee404d4f1c39d8bd7f1fbc2096d8d6cbeed6f8
Reviewed-on: https://go-review.googlesource.com/c/150044
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
The vet-lite tool was useful for developing the new cmd/vet but no
longer needs to exist. This changes removes the command and moves the
main.go file to the unitchecker directory where it serves as an
example and can still be built for testing and debugging.
See also https://go-review.googlesource.com/c/go/+/150297.
Change-Id: Ic10c7cd3aeeaa2e1397dd81939616c6877f7005d
Reviewed-on: https://go-review.googlesource.com/c/150298
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
This makes it possible to run just one type of test if needed
Also add some verification that the right number of tests is being run
And finally collect all the expectations up front, including the completions.
Change-Id: Iee6045a8ad89fa399fefd03bc0712770701ec6f8
Reviewed-on: https://go-review.googlesource.com/c/149737
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Also improve the error messages from a failing diagnostic tests so you can read
them.
Change-Id: I3554ce5a029de22a55a9636ed26ba02d95fc3246
Reviewed-on: https://go-review.googlesource.com/c/150042
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This allows it to be used in benchmarks as well as tests.
Change-Id: I1eb7307a0a7d27c541b14dd8b84c4bc2c770f3c9
Reviewed-on: https://go-review.googlesource.com/c/150257
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
As Alan rightfully guessed, porting the stdmethods check to use go/types
required the use of types.TypeString not only when printing signatures
in warnings, but also when matching them.
Added a simple test case too.
Fixesgolang/go#28792.
Change-Id: Ifbbdd4b1a2f1090d6f9a1674d52b8f0887a67d06
Reviewed-on: https://go-review.googlesource.com/c/149977
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
All of these were quite heavily indented for no good reason; breaking or
returning early makes the code easier to read and follow.
Change-Id: Ic539517b07604d71495277b16f1b7eb60d2e3d3c
Reviewed-on: https://go-review.googlesource.com/c/149978
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Go's CL numbers as assigned by Gerrit have started to collide with the
lower numbers in the sparse set of CL numbers as returned by our old
code review system (Rietveld).
The old heuristic no longer works now that Gerrit CL numbers have
reached 150000.
Instead, include a map of the low Rietveld CL numbers where we might
overlap and bump the threshold heuristic up.
Updates golang/go#28836
Change-Id: Ice719ab807ce3922b885a800ac873cdbf165a8f7
Reviewed-on: https://go-review.googlesource.com/c/150057
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
The -json and -c=N flags, formerly belonging only to the
go/packages-based {single,multi}checkers, are now supported by
unitchecker as well.
The no-op -source, -v, -all, and -tags flags, formerly belonging only
to unitchecker, have moved to the analysisflags package, which is
common to all checkers.
The -flags flag now reports all registered flags (except the
{single,multi}checker-only debugging flags) rather than just those
related to analyzers, allowing one to say: 'go vet -json' or 'go vet -c=1'.
The code for printing diagnostics, either plain or in JSON, has been
factored and moved into the common analysisflags package.
This CL depends on https://go-review.googlesource.com/c/go/+/149960 to
cmd/go, which causes 'go vet' to populate the ID field of the *.cfg.
This field is used as a key in the JSON tree.
Added basic tests of the new -json and -c unitchecker flags.
Change-Id: Ia7a3a9adc86de067de060732d2c200c58be3945a
Reviewed-on: https://go-review.googlesource.com/c/150038
Reviewed-by: Michael Matloob <matloob@golang.org>
It's only for debugging.
Change-Id: Ic2aacc6bcb52607c253f02b963e0e281213142b0
Reviewed-on: https://go-review.googlesource.com/c/150039
Reviewed-by: Michael Matloob <matloob@golang.org>
The suite used by this tool matters to GOROOT/src/cmd/vet/all and the
'vetall' builder. Add a comment to this effect.
Change-Id: I2e16eb670b03a7bae8224625baaebd1298e2424c
Reviewed-on: https://go-review.googlesource.com/c/150040
Reviewed-by: Michael Matloob <matloob@golang.org>
These are intended only for debug printing and error messages for the most
common protocol types that you need to know the contents of.
Change-Id: I1f0f7b17b4b12c3b26096b46808bce37c3722ced
Reviewed-on: https://go-review.googlesource.com/c/150037
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
The go/format.Node function fails silently on malformed ASTs, even
though it writes out an invalid tree containing the strings "BadExpr"
and "BadStmt". We fix this by checking for *ast.Bad{Expr,Decl,Stmt}
before running the function. Ultimately, this should be fixed upstream
and just return an error from format.Node.
Change-Id: I2ba25551f0e97c0321d8e757de67360af44044d7
Reviewed-on: https://go-review.googlesource.com/c/149613
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This change allows it to jump to the type if you are directly on the
embedded field when you trigger go to definition.
Change-Id: I48825a5a683e69c0714978c76b1d188d40b38c5d
Reviewed-on: https://go-review.googlesource.com/c/149615
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This walks the list produced by the MustCopyFileTree call instead of
scanning the file system
It also removes the .in file from the copies, so only the trimmed
version will be present in the exported data set.
Change-Id: I95b0298ab49021a09f6b26e08158ce162b5a99e6
Reviewed-on: https://go-review.googlesource.com/c/149614
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
The recursive stringer check should report cases such as
func (x T) String() string { return fmt.Sprint(x) }
in which the receiver x (or possibly &x) was passed into a fmt print call.
However, in translating it from the go/ast to the go/types representation,
I inadvertently made it report any situation in which a value of type T
was passed to fmt, even when the value is not x, as in:
func (cons *cons) String() string {
... fmt.Sprint(cons.cdr) ...
}
Fixed and tested.
Change-Id: I57e88755c9989deaaad45cc306a604f3db4ee269
Reviewed-on: https://go-review.googlesource.com/c/149616
Reviewed-by: Michael Matloob <matloob@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
(By "vet lite", we mean static tools that must be invoked by a build
system, such as 'go vet'.)
This CL publishes the former internal/unitchecker package.
Its misnamed Main function is renamed Run, and it has a new Main
that does the steps of a real main (log, flag, etc).
The motivation for this change is to reduce cmd/vet-lite to the point
of triviality to simplify the maintenance of the vendored copy of
x/tools in GOROOT, because GOROOT/src/cmd/vet will need a copy of that
logic. It is now essentially a one-liner.
Also, improve usage messages; analysisflags.PrintUsage wasn't
appropriate for all callers so it has been eliminated.
Each of {single,multi,unit}checker prints its own 1-line usage message.
Change-Id: I214c0e4ae7a2923eee8df3f7548341f2320cad2b
Reviewed-on: https://go-review.googlesource.com/c/149742
Reviewed-by: Michael Matloob <matloob@golang.org>
- add a no-op -tags flag for legacy compatibility.
Tags processing is done by go vet, but it passes the flag on.
Exercised by cmd/go TestGoVetWithTags.
- rename OtherFiles to NonGoFiles in the JSON *.cfg file, to match
the name actually used for this field (see github.com/golang/go/issues/27665).
We really need to publish the types for this protocol.
Exercised by cmd/go TestScript/vet_asm.
- suppress diagnostics in cfg.VetxOnly mode.
Exercised by cmd/go TestTestVet.
Change-Id: I63259f1bd01531d110362e38190a220389b2ec4b
Reviewed-on: https://go-review.googlesource.com/c/149608
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
This happens whenever we load standard library information from export
data, and prevents the editor from understanding the file names
Change-Id: If5c04176a3e669ba396f322275993616e51ec097
Reviewed-on: https://go-review.googlesource.com/c/149612
Run-TryBot: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
We use the custom marker support to allow us to simplify the
annotations, making it much easier to understand the tests.
Change-Id: Id818a286e4e85f48cfe505f14ec82a80498e494c
Reviewed-on: https://go-review.googlesource.com/c/149611
Run-TryBot: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This exposes the ability to add markers to the public interface, and
changes the way markers are collected to make it so a standard call to
Expect can replicate the internal behaviour.
This allows custom rules to also add marks.
Also add a special EOF identifier that acts like a mark at the end of
the file in which it occurs.
Change-Id: Ic5e41cbc5b7ae3c4d1c5b8baba980147c1d22ef1
Reviewed-on: https://go-review.googlesource.com/c/149610
Run-TryBot: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Delivering each message in a go routine turned out to be problematic, there are some messages
that must be fully processed before later messages are started, and there was no way to guarantee that.
We now push concurrence handling up to the higher level, this has the disadvantage of not being able to guarantee
we respond to call messages correctly, but its a small price to pay.
The LSP currently processes each message fully in order blocking the handler, while we still work on basic
functionality.
Change-Id: If0648c77713ddbe4fed69da97a57696f433b8002
Reviewed-on: https://go-review.googlesource.com/c/149497
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>