Home | History | Annotate | Download | only in articles
      1 <!--{
      2 	"title": "About the go command"
      3 }-->
      4 
      5 <p>The Go distribution includes a command, named
      6 "<code><a href="/cmd/go/">go</a></code>", that
      7 automates the downloading, building, installation, and testing of Go packages
      8 and commands.  This document talks about why we wrote a new command, what it
      9 is, what it's not, and how to use it.</p>
     10 
     11 <h2>Motivation</h2>
     12 
     13 <p>You might have seen early Go talks in which Rob Pike jokes that the idea
     14 for Go arose while waiting for a large Google server to compile.  That
     15 really was the motivation for Go: to build a language that worked well
     16 for building the large software that Google writes and runs. It was
     17 clear from the start that such a language must provide a way to
     18 express dependencies between code libraries clearly, hence the package
     19 grouping and the explicit import blocks.  It was also clear from the
     20 start that you might want arbitrary syntax for describing the code
     21 being imported; this is why import paths are string literals.</p>
     22 
     23 <p>An explicit goal for Go from the beginning was to be able to build Go
     24 code using only the information found in the source itself, not
     25 needing to write a makefile or one of the many modern replacements for
     26 makefiles.  If Go needed a configuration file to explain how to build
     27 your program, then Go would have failed.</p>
     28 
     29 <p>At first, there was no Go compiler, and the initial development
     30 focused on building one and then building libraries for it. For
     31 expedience, we postponed the automation of building Go code by using
     32 make and writing makefiles.  When compiling a single package involved
     33 multiple invocations of the Go compiler, we even used a program to
     34 write the makefiles for us.  You can find it if you dig through the
     35 repository history.</p>
     36 
     37 <p>The purpose of the new go command is our return to this ideal, that Go
     38 programs should compile without configuration or additional effort on
     39 the part of the developer beyond writing the necessary import
     40 statements.</p>
     41 
     42 <h2>Configuration versus convention</h2>
     43 
     44 <p>The way to achieve the simplicity of a configuration-free system is to
     45 establish conventions. The system works only to the extent that those conventions
     46 are followed. When we first launched Go, many people published packages that
     47 had to be installed in certain places, under certain names, using certain build
     48 tools, in order to be used. That's understandable: that's the way it works in
     49 most other languages. Over the last few years we consistently reminded people
     50 about the <code>goinstall</code> command
     51 (now replaced by <a href="/cmd/go/#hdr-Download_and_install_packages_and_dependencies"><code>go get</code></a>)
     52 and its conventions: first, that the import path is derived in a known way from
     53 the URL of the source code; second, that the place to store the sources in
     54 the local file system is derived in a known way from the import path; third,
     55 that each directory in a source tree corresponds to a single package; and
     56 fourth, that the package is built using only information in the source code.
     57 Today, the vast majority of packages follow these conventions.
     58 The Go ecosystem is simpler and more powerful as a result.</p>
     59 
     60 <p>We received many requests to allow a makefile in a package directory to
     61 provide just a little extra configuration beyond what's in the source code.
     62 But that would have introduced new rules. Because we did not accede to such
     63 requests, we were able to write the go command and eliminate our use of make
     64 or any other build system.</p>
     65 
     66 <p>It is important to understand that the go command is not a general
     67 build tool. It cannot be configured and it does not attempt to build
     68 anything but Go packages.  These are important simplifying
     69 assumptions: they simplify not only the implementation but also, more
     70 important, the use of the tool itself.</p>
     71 
     72 <h2>Go's conventions</h2>
     73 
     74 <p>The <code>go</code> command requires that code adheres to a few key,
     75 well-established conventions.</p>
     76 
     77 <p>First, the import path is derived in an known way from the URL of the
     78 source code.  For Bitbucket, GitHub, Google Code, and Launchpad, the
     79 root directory of the repository is identified by the repository's
     80 main URL, without the <code>http://</code> prefix.  Subdirectories are named by
     81 adding to that path.
     82 For example, the Go example programs are obtained by running</p>
     83 
     84 <pre>
     85 git clone https://github.com/golang/example
     86 </pre>
     87 
     88 <p>and thus the import path for the root directory of that repository is
     89 "<code>github.com/golang/example</code>".
     90 The <a href="https://godoc.org/github.com/golang/example/stringutil">stringutil</a>
     91 package is stored in a subdirectory, so its import path is
     92 "<code>github.com/golang/example/stringutil</code>".</p>
     93 
     94 <p>These paths are on the long side, but in exchange we get an
     95 automatically managed name space for import paths and the ability for
     96 a tool like the go command to look at an unfamiliar import path and
     97 deduce where to obtain the source code.</p>
     98 
     99 <p>Second, the place to store sources in the local file system is derived
    100 in a known way from the import path.  Specifically, the first choice
    101 is <code>$GOPATH/src/&lt;import-path&gt;</code>.  If <code>$GOPATH</code> is
    102 unset, the go command will fall back to storing source code alongside the
    103 standard Go packages, in <code>$GOROOT/src/&lt;import-path&gt;</code>.
    104 If <code>$GOPATH</code> is set to a list of paths, the go command tries
    105 <code>&lt;dir&gt;/src/&lt;import-path&gt;</code> for each of the directories in
    106 that list.</p>
    107 
    108 <p>Each of those trees contains, by convention, a top-level directory named
    109 "<code>bin</code>", for holding compiled executables, and a top-level directory
    110 named "<code>pkg</code>", for holding compiled packages that can be imported,
    111 and the "<code>src</code>" directory, for holding package source files.
    112 Imposing this structure lets us keep each of these directory trees
    113 self-contained: the compiled form and the sources are always near each
    114 other.</p>
    115 
    116 <p>These naming conventions also let us work in the reverse direction,
    117 from a directory name to its import path. This mapping is important
    118 for many of the go command's subcommands, as we'll see below.</p>
    119 
    120 <p>Third, each directory in a source tree corresponds to a single
    121 package. By restricting a directory to a single package, we don't have
    122 to create hybrid import paths that specify first the directory and
    123 then the package within that directory.  Also, most file management
    124 tools and UIs work on  directories as fundamental units.  Tying the
    125 fundamental Go unit&mdash;the package&mdash;to file system structure means
    126 that file system tools become Go package tools.  Copying, moving, or
    127 deleting a package corresponds to copying, moving, or deleting a
    128 directory.</p>
    129 
    130 <p>Fourth, each package is built using only the information present in
    131 the source files.  This makes it much more likely that the tool will
    132 be able to adapt to changing build environments and conditions. For
    133 example, if we allowed extra configuration such as compiler flags or
    134 command line recipes, then that configuration would need to be updated
    135 each time the build tools changed; it would also be inherently tied
    136 to the use of a specific tool chain.</p>
    137 
    138 <h2>Getting started with the go command</h2>
    139 
    140 <p>Finally, a quick tour of how to use the go command, to supplement
    141 the information in <a href="/doc/code.html">How to Write Go Code</a>,
    142 which you might want to read first.  Assuming you want
    143 to keep your source code separate from the Go distribution source
    144 tree, the first step is to set <code>$GOPATH</code>, the one piece of global
    145 configuration that the go command needs.  The <code>$GOPATH</code> can be a
    146 list of directories, but by far the most common usage should be to set it to a
    147 single directory.  In particular, you do not need a separate entry in
    148 <code>$GOPATH</code> for each of your projects.  One <code>$GOPATH</code> can
    149 support many projects.</p>
    150 
    151 <p>Heres an example.  Lets say we decide to keep our Go code in the directory
    152 <code>$HOME/mygo</code>.  We need to create that directory and set
    153 <code>$GOPATH</code> accordingly.</p>
    154 
    155 <pre>
    156 $ mkdir $HOME/mygo
    157 $ export GOPATH=$HOME/mygo
    158 $
    159 </pre>
    160 
    161 <p>Into this directory, we now add some source code.  Suppose we want to use
    162 the indexing library from the codesearch project along with a left-leaning
    163 red-black tree.  We can install both with the "<code>go get</code>"
    164 subcommand:</p>
    165 
    166 <pre>
    167 $ go get code.google.com/p/codesearch/index
    168 $ go get github.com/petar/GoLLRB/llrb
    169 $
    170 </pre>
    171 
    172 <p>Both of these projects are now downloaded and installed into our
    173 <code>$GOPATH</code> directory. The one tree now contains the two directories
    174 <code>src/code.google.com/p/codesearch/index/</code> and
    175 <code>src/github.com/petar/GoLLRB/llrb/</code>, along with the compiled
    176 packages (in <code>pkg/</code>) for those libraries and their dependencies.</p>
    177 
    178 <p>Because we used version control systems (Mercurial and Git) to check
    179 out the sources, the source tree also contains the other files in the
    180 corresponding repositories, such as related packages. The "<code>go list</code>"
    181 subcommand lists the import paths corresponding to its arguments, and
    182 the pattern "<code>./...</code>" means start in the current directory
    183 ("<code>./</code>") and find all packages below that directory
    184 ("<code>...</code>"):</p>
    185 
    186 <pre>
    187 $ go list ./...
    188 code.google.com/p/codesearch/cmd/cgrep
    189 code.google.com/p/codesearch/cmd/cindex
    190 code.google.com/p/codesearch/cmd/csearch
    191 code.google.com/p/codesearch/index
    192 code.google.com/p/codesearch/regexp
    193 code.google.com/p/codesearch/sparse
    194 github.com/petar/GoLLRB/example
    195 github.com/petar/GoLLRB/llrb
    196 $
    197 </pre>
    198 
    199 <p>We can also test those packages:</p>
    200 
    201 <pre>
    202 $ go test ./...
    203 ?       code.google.com/p/codesearch/cmd/cgrep   [no test files]
    204 ?       code.google.com/p/codesearch/cmd/cindex  [no test files]
    205 ?       code.google.com/p/codesearch/cmd/csearch [no test files]
    206 ok      code.google.com/p/codesearch/index       0.239s
    207 ok      code.google.com/p/codesearch/regexp      0.021s
    208 ?       code.google.com/p/codesearch/sparse      [no test files]
    209 ?       github.com/petar/GoLLRB/example          [no test files]
    210 ok      github.com/petar/GoLLRB/llrb             0.231s
    211 $
    212 </pre>
    213 
    214 <p>If a go subcommand is invoked with no paths listed, it operates on the
    215 current directory:</p>
    216 
    217 <pre>
    218 $ cd $GOPATH/src/code.google.com/p/codesearch/regexp
    219 $ go list
    220 code.google.com/p/codesearch/regexp
    221 $ go test -v
    222 === RUN TestNstateEnc
    223 --- PASS: TestNstateEnc (0.00 seconds)
    224 === RUN TestMatch
    225 --- PASS: TestMatch (0.01 seconds)
    226 === RUN TestGrep
    227 --- PASS: TestGrep (0.00 seconds)
    228 PASS
    229 ok      code.google.com/p/codesearch/regexp     0.021s
    230 $ go install
    231 $
    232 </pre>
    233 
    234 <p>That "<code>go install</code>" subcommand installs the latest copy of the
    235 package into the pkg directory. Because the go command can analyze the
    236 dependency graph, "<code>go install</code>" also installs any packages that
    237 this package imports but that are out of date, recursively.</p>
    238 
    239 <p>Notice that "<code>go install</code>" was able to determine the name of the
    240 import path for the package in the current directory, because of the convention
    241 for directory naming.  It would be a little more convenient if we could pick
    242 the name of the directory where we kept source code, and we probably wouldn't
    243 pick such a long name, but that ability would require additional configuration
    244 and complexity in the tool. Typing an extra directory name or two is a small
    245 price to pay for the increased simplicity and power.</p>
    246 
    247 <p>As the example shows, its fine to work with packages from many different
    248 projects at once within a single <code>$GOPATH</code> root directory.</p>
    249 
    250 <h2>Limitations</h2>
    251 
    252 <p>As mentioned above, the go command is not a general-purpose build
    253 tool.
    254 In particular, it does not have any facility for generating Go
    255 source files <em>during</em> a build, although it does provide
    256 <a href="/cmd/go/#hdr-Generate_Go_files_by_processing_source"><code>go</code>
    257 <code>generate</code></a>,
    258 which can automate the creation of Go files <em>before</em>
    259 the build, such as by running <code>yacc</code>.
    260 For more advanced build setups, you may need to write a
    261 makefile (or a configuration file for the build tool of your choice)
    262 to run whatever tool creates the Go files and then check those generated source files
    263 into your repository. This is more work for you, the package author,
    264 but it is significantly less work for your users, who can use
    265 "<code>go get</code>" without needing to obtain and build
    266 any additional tools.</p>
    267 
    268 <h2>More information</h2>
    269 
    270 <p>For more information, read <a href="/doc/code.html">How to Write Go Code</a>
    271 and see the <a href="/cmd/go/">go command documentation</a>.</p>
    272