go.talks: Organizing Go Code

LGTM=campoy
R=cmang, sameer, r, campoy
CC=golang-codereviews
https://golang.org/cl/108140044
diff --git a/2014/organizeio.slide b/2014/organizeio.slide
new file mode 100644
index 0000000..0cff214
--- /dev/null
+++ b/2014/organizeio.slide
@@ -0,0 +1,333 @@
+Organizing Go code
+
+David Crawshaw
+crawshaw@golang.org
+
+
+* Packages
+
+* Go programs are made up of packages
+
+All Go source is part of a package.
+Every file begins with a package statement.
+Programs start in package main.
+
+.play organizeio/hello.go
+
+For very small programs, `main` is the only package you need to write.
+
+The hello world program _imports_ package `fmt`.
+
+The function `Println` is defined in the fmt package.
+
+* An example package: fmt
+
+	// Package fmt implements formatted I/O.
+	package fmt
+
+	// Println formats using the default formats for its
+	// operands and writes to standard output.
+	func Println(a ...interface{}) (n int, err error) {
+		...
+	}
+
+	func newPrinter() *pp {
+		...
+	}
+
+The `Println` function is _exported_. It starts with an upper case
+letter, which means other packages are allowed to call it.
+
+The `newPrinter` function is _unexported_. It starts with a lower
+case letter, so it can only be used inside the fmt package.
+
+* The shape of a package
+
+Packages collect related code.
+
+They can be big or small,
+and may be spread across multiple files.
+
+All the files in a package live in a single directory.
+
+The `net/http` package exports more than 100 names. (18 files)
+The `errors` package exports just one. (1 file)
+
+* The name of a package
+
+Keep package names short and meaningful.
+Don't use underscores, they make package names long.
+
+- `io/ioutil` not `io/util`
+- `suffixarray` not `suffix_array`
+
+Don't overgeneralize. A `util` package could be anything.
+
+The name of a package is part of its type and function names.
+On its own, type `Buffer` is ambiguous. But users see:
+
+	buf := new(bytes.Buffer)
+
+Choose package names carefully.
+
+Choose good names for users.
+
+* The testing of a package
+
+Tests are distinguished by file name. Test files end in `_test.go`.
+
+	package fmt
+
+	import "testing"
+
+	var fmtTests = []fmtTest{
+		{"%d", 12345, "12345"},
+		{"%v", 12345, "12345"},
+		{"%t", true, "true"},
+	}
+
+	func TestSprintf(t *testing.T) {
+		for _, tt := range fmtTests {
+			if s := Sprintf(tt.fmt, tt.val); s != tt.out {
+				t.Errorf("...")
+			}
+		}
+	}
+
+Test well.
+
+* Code organization
+
+* Introducing workspaces
+
+Your Go code is kept in a _workspace_.
+
+A workspace contains _many_ source repositories (git, hg).
+
+The Go tool understands the layout of a workspace.
+You don't need a `Makefile`. The file layout is everything.
+
+Change the file layout, change the build.
+
+	$GOPATH/
+		src/
+			github.com/user/repo/
+				mypkg/
+					mysrc1.go
+					mysrc2.go
+				cmd/mycmd/
+					main.go
+		bin/
+			mycmd
+
+
+* Let's make a workspace
+
+	mkdir /tmp/gows
+	GOPATH=/tmp/gows
+
+The `GOPATH` environment variable tells the Go tool where your workspace is located.
+
+	go get github.com/dsymonds/fixhub/cmd/fixhub
+
+The `go` `get` command fetches source repositories from the internet and places them in your workspace.
+
+Package paths matter to the Go tool. Using "github.com/..."
+means the tool knows how to fetch your repository.
+
+	go install github.com/dsymonds/fixhub/cmd/fixhub
+
+The go install command builds a binary and places it in `$GOPATH/bin/fixhub`.
+
+* Our workspace
+
+	$GOPATH/
+		bin/fixhub                              # installed binary
+		pkg/darwin_amd64/                       # compiled archives
+			code.google.com/p/goauth2/oauth.a
+			github.com/...
+		src/                                    # source repositories
+			code.google.com/p/goauth2/
+				.hg
+				oauth                           # used by package go-github
+				...
+			github.com/
+				golang/lint/...                 # used by package fixhub
+					.git
+				google/go-github/...            # used by package fixhub
+					.git
+				dsymonds/fixhub/
+					.git
+					client.go
+					cmd/fixhub/fixhub.go        # package main
+
+`go` `get` fetched many repositories.
+`go` `install` built a binary out of them.
+
+
+* Why prescribe file layout?
+
+Using file layout for builds means less configuration.
+In fact, it means no configuration.
+No `Makefile`, no `build.xml`.
+
+Less time configuring means more time programming.
+
+Everyone in the community uses the same layout.
+This makes it easier to share code.
+
+The Go tool helps build the Go community.
+
+* Where's your workspace?
+
+It is possible to have multiple workspaces, but most people just use one.
+
+So where do you point your `GOPATH`? A common preference:
+
+.image organizeio/home.png
+
+This puts `src`, `bin`, and `pkg` directories in your home directory.
+
+(Convenient, because `$HOME/bin` is probably already in your `PATH`.)
+
+
+* Working with workspaces
+
+Unix eschews typing:
+
+	CDPATH=$GOPATH/src/github.com:$GOPATH/src/code.google.com/p
+
+	$ cd dsymonds/fixhub
+	/tmp/gows/src/github.com/dsymonds/fixhub
+	$ cd goauth2
+	/tmp/gows/src/code.google.com/p/goauth2
+	$
+
+A shell function for your `~/.profile`:
+
+	gocd () { cd `go list -f '{{.Dir}}' $1` }
+
+This lets you move around using the Go tool's path names:
+
+	$ gocd .../lint
+	/tmp/gows/src/github.com/golang/lint
+	$
+
+
+* The Go tool's many talents
+
+	$ go help
+	Go is a tool for managing Go source code.
+
+	Usage:
+
+		go command [arguments]
+
+	The commands are:
+
+Worth exploring! Some highlights:
+
+	    build       compile packages and dependencies
+	    get         download and install packages and dependencies
+	    install     compile and install packages and dependencies
+	    test        test packages
+
+There are more useful subcommands. Check out `vet` and `fmt`.
+
+* Dependency management
+
+* In production, versions matter.
+
+`go` `get` always fetches the latest code, even if your build breaks.
+
+.image organizeio/gogetversion.png
+
+That's fine when developing. It's not fine when releasing.
+We need other tools.
+
+* Versioning
+
+My favorite technique: vendoring.
+
+For building binaries, import the packages you care about
+into a `_vendor` workspace.
+
+	GOPATH=/tmp/gows/_vendor:/tmp/gows
+
+For building libraries, import the packages you care about
+into your repository. Rename the imports to:
+
+	import "github.com/you/proj/vendor/github.com/them/lib"
+
+Long paths, but trivial to automate. Write a Go program!
+
+Another technique: [[http://gopkg.in][gopkg.in]], provides versioned package paths:
+
+	gopkg.in/user/pkg.v3 -> github.com/user/pkg (branch/tag v3, v3.N, or v.3.N.M)
+
+* Naming
+
+* Names matter
+
+Programs are full of names. Names have costs and benefits.
+
+*Costs*: *space* *and* *time*
+Names need to be in short term memory when reading code.
+You can only fit so many. Longer names take up more space.
+
+*Benefits:* *information*
+A good name is not only a referent, it conveys information.
+
+Use the shortest name that carries the right amount of information in its context.
+
+Devote time to naming.
+
+* Name style
+
+Use `camelCase`, `not_underscores`.
+Local variable names should be short, typically one or two characters.
+
+Package names are usually one lowercase word.
+
+Global variables should have longer names.
+
+Don't stutter.
+
+- `bytes.Buffer` not `bytes.ByteBuffer`
+- `zip.Reader` not `zip.ZipReader`
+- `errors.New` not `errors.NewError`
+- `r` not `bytesReader`
+- `i` not `loopIterator`
+
+* Doc comments
+
+Doc comments precede the declaration of an exported identifier:
+
+        // Join concatenates the elements of elem to create a single string.
+        // The separator string sep is placed between elements in the resulting string.
+        func Join(elem []string, sep string) string {
+
+The godoc tool extracts such comments and presents them on the web:
+
+.image organizeio/godoc.png
+
+* Writing doc comments
+
+Doc comments should be English sentences and paragraphs.
+They use no special formatting beyond indentation for preformatted text.
+
+Doc comments should begin with the noun they describe.
+
+	// Join concatenates… 		good
+	// This function… 			bad
+
+Package docs go above the package declaration:
+
+	// Package fmt…
+	package fmt
+
+Read the world's Go docs on [[godoc.org]]. E.g.
+
+[[http://godoc.org/code.google.com/p/go.tools/cmd/vet]]
+
+* Questions?
diff --git a/2014/organizeio/godoc.png b/2014/organizeio/godoc.png
new file mode 100644
index 0000000..1f03b6e
--- /dev/null
+++ b/2014/organizeio/godoc.png
Binary files differ
diff --git a/2014/organizeio/gogetversion.png b/2014/organizeio/gogetversion.png
new file mode 100644
index 0000000..67a5d2a
--- /dev/null
+++ b/2014/organizeio/gogetversion.png
Binary files differ
diff --git a/2014/organizeio/hello.go b/2014/organizeio/hello.go
new file mode 100644
index 0000000..f7b60bd
--- /dev/null
+++ b/2014/organizeio/hello.go
@@ -0,0 +1,7 @@
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Println("Hello, world!")
+}
diff --git a/2014/organizeio/home.png b/2014/organizeio/home.png
new file mode 100644
index 0000000..7dd06cd
--- /dev/null
+++ b/2014/organizeio/home.png
Binary files differ