github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/doc/articles/go_command.html (about)

     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>Here’s an example.  Let’s 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, it’s 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>