mirror of
https://github.com/golang/go
synced 2024-11-12 10:30:23 -07:00
644 lines
19 KiB
HTML
644 lines
19 KiB
HTML
<!-- Contributing to the Go project -->
|
|
|
|
<h2 id="Introduction">Introduction</h2>
|
|
|
|
<p>
|
|
This document explains how to write a new package,
|
|
how to test code, and how to contribute changes to the Go project.
|
|
It assumes you have installed Go using the
|
|
<a href="install.html">installation instructions</a>. (Note that
|
|
the <code>gccgo</code> frontend lives elsewhere;
|
|
see <a href="gccgo_contribute.html">Contributing to gccgo</a>.)
|
|
</p>
|
|
|
|
<p>
|
|
Before embarking on a significant change to an existing
|
|
package or the creation of a major new package,
|
|
it's a good idea to send mail to the <a href="FIXME">mailing list</a>
|
|
to let people know what you are thinking of doing.
|
|
Doing so helps avoid duplication of effort and
|
|
enables discussions about design before much code
|
|
has been written.
|
|
</p>
|
|
|
|
<h2 id="Community_resources">Community resources</h2>
|
|
|
|
<p>
|
|
For real-time help, there may be users or developers on
|
|
<code>#go-nuts</code> on the <a href="http://freenode.net/">Freenode</a> IRC server.
|
|
</p>
|
|
|
|
<p>
|
|
The official mailing list for discussion of the Go language is
|
|
<a href="http://groups.google.com/group/golang-nuts">Go Nuts</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Bugs can be reported using the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>.
|
|
</p>
|
|
|
|
<p>
|
|
For those who wish to keep up with development,
|
|
there is another mailing list, <a href="http://groups.google.com/group/golang-checkins">golang-checkins</a>,
|
|
that receives a message summarizing each checkin to the Go repository.
|
|
</p>
|
|
|
|
|
|
<h2 id="New_package">Creating a new package</h2>
|
|
|
|
<p>
|
|
The source code for the package with import path
|
|
<code>x/y</code> is, by convention, kept in the
|
|
directory <code>$GOROOT/src/pkg/x/y</code>.
|
|
</p>
|
|
|
|
<h3>Makefile</h3>
|
|
|
|
<p>
|
|
It would be nice to have Go-specific tools that
|
|
inspect the source files to determine what to build and in
|
|
what order, but for now, Go uses GNU <code>make</code>.
|
|
Thus, the first file to create in a new package directory is
|
|
usually the <code>Makefile</code>.
|
|
The basic form is illustrated by <a href="../src/pkg/container/vector/Makefile"><code>src/pkg/container/vector/Makefile</code></a>:
|
|
</p>
|
|
|
|
<pre>
|
|
include $(GOROOT)/src/Make.$(GOARCH)
|
|
|
|
TARG=container/vector
|
|
GOFILES=\
|
|
intvector.go\
|
|
stringvector.go\
|
|
vector.go\
|
|
|
|
include $(GOROOT)/src/Make.pkg
|
|
</pre>
|
|
|
|
<p>
|
|
The first and last lines <code>include</code> standard definitions and rules,
|
|
so that the body of the <code>Makefile</code> need only specify two variables.
|
|
</p>
|
|
|
|
<p>
|
|
<code>TARG</code> is the target install path for the package,
|
|
the string that clients will use to import it.
|
|
This string should be the same as the directory
|
|
in which the <code>Makefile</code> appears, with the
|
|
<code>$GOROOT/src/pkg/</code> removed.
|
|
</p>
|
|
|
|
<p>
|
|
<code>GOFILES</code> is a list of source files to compile to
|
|
create the package. The trailing <code>\</code> characters
|
|
allow the list to be split onto multiple lines
|
|
for easy sorting.
|
|
</p>
|
|
|
|
<p>
|
|
After creating a new package directory, add it to the list in
|
|
<code>$GOROOT/src/pkg/Makefile</code> so that it
|
|
is included in the standard build. Then run:
|
|
<pre>
|
|
cd $GOROOT/src/pkg
|
|
./deps.bash
|
|
</pre>
|
|
<p>
|
|
to update the dependency file <code>Make.deps</code>.
|
|
</p>
|
|
|
|
<p>
|
|
If you change the imports of an existing package,
|
|
you do not need to edit <code>$GOROOT/src/pkg/Makefile</code>
|
|
but you will still need to run <code>deps.bash</code> as above.
|
|
</p>
|
|
|
|
|
|
<h3>Go source files</h3>
|
|
|
|
<p>
|
|
The first statement in each of the source files listed in the <code>Makefile</code>
|
|
should be <code>package <i>name</i></code>, where <code><i>name</i></code>
|
|
is the package's default name for imports.
|
|
(All files in a package must use the same <code><i>name</i></code>.)
|
|
Go's convention is that the package name is the last element of the
|
|
import path: the package imported as <code>"crypto/rot13"</code>
|
|
should be named <code>rot13</code>.
|
|
The Go tools impose a restriction that package names are unique
|
|
across all packages linked into a single binary, but that restriction
|
|
will be lifted soon.
|
|
</p>
|
|
|
|
<p>
|
|
Go compiles all the source files in a package at once, so one file
|
|
can refer to constants, variables, types, and functions in another
|
|
file without special arrangement or declarations.
|
|
</p>
|
|
|
|
<p>
|
|
Writing clean, idiomatic Go code is beyond the scope of this document.
|
|
<a href="effective_go.html">Effective Go</a> is an introduction to
|
|
that topic.
|
|
</p>
|
|
|
|
<h2 id="Testing">Testing</h2>
|
|
|
|
<p>
|
|
Go has a lightweight test framework known as <code>gotest</code>.
|
|
You write a test by creating a file with a name ending in <code>_test.go</code>
|
|
that contains functions named <code>TestXXX</code> with signature <code>func (t *testing.T)</code>.
|
|
The test framework runs each such function;
|
|
if the function calls a failure function such as <code>t.Error</code> or <code>t.Fail</code>, the test is considered to have failed.
|
|
The <a href="/cmd/gotest/">gotest command documentation</a>
|
|
and the <a href="/pkg/testing/">testing package documentation</a> give more detail.
|
|
</p>
|
|
|
|
<p>
|
|
The <code>*_test.go</code> files should not be listed in the <code>Makefile</code>.
|
|
</p>
|
|
|
|
<p>
|
|
To run the test, run either <code>make test</code> or <code>gotest</code>
|
|
(they are equivalent).
|
|
To run only the tests in a single test file, for instance <code>one_test.go</code>,
|
|
run <code>gotest one_test.go</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Before sending code out for review, make sure everything
|
|
still works and the dependencies are right:
|
|
</p>
|
|
|
|
<pre>
|
|
cd $GOROOT/src
|
|
./all.bash
|
|
</pre>
|
|
|
|
<p>
|
|
The final line printed by <code>all.bash</code> should be of the form:
|
|
</p>
|
|
|
|
<pre>
|
|
<i>N</i> known bugs; 0 unexpected bugs
|
|
</pre>
|
|
|
|
<p>
|
|
The value of <i>N</i> varies over time, but the line must
|
|
say “<code>0 unexpected bugs</code>” and must not
|
|
add “<code>test output differs</code>.”
|
|
</p>
|
|
|
|
<p>
|
|
Once your new code is tested and working,
|
|
it's time to get it reviewed and submitted.
|
|
</p>
|
|
|
|
<h2 id="Code_review">Code review</h2>
|
|
|
|
<p>
|
|
Changes to Go must be reviewed before they are submitted,
|
|
no matter who makes the change.
|
|
(In exceptional cases, such as fixing a build, the review can
|
|
follow shortly after submitting.)
|
|
A Mercurial extension helps manage the code review process.
|
|
The extension is included in the Go source tree but needs
|
|
to be added to your Mercurial configuration.
|
|
</p>
|
|
|
|
<h3>Caveat for Mercurial aficionados</h3>
|
|
|
|
<p>
|
|
<i>Using Mercurial with the code review extension is not the same
|
|
as using standard Mercurial.</i>
|
|
</p>
|
|
|
|
<p>
|
|
The Go repository is maintained as a single line of reviewed changes;
|
|
we prefer to avoid the complexity of Mercurial's arbitrary change graph.
|
|
The code review extension helps here: its <code>hg submit</code> command
|
|
automatically checks for and warns about the local repository
|
|
being out of date compared to the remote one.
|
|
The <code>hg submit</code> command also verifies other
|
|
properties about the Go repository.
|
|
For example,
|
|
it checks that Go code being checked in is formatted in the standard style,
|
|
as defined by <a href="/cmd/gofmt">gofmt</a>,
|
|
and it checks that the author of the code is properly recorded for
|
|
<a href="#copyright">copyright purposes</a>.
|
|
</p>
|
|
|
|
<p>
|
|
To help ensure changes are only created by <code>hg submit</code>,
|
|
the code review extension disables the standard <code>hg commit</code>
|
|
command.
|
|
</p>
|
|
|
|
<p>
|
|
Mercurial power users: To allow Go contributors to take advantage of
|
|
Mercurial's functionality for local revision control, it might be interesting
|
|
to explore how the code review extension can be made to work alongside
|
|
the Mercurial Queues extension.
|
|
</p>
|
|
|
|
<h3>Configure the extension</h3>
|
|
|
|
[NOTE FOR BEFORE LAUNCH: <a href="http://www/~rsc/internal-hg.html">Read this instead</a>.]
|
|
|
|
<p>Edit <code>$GOROOT/.hg/hgrc</code> to add:</p>
|
|
|
|
<pre>
|
|
[extensions]
|
|
codereview = YOUR_GO_ROOT/lib/codereview/codereview.py
|
|
</pre>
|
|
|
|
<p>Replace YOUR_GO_ROOT with the value of <code>$GOROOT</code>.
|
|
The Mercurial configuration file format does not allow environment variable substitution.
|
|
</p>
|
|
|
|
<h3>Log in to the code review site.</h3>
|
|
|
|
[NOTE FOR BEFORE LAUNCH: <a href="http://www/~rsc/internal-hg.html">Read this instead</a>.]
|
|
|
|
<p>
|
|
The code review server uses a Google Account to authenticate.
|
|
(If you can use the account to
|
|
<a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.com/">sign in at google.com</a>,
|
|
you can use it to sign in to the code review server.)
|
|
</p>
|
|
|
|
<pre>
|
|
$ cd $GOROOT
|
|
$ hg code-login
|
|
Email (login for uploading to codereview.appspot.com): rsc@golang.org
|
|
Password for rsc@golang.org:
|
|
|
|
Saving authentication cookies to /Users/rsc/.codereview_upload_cookies_codereview.appspot.com
|
|
</pre>
|
|
|
|
<h3>Configure your account settings.</h3>
|
|
|
|
<p>Edit your <a href="http://codereview.prom.corp.google.com/settings">code review settings</a>.
|
|
Grab a nickname.
|
|
Many people prefer to set the Context option to
|
|
“Whole file” to see more context when reviewing changes.
|
|
</p>
|
|
|
|
<p>Once you have chosen a nickname in the settings page, others
|
|
can use that nickname as a shorthand for naming reviewers and the CC list.
|
|
For example, <code>rsc</code> is an alias for <code>rsc@golang.org</code>.
|
|
</p>
|
|
|
|
<h3>Make a change</h3>
|
|
|
|
<p>
|
|
The entire checked-out tree is writable.
|
|
If you need to edit files, just edit them: Mercurial will figure out which ones changed.
|
|
You do need to inform Mercurial of added, removed, copied, or renamed files,
|
|
by running
|
|
<code>hg add</code>,
|
|
<code>hg rm</code>,
|
|
<code>hg cp</code>,
|
|
or
|
|
<code>hg mv</code>.
|
|
</p>
|
|
|
|
<p>When you are ready to send a change out for review, run</p>
|
|
|
|
<pre>
|
|
$ hg change
|
|
</pre>
|
|
|
|
<p>from any directory in your Go repository.
|
|
Mercurial will open a change description file in your editor.
|
|
(It uses the editor named by the <code>$EDITOR</code> environment variable, <code>vi</code> by default.)
|
|
The file will look like:
|
|
</p>
|
|
|
|
<pre>
|
|
# Change list.
|
|
# Lines beginning with # are ignored.
|
|
# Multi-line values should be indented.
|
|
|
|
Reviewer:
|
|
CC:
|
|
|
|
Description:
|
|
<enter description here>
|
|
|
|
Files:
|
|
src/pkg/math/sin.go
|
|
src/pkg/math/tan.go
|
|
src/pkg/regexp/regexp.go
|
|
</pre>
|
|
|
|
<p>
|
|
The <code>Reviewer</code> line lists the reviewers assigned
|
|
to this change, and the <code>CC</code> line lists people to
|
|
notify about the change.
|
|
These can be code review nicknames or arbitrary email addresses.
|
|
</p>
|
|
|
|
<p>
|
|
Replace “<code><enter description here></code>”
|
|
with a description of your change.
|
|
The first line of the change description is conventionally
|
|
a one-line summary of the change and is used as the
|
|
subject for code review mail; the rest of the
|
|
description elaborates.
|
|
</p>
|
|
|
|
<p>
|
|
The <code>Files</code> section lists all the modified files
|
|
in your client.
|
|
It is best to keep unrelated changes in different change lists.
|
|
In this example, we can include just the changes to package <code>math</code>
|
|
by deleting the line mentioning <code>regexp.go</code>.
|
|
</p>
|
|
|
|
<p>
|
|
After editing, the template might now read:
|
|
</p>
|
|
|
|
<pre>
|
|
# Change list.
|
|
# Lines beginning with # are ignored.
|
|
# Multi-line values should be indented.
|
|
|
|
Reviewer: r, rsc
|
|
CC: math-nuts@swtch.com
|
|
|
|
Description:
|
|
Sin, Cos, Tan: improved precision for very large arguments
|
|
|
|
See Bimmler and Shaney, ``Extreme sinusoids,'' J. Math 3(14).
|
|
Fixes issue 159.
|
|
|
|
Files:
|
|
src/pkg/math/sin.go
|
|
src/pkg/math/tan.go
|
|
</pre>
|
|
|
|
<p>
|
|
The special sentence “Fixes issue 159.” associates
|
|
the change with issue 159 in the <a href="http://code.google.com/p/go/issues/list">Go issue tracker</a>.
|
|
When this change is eventually submitted, the issue
|
|
tracker will automatically mark the issue as fixed.
|
|
</p>
|
|
|
|
<p>
|
|
Save the file and exit the editor.</p>
|
|
|
|
<p>
|
|
The code review server assigns your change an issue number and URL,
|
|
which <code>hg change</code> will print, something like:
|
|
</p>
|
|
|
|
<pre>
|
|
CL created: http://codereview.appspot.com/99999
|
|
</pre>
|
|
|
|
<p>
|
|
If you need to re-edit the change description,
|
|
run <code>hg change 99999</code>.
|
|
</p>
|
|
|
|
<p>
|
|
You can see a list of your pending changes by running <code>hg pending</code> (<code>hg p</code> for short).
|
|
</p>
|
|
|
|
|
|
<h3>Synchronize your client</h3>
|
|
|
|
<p>While you were working, others might have submitted changes
|
|
to the repository. To update your client, run</p>
|
|
|
|
<pre>
|
|
$ hg sync
|
|
</pre>
|
|
|
|
<p>(For Mercurial fans, <code>hg sync</code> runs <code>hg pull -u</code>
|
|
but then also synchronizes the local change list state against the new data.)</p>
|
|
|
|
<p>
|
|
If files you were editing have changed, Mercurial does its best to merge the
|
|
remote changes into your local changes. It may leave some files to merge by hand.
|
|
</p>
|
|
|
|
<p>
|
|
For example, suppose you have edited <code>flag_test.go</code> but
|
|
someone else has committed an independent change.
|
|
When you run <code>hg sync</code>, you will get the (scary-looking) output
|
|
(emphasis added):
|
|
|
|
<pre>
|
|
$ hg sync
|
|
adding changesets
|
|
adding manifests
|
|
adding file changes
|
|
added 1 changeset with 2 changes to 2 files
|
|
getting src/pkg/flag/flag.go
|
|
couldn't find merge tool hgmerge
|
|
merging src/pkg/flag/flag_test.go
|
|
warning: conflicts during merge.
|
|
<i>merging src/pkg/flag/flag_test.go failed!</i>
|
|
1 file updated, 0 files merged, 0 files removed, 1 file unresolved
|
|
use 'hg resolve' to retry unresolved file merges
|
|
$
|
|
</pre>
|
|
|
|
<p>
|
|
The only important part in that transcript is the italicized line:
|
|
Mercurial failed to merge your changes with the independent change.
|
|
When this happens, Mercurial leaves both edits in the file,
|
|
marked by <code><<<<<<<</code> and
|
|
<code>>>>>>>></code>.
|
|
it is now your job to edit the file to combine them.
|
|
Continuing the example, searching for those strings in <code>flag_test.go</code>
|
|
might turn up:
|
|
</p>
|
|
|
|
<pre>
|
|
VisitAll(visitor);
|
|
<<<<<<< local
|
|
if len(m) != 7 {
|
|
=======
|
|
if len(m) != 8 {
|
|
>>>>>>> other
|
|
t.Error("VisitAll misses some flags");
|
|
</pre>
|
|
|
|
<p>
|
|
Mercurial doesn't show it, but suppose the original text that both edits
|
|
started with was 6; you added 1 and the other change added 2,
|
|
so the correct answer might now be 9. If you edit the section
|
|
to remove the markers and leave the correct code:
|
|
</p>
|
|
|
|
<pre>
|
|
VisitAll(visitor);
|
|
if len(m) != 9 {
|
|
t.Error("VisitAll misses some flags");
|
|
</pre>
|
|
|
|
<p>
|
|
then that is enough. There is no need to inform Mercurial
|
|
that you have corrected the file.
|
|
</p>
|
|
|
|
<p>
|
|
If you had been editing the file, say for debugging, but do not
|
|
care to preserve your changes, you can run
|
|
<code>hg revert flag_test.go</code> to abandon your
|
|
changes.
|
|
</p>
|
|
|
|
<h3>Mail the change for review</h3>
|
|
|
|
<p>To send out a change for review, run <code>hg mail</code> using the change list number
|
|
assigned during <code>hg change</code>:</p>
|
|
|
|
<pre>
|
|
$ hg mail 99999
|
|
</pre>
|
|
|
|
<p>You can add to the <code>Reviewer:</code> and <code>CC:</code> lines
|
|
using the <code>-r</code> or <code>--cc</code> options.
|
|
In the above example, we could have left the <code>Reviewer</code> and <code>CC</code>
|
|
lines blank and then run:
|
|
</p>
|
|
|
|
<pre>
|
|
$ hg mail -r r,rsc --cc math-nuts@swtch.com 99999
|
|
</pre>
|
|
|
|
<p>to achieve the same effect.</p>
|
|
|
|
<p>Note that <code>-r</code> and <code>--cc</code> cannot be spelled <code>--r</code> or <code>-cc</code>.</p>
|
|
|
|
|
|
<h3>Reviewing code</h3>
|
|
|
|
<p>
|
|
Running <code>hg mail</code> will send an email to you and the reviewers
|
|
asking them to visit the issue's URL and make coments on the change.
|
|
When done, the reviewer clicks “Publish and Mail comments”
|
|
to send comments back.
|
|
</p>
|
|
|
|
|
|
<h3>Revise and upload</h3>
|
|
|
|
<p>You will probably revise your code in response to the reviewer comments.
|
|
When you have revised the code and are ready for another round of review, run
|
|
</p>
|
|
|
|
<pre>
|
|
$ hg upload 99999
|
|
</pre>
|
|
|
|
<p>to upload the latest copy.
|
|
You might also visit the code review web page and reply to the comments,
|
|
letting the reviewer know that you've addressed them or explain why you
|
|
haven't. When you're done replying, click “Publish and Mail comments”
|
|
to send the line-by-line replies and any other comments.
|
|
A common acronym in such mails is <code>PTAL</code>: please take another look.
|
|
</p>
|
|
<p>
|
|
The reviewer can comment on the new copy, and the process repeats.
|
|
The reviewer approves the change by replying with a mail that says
|
|
<code>LGTM</code>: looks good to me.
|
|
</p>
|
|
|
|
<h3>Submit the change</h3>
|
|
|
|
<p>
|
|
Once the code has been <code>LGTM</code>'ed, it is time to submit
|
|
it to the Mercurial repository.
|
|
If you are a committer, you can run:
|
|
</p>
|
|
|
|
<pre>
|
|
$ hg submit 99999
|
|
</pre>
|
|
|
|
<p>
|
|
This checks the change into the repository.
|
|
The change description will include a link to the code review,
|
|
and the code review will be updated with a link to the change
|
|
in the repository.
|
|
</p>
|
|
|
|
<p>
|
|
If your local copy of the repository is out of date,
|
|
<code>hg submit</code>
|
|
will refuse the change:
|
|
</p>
|
|
|
|
<pre>
|
|
$ hg submit 12345678
|
|
local repository out of date; must sync before submit
|
|
</pre>
|
|
|
|
<p>
|
|
If you are not a committer, you cannot submit the change directly.
|
|
Instead, a committer, usually the reviewer who said <code>LGTM</code>,
|
|
will run:
|
|
</p>
|
|
|
|
<pre>
|
|
$ hg clpatch 99999
|
|
$ hg submit 99999
|
|
</pre>
|
|
|
|
<p>The <code>clpatch</code> command imports your change 99999 into
|
|
the committer's local Mercurial client, at which point the committer
|
|
can check or test the code more.
|
|
(Anyone can run <code>clpatch</code> to try a change that
|
|
has been uploaded to the code review server.)
|
|
The <code>submit</code> command submits the code. You will be listed as the
|
|
author, but the change message will also indicate who the committer was.
|
|
Your local client will notice that the change has been submitted
|
|
when you next run <code>hg sync</code>.
|
|
</p>
|
|
|
|
|
|
<h3 id="copyright">Copyright</h3>
|
|
|
|
<p>The standard copyright header for files in the Go tree is:</p>
|
|
|
|
<pre>
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
</pre>
|
|
|
|
<p>
|
|
Code you contribute should have this header.
|
|
You need to be listed in the
|
|
<a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file,
|
|
which defines who the Go contributors—the people—are;
|
|
and the copyright holder for the code you submit (either you or the
|
|
organization you work for) needs to be listed in the
|
|
<a href="/AUTHORS"><code>AUTHORS</code></a> file, which defines
|
|
who “The Go Authors”—the copyright holders—are.
|
|
</p>
|
|
|
|
<p>
|
|
When sending your first change list, you should prepare
|
|
and send a separate change list adding yourself to
|
|
<code>CONTRIBUTORS</code> and adding
|
|
the copyright holder for your code to <code>AUTHORS</code> if not already listed.
|
|
If you are the copyright holder, you will need to agree to
|
|
the <a href="http://code.google.com/legal/individual-cla-v1.0.html">individual contributor license agreement</a>,
|
|
which can be completed online;
|
|
if your organization is the copyright holder, the organization
|
|
will need to agree to the <a href="http://code.google.com/legal/corporate-cla-v1.0.html">corporate contributor license agreement</a>.
|
|
If the copyright holder for your code has already completed the
|
|
agreement in connection with another Google open source project,
|
|
it does not need to be completed again.
|
|
One of the Go developers at Google will approve and submit
|
|
this change after checking the list of people/organizations
|
|
that have completed the agreement.
|
|
</p>
|
|
|