Skip to content

Instantly share code, notes, and snippets.

@rastasheep
Created July 28, 2013 15:58
Show Gist options
  • Save rastasheep/6099068 to your computer and use it in GitHub Desktop.
Save rastasheep/6099068 to your computer and use it in GitHub Desktop.
How to organize a multi-package golang application hosted on Github.

Introduction

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".

Code Layout

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.

Your code layout would look like this:

    $GOPATH/
        src/
            github.com/
                jmcvetta/
                    useless/
                        .git/
                        useless.go
                        useless_test.go
                        README.md
                    uselessd/
                        .git/
                        uselessd.go
                        uselessd_test.go
                        README.md

Each folder under src/github.com/jmcvetta/ is the root of a separate git checkout.

$GOPATH

Your $GOPATH variable will point to the root of your Go workspace, as described in How to Write Go Code.

Note for Eclipse Users

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.

Setup the Workspace

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:

     cd ~/workspace # Standard location for Eclipse workspace
     mkdir mygo # Create your Go workspace
     export GOPATH=~/workspace/mygo # GOPATH = Go workspace
     cd $GOPATH
     mkdir -p src/github.com/jmcvetta
     cd src/github.com/jmcvetta
     git clone [email protected]/jmcvetta/useless.git
     git clone [email protected]:jmcvetta/uselessd.git

Libraries

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:

    package useless
     
    
    func Foobar() string {
     	return "Foobar!"
     }

Applications

An application - Go code that will be compiled into an executable command - always defines package main with a main() function.

So uselessd.go looks like this:

    package main
     
    
    import (
     	"code.google.com/p/go.net/websocket"
     	"github.com/jmcvetta/useless"
     	"net/http"
     )
     
    
    func main() {
     	http.Handle("/useless", websocket.Handler(func(ws *websocket.Conn) {
     		ws.Write([]byte(useless.Foobar()))
     	}))
     	http.ListenAndServe(":3000", nil)
     }

Dependencies

Your project will probably depend on some existing packages. The application above depends upon code.google.com/p/go.net/websocket. You can install all dependencies by running "go get -v ..." from the root of your workspace. You will need to go get dependencies before compiling your code.

All dependencies will be installed alongside your code under $GOPATH/src. All Github reposities checked out by go get will be read-only, even those that belong to you. If you plan to alter the code, clone the repo manually as described above.

Build

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". See the output of "go help packages" for a full explanation of the "..." syntax.

To compile uselessd.go and its dependencies into an executable, use the command "go build ...uselessd".

Example Code

FWIW all the repo addresses on this page are real, and the uselessd application should compile if you follow the directions above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment