Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 1 | # Introduction |
| 2 | |
| 3 | A common use case is to create a reusable library and an application that consumes it, and host both on Github. We will illustrate this with a trivial application called "` uselessd `" that consumes a likewise trivial library called "` useless `". |
| 4 | |
| 5 | |
| 6 | # Code Layout |
| 7 | |
| 8 | The app and both libraries live on Github, each in its own repository. ` $GOPATH ` is the root of the _project_ - each of your Github repos will be checked out several folders below ` $GOPATH `. |
| 9 | |
| 10 | Your code layout would look like this: |
| 11 | |
| 12 | ``` |
| 13 | $GOPATH/ |
| 14 | src/ |
| 15 | github.com/ |
| 16 | jmcvetta/ |
| 17 | useless/ |
| 18 | .git/ |
| 19 | useless.go |
| 20 | useless_test.go |
| 21 | README.md |
| 22 | uselessd/ |
| 23 | .git/ |
| 24 | uselessd.go |
| 25 | uselessd_test.go |
| 26 | README.md |
| 27 | ``` |
| 28 | |
| 29 | Each folder under ` src/github.com/jmcvetta/ ` is the root of a separate git checkout. |
| 30 | |
| 31 | |
| 32 | # $GOPATH |
| 33 | |
| 34 | Your ` $GOPATH ` variable will point to the root of your Go workspace, as described in [How to Write Go Code](http://golang.org/doc/code.html). |
| 35 | |
| 36 | |
| 37 | # Note for Eclipse Users |
| 38 | |
| 39 | Both Go and Eclipse use the term "workspace", but they use it to mean something different. What Go calls a "workspace" is what Eclipse calls a "project". Whenever this document uses either term, it refers to a Go workspace. |
| 40 | |
| 41 | |
| 42 | # Setup the Workspace |
| 43 | |
| 44 | Let's assume we are starting from scratch. Initialize the two new repositories on Github, using the "Initialize this repository with a README" option so your repos can be cloned immediately. Then setup the project like this: |
| 45 | |
| 46 | ```sh |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 47 | cd ~/workspace # Standard location for Eclipse workspace |
| 48 | mkdir mygo # Create your Go workspace |
| 49 | export GOPATH=~/workspace/mygo # GOPATH = Go workspace |
| 50 | cd $GOPATH |
| 51 | mkdir -p src/github.com/jmcvetta |
| 52 | cd src/github.com/jmcvetta |
| 53 | git clone git@github.com:jmcvetta/useless.git |
| 54 | git clone git@github.com:jmcvetta/uselessd.git |
| 55 | ``` |
| 56 | |
| 57 | # Libraries |
| 58 | |
| 59 | Conventionally, the name of the repository is the same as the name of the package it contains. Our ` useless ` repo contains ` useless.go ` which defines ` package useless `: |
| 60 | |
| 61 | ```Go |
| 62 | package useless |
| 63 | |
| 64 | func Foobar() string { |
Dave Day | 0d6986a | 2014-12-10 15:02:18 +1100 | [diff] [blame] | 65 | return "Foobar!" |
| 66 | } |
| 67 | ``` |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 68 | |
| 69 | |
| 70 | # Applications |
| 71 | |
| 72 | An application - Go code that will be compiled into an executable command - always defines ` package main ` with a ` main() ` function. |
| 73 | |
| 74 | So ` uselessd.go ` looks like this: |
| 75 | |
| 76 | ```Go |
| 77 | package main |
| 78 | |
| 79 | import ( |
Dave Day | 0d6986a | 2014-12-10 15:02:18 +1100 | [diff] [blame] | 80 | "net/http" |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 81 | |
nathany | 5f8aa64 | 2014-12-10 22:14:43 -0800 | [diff] [blame] | 82 | "golang.org/x/net/websocket" |
Dave Day | 0d6986a | 2014-12-10 15:02:18 +1100 | [diff] [blame] | 83 | "github.com/jmcvetta/useless" |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 84 | ) |
| 85 | |
| 86 | func main() { |
Dave Day | 0d6986a | 2014-12-10 15:02:18 +1100 | [diff] [blame] | 87 | http.Handle("/useless", websocket.Handler(func(ws *websocket.Conn) { |
| 88 | ws.Write([]byte(useless.Foobar())) |
| 89 | })) |
| 90 | http.ListenAndServe(":3000", nil) |
| 91 | } |
| 92 | ``` |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 93 | |
| 94 | |
| 95 | # Dependencies |
| 96 | |
nathany | 5f8aa64 | 2014-12-10 22:14:43 -0800 | [diff] [blame] | 97 | Your project will probably depend on some existing packages. The application above depends upon ` golang.org/x/net/websocket `. You can install all dependencies by running "` go get -v ./... `" from the root of your workspace. The "` go get `" command is similar to "` go install `" in that it will attempt to build and install all packages in the workspace (technically, all packages matched by "` ./... `"), except that it will also examine their dependencies and download (and install) any that are missing first. |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 98 | |
| 99 | See the output of "` go help packages `" for a full explanation of the "` ... `" syntax. |
| 100 | |
| 101 | All dependencies will be installed alongside your code under "` $GOPATH/src `". All Github reposities checked out by "` go get `" will be use the read-only ` https:// ` repository by default. To push changes back to github from one of these repositories, change the "` origin/master `" ref in ` .git/config ` to match the SSH repository from Github. |
| 102 | |
| 103 | # Build |
| 104 | |
| 105 | During development you can build the ` useless ` library by itself with the command "` go build ...useless `". You could also give the full path to the package name, "` go build github.com/jmcvetta/useless `". |
| 106 | |
| 107 | To compile ` uselessd.go ` and its dependencies into an executable, use the command "` go build ...uselessd `". |
| 108 | |
| 109 | # Example Code |
| 110 | |
| 111 | FWIW all the repo addresses on this page are real, and the ` uselessd ` application should compile if you follow the directions above. |