github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/CONTRIBUTING.md (about) 1 Getting started 2 =============== 3 4 Before contributing to `juju` please read the following sections describing 5 the tools and conventions of this project. This file is a companion to README 6 and it is assumed that file has been read prior. 7 8 9 ## Git 10 11 Juju uses git for source control, and is hosted on [Github](http://github.com). It also has dependencies 12 hosted elsewhere with other version control tools. To get started, install git and 13 configure your username: 14 15 ```shell 16 $ cat ~/.gitconfig 17 [user] 18 name = A. Hacker 19 email = a.hacker@example.com 20 21 ``` 22 23 1. Sign up for github (a free account is fine): 24 25 > [https://github.com/join](https://github.com/join) 26 27 2. Add your ssh public key to your account: 28 29 > [https://github.com/settings/ssh](https://github.com/settings/ssh) 30 31 ### Fork 32 33 To get your own copy of the source code, hit the "Fork" button on the web page for 34 the juju branch: 35 36 > [https://github.com/juju/juju](https://github.com/juju/juju) 37 38 Then clone it locally, making sure the repo goes into the correct place in GOPATH, 39 replace USERNAME with your github user name: 40 41 ```shell 42 $ mkdir -p $GOPATH/src/github.com/juju 43 $ cd $GOPATH/src/github.com/juju 44 $ git clone git@github.com:USERNAME/juju.git 45 $ cd juju 46 $ git remote add upstream https://github.com/juju/juju.git 47 $ git fetch upstream 48 ``` 49 50 More detailed instructions for the general process are on the [Github Help](https://help.github.com/articles/fork-a-repo) page. 51 52 To make sure that any changes you commit pass a basic sanity check, make sure to 53 add the check script as a git hook: 54 55 ```shell 56 $ cd $GOPATH/src/github.com/juju/juju 57 $ ln -s ../../scripts/pre-push.bash .git/hooks/pre-push 58 ``` 59 60 Using pre-push requires git 1.8.2 or later, alternatively running the check as a 61 pre-commit hook also works. 62 63 64 ## Dependency management 65 66 In the top-level directory of the juju repo, there is a file, dependencies.tsv, that holds the 67 revision ids of all the external projects that juju depends on. This file is used by [godeps](launchpad.net/godeps) 68 to freeze the code in external repositories so that juju is insulated from changes to those repos. 69 70 After getting the juju code, you need to get godeps: 71 72 ```shell 73 go get launchpad.net/godeps 74 ``` 75 76 This installs the godeps application. You can then run godeps from the root of juju, to set the revision number on the external repositories: 77 78 ```shell 79 godeps -u dependencies.tsv 80 ``` 81 82 Now you're ready to build, run, test, etc. 83 84 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. 85 86 If you update a repo that juju depends on, you'll need to recreate depdencies.tsv: 87 88 ```shell 89 $ godeps -t $(go list github.com/juju/juju/...) > dependencies.tsv 90 ``` 91 92 ## Working 93 94 All development should be done on feature branches based on a current copy of master. 95 When starting a new line of work, first check the branch is on master: 96 97 ```shell 98 $ git branch 99 * master 100 old_feature 101 ``` 102 103 Pull in the latest changes from upstream, assuming you've done the setup as above: 104 105 ```shell 106 $ git pull upstream master 107 ``` 108 109 Make a new branch for your work: 110 111 ```shell 112 $ git checkout -b new_feature 113 ``` 114 115 ## Imports 116 117 Import statements are grouped into 3 sections: standard library, 3rd party 118 libraries, juju imports. The tool "go fmt" can be used to ensure each 119 group is alphabetically sorted. eg: 120 121 ```go 122 123 import ( 124 "fmt" 125 "time" 126 127 "labix.org/v2/mgo" 128 gc "launchpad.net/gocheck" 129 "github.com/juju/loggo" 130 131 "github.com/juju/juju/state" 132 "github.com/juju/juju/worker" 133 ) 134 135 ``` 136 137 Because "launchpad.net/gocheck" will be referenced frequently in test suites, 138 its name gets a default short name of just "gc". 139 140 141 ## Testing 142 143 `juju` uses the `gocheck` testing framework. `gocheck` is automatically 144 installed as a dependency of `juju`. You can read more about `gocheck` 145 at http://go.pkgdoc.org/pkg/launchpad.net/gocheck. `gocheck` is integrated 146 into the source of each package so the standard `go test` command is used 147 to run `gocheck` tests. For example 148 149 ```shell 150 $ go test github.com/juju/juju/... 151 ``` 152 will run all the tests in the `juju` project. By default `gocheck` prints 153 only minimal output, and as `gocheck` is hooked into the testing framework via 154 a single `go test` test per package, the usual `go test -v` flags are less 155 useful. As a replacement the following commands produce more output from 156 `gocheck`. 157 158 ```shell 159 $ go test -gocheck.v 160 ``` 161 162 is similar to `go test -v` and outputs the name of each test as it is run as 163 well as any logging statements. It is important to note that these statements 164 are buffered until the test completes. 165 166 ```shell 167 $ go test -gocheck.vv 168 ``` 169 170 extends the previous example by outputting any logging data immediately, rather 171 than waiting for the test to complete. By default `gocheck` will run all tests 172 in a package, selected tests can by run by passing `-gocheck.f` to match a subset of test names. 173 174 175 ```shell 176 $ go test -gocheck.f '$REGEX' 177 ``` 178 179 Finally, because by default `go test` runs the tests in the current package, and 180 is not recursive, the following commands are equal, and will produce no output. 181 182 ```shell 183 $ cd $GOPATH/src/github.com/juju/juju 184 $ go test 185 $ go test github.com/juju/juju 186 ``` 187 188 ## MongoDB 189 190 Many tests use a standalone instance of mongod as part of their setup. The 191 `mongod` binary found in $PATH is executed by these suites. 192 193 Some tests (particularly those under ./store/...) assume a MongoDB instance 194 that supports Javascript for map-reduce functions. These functions are not 195 supported by juju-mongodb and the associated tests will fail unless disabled 196 with an environment variable: 197 198 ```shell 199 $ JUJU_NOTEST_MONGOJS=1 go test github.com/juju/juju/... 200 ``` 201 202 ## Proposing 203 204 When ready for feedback, push your feature branch to github, optionally after 205 collapsing multiple commits into discrete changes: 206 207 ```shell 208 $ git rebase -i --autosquash master 209 $ git push origin new_feature 210 ``` 211 Go to the web page and hit the "Pull Request" button, selecting master as the target. 212 213 > [https://github.com/$YOUR_GITHUB_USERNAME/juju](https://github.com/$YOUR_GITHUB_USERNAME/juju) 214 215 This creates a numbered pull request on the github site, where members of the juju 216 project can see and comment on the changes. 217 218 Make sure to add a clear description of why and what has been changed, and include 219 the launchpad bug number if one exists. 220 221 It is often helpful to mention newly created proposals in the #juju-dev IRC channel on 222 Freenode, especially if you'd like a specific developer to be aware of the proposal. 223 224 > irc.freenode.net #juju-dev 225 226 227 ## Code review 228 229 A branch needs at least one approval review in order to land. By convention, this is 230 signaled by LGTM in a review comment. In the rare case where a propsal has an issue 231 that means it should not land, NOT LGTM can be used as a veto. Often several rounds 232 of suggestions are made without either marker, and LGTM is added when the comments 233 are addressed. 234 235 After a proposal has received an LGTM, the landing must be notified to test and merge 236 the code into master. This is done by a member of the juju project adding the magic 237 string $$merge$$ in a comment. 238 239 240 241 242