Before contributing to juju
please read the following sections describing
the tools and conventions of this project. This file is a companion to README
and it is assumed that file has been read prior.
Juju uses git for source control, and is hosted on Github. It also has dependencies hosted elsewhere with other version control tools. To get started, install git and configure your username:
$ cat ~/.gitconfig
[user]
name = A. Hacker
email = [email protected]
- Sign up for github (a free account is fine):
- Add your ssh public key to your account:
To get your own copy of the source code, hit the "Fork" button on the web page for the juju branch:
Then clone it locally, making sure the repo goes into the correct place in GOPATH, replace USERNAME with your github user name:
$ mkdir -p $GOPATH/src/github.com/juju
$ cd $GOPATH/src/github.com/juju
$ git clone [email protected]:USERNAME/juju.git
$ cd juju
$ git remote add upstream https://github.com/juju/juju.git
$ git fetch upstream
More detailed instructions for the general process are on the Github Help page.
To make sure that any changes you commit pass a basic sanity check, make sure to add the check script as a git hook:
$ cd $GOPATH/src/github.com/juju/juju
$ ln -s ../../scripts/pre-push.bash .git/hooks/pre-push
Using pre-push requires git 1.8.2 or later, alternatively running the check as a pre-commit hook also works.
In the top-level directory of the juju repo, there is a file, dependencies.tsv, that holds the revision ids of all the external projects that juju depends on. This file is used by godeps to freeze the code in external repositories so that juju is insulated from changes to those repos.
After getting the juju code, you need to get godeps:
go get launchpad.net/godeps
This installs the godeps application. You can then run godeps from the root of juju, to set the revision number on the external repositories:
godeps -u dependencies.tsv
Now you're ready to build, run, test, etc.
Note that you'll need to do this any time you switch to a branch that has a different dependencies.tsv file. In practice, you can wait until you get a compile error about an external package not existing/having an incorrect API, and then rerun godeps.
If you update a repo that juju depends on, you'll need to recreate depdencies.tsv:
$ godeps -t $(go list github.com/juju/juju/...) > dependencies.tsv
All development should be done on feature branches based on a current copy of master. When starting a new line of work, first check the branch is on master:
$ git branch
* master
old_feature
Pull in the latest changes from upstream, assuming you've done the setup as above:
$ git pull upstream master
Make a new branch for your work:
$ git checkout -b new_feature
Import statements are grouped into 3 sections: standard library, 3rd party libraries, juju imports. The tool "go fmt" can be used to ensure each group is alphabetically sorted. eg:
import (
"fmt"
"time"
"labix.org/v2/mgo"
gc "launchpad.net/gocheck"
"github.com/juju/loggo"
"github.com/juju/juju/state"
"github.com/juju/juju/worker"
)
Because "launchpad.net/gocheck" will be referenced frequently in test suites, its name gets a default short name of just "gc".
juju
uses the gocheck
testing framework. gocheck
is automatically
installed as a dependency of juju
. You can read more about gocheck
at http://go.pkgdoc.org/pkg/launchpad.net/gocheck. gocheck
is integrated
into the source of each package so the standard go test
command is used
to run gocheck
tests. For example
$ go test github.com/juju/juju/...
will run all the tests in the juju
project. By default gocheck
prints
only minimal output, and as gocheck
is hooked into the testing framework via
a single go test
test per package, the usual go test -v
flags are less
useful. As a replacement the following commands produce more output from
gocheck
.
$ go test -gocheck.v
is similar to go test -v
and outputs the name of each test as it is run as
well as any logging statements. It is important to note that these statements
are buffered until the test completes.
$ go test -gocheck.vv
extends the previous example by outputting any logging data immediately, rather
than waiting for the test to complete. By default gocheck
will run all tests
in a package, selected tests can by run by passing -gocheck.f
to match a subset of test names.
$ go test -gocheck.f '$REGEX'
Finally, because by default go test
runs the tests in the current package, and
is not recursive, the following commands are equal, and will produce no output.
$ cd $GOPATH/src/github.com/juju/juju
$ go test
$ go test github.com/juju/juju
Many tests use a standalone instance of mongod as part of their setup. The
mongod
binary found in $PATH is executed by these suites.
Some tests (particularly those under ./store/...) assume a MongoDB instance that supports Javascript for map-reduce functions. These functions are not supported by juju-mongodb and the associated tests will fail unless disabled with an environment variable:
$ JUJU_NOTEST_MONGOJS=1 go test github.com/juju/juju/...
When ready for feedback, push your feature branch to github, optionally after collapsing multiple commits into discrete changes:
$ git rebase -i --autosquash master
$ git push origin new_feature
Go to the web page and hit the "Pull Request" button, selecting master as the target.
This creates a numbered pull request on the github site, where members of the juju project can see and comment on the changes.
Make sure to add a clear description of why and what has been changed, and include the launchpad bug number if one exists.
It is often helpful to mention newly created proposals in the #juju-dev IRC channel on Freenode, especially if you'd like a specific developer to be aware of the proposal.
irc.freenode.net #juju-dev
A branch needs at least one approval review in order to land. By convention, this is signaled by LGTM in a review comment. In the rare case where a propsal has an issue that means it should not land, NOT LGTM can be used as a veto. Often several rounds of suggestions are made without either marker, and LGTM is added when the comments are addressed.
After a proposal has received an LGTM, the landing must be notified to test and merge
the code into master. This is done by a member of the juju project adding the magic
string