~themue/juju-core/053-env-more-script-friendly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
Getting started
===============

Before contributing to `juju-core` 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.

cobzr
-----

juju-core uses bzr for source control. To make the bzr branching strategy more
palatable for the go toolset `juju-core` recommends using the `cobzr` helper.
`cobzr` allows the user to juggle multiple branches in place in a way that is
compatible with GOPATH. While it is possible to manage bzr branches manually,
the remainder of this document will assume cobzr is in use as practiced by the
juju-core team.

To install `cobzr`,

    go get launchpad.net/cobzr

TODO(dfc) document PPA version

It is recommended to use alias `cobzr` to `bzr`.

    alias bzr=cobzr

As `cobzr` passes any options it does not handle to `bzr`, it is safe, and recommended
to add this alias command to your login shell.

lbox
----

`juju-core` uses `lbox` for code review and submission. In addition `lbox` enables
the use of prerequisite branches.

To install lbox

    go get launchpad.net/lbox

TODO(dfc) document PPA version

Branching
=========

All changes to `juju-core` must be performed on a branch, that branch reviewed,
then submitted. An overview of the commands used to do so follows. These
examples use the `bzr` command, which is assumed to be aliased to `cobzr`, as
described above. It is also assumed that your working directory is
$GOPATH/src/launchpad.net/juju-core.

First, create a branch for your change using the following command

    bzr branch lp:juju-core/ add-CONTRIBUTING

This will branch `juju-core` and create a new branch called `add-CONTRIBUTING` in
your local workspace. Importantly this will not switch to this branch immediately,
so to switch to this branch use the following

    bzr switch add-CONTRIBUTING

At this point your previous branch will be stashed and the working copy updated
to match the state of the `add-CONTRIBUTING` branch. You must ensure any
outstanding changes to the previous branch are committed or reverted to avoid
local merge issues.

You can also list any branches you are currently working on by

    bzr branch


Imports
-------

Import statements are grouped into 3 sections: standard library, 3rd party
libraries, juju-core 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"
        "launchpad.net/loggo"

        "launchpad.net/juju-core/state"
        "launchpad.net/juju-core/worker"
    )

Because "launchpad.net/gocheck" will be referenced frequently in test suites,
its name gets a default short name of just "gc".

Testing
=======

`juju-core` uses the `gocheck` testing framework. `gocheck` is automatically
installed as a dependency of `juju-core`. 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 launchpad.net/juju-core/...

will run all the tests in the `juju-core` 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`

    go test -gocheck.f '$REGEX'

to match a subset of test names.

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/launchpad.net/juju-core
    go test

    go test launchpad.net/juju-core

Proposing
=========

All code review is done on rietveld (http://code.google.com/p/rietveld/), not
on launchpad.

Note: If this is your first time using `lbox` you will also be prompted to visit
lauchpad to authorise an oauth token for `lbox`

Once your change is ready, and you have successfully run all the tests you can
propose your branch for merging

    lbox propose

`lbox` will prompt you for a branch description and will create a rietveld code
review for this change, linking it to the launchpad branch, and mailing
reviewers. The `lbox` tool manages the state of the launchpad review, with the
exception of marking reviews as rejected or work in progress by the reviewer.
If you abandon a proposal, you should mark it as rejected in launchpad to avoid
wasting the time of others. If you decide to start again, you should add a
comment to the abandoned rietveld proposal linking it to your replacement.

If your proposal requires additional work, then you can use the `lbox propose`
command again to re-propose, this will also instruct rietveld to mail off any
comments to your reviewers and upload fresh diff.

If your branch requires another branch as a prerequisite use the `-req` flag to
indicate so

    lbox propose -req lp:dave-cheney/add-README

This will produce a diff in rietveld which masks the changes from your prereq.

It is sometimes useful to be able to review your branch in rietveld without
proposing, do to this the `-wip` flag is used

    lbox propose -wip

You can also edit the description of your change with `-edit`. This is useful
when combined with the `-wip` flag to avoid sending too many mails to reviewers
while preparing your proposal.

    lbox propose -edit

By default, lbox creates a new bug in launchpad for each proposed branch, and
assigns the branch to it. If you wish to assign it to an existing bug instead,
use the `-bug` flag to link the branch inside launchpad.

    lbox propose -bug 1234567

There is currently a bug with `lbox` when linking a branch to a bug which sets
the milestone field to the last milestone defined on the project. Generally
this is not what you want, so you should visit the bug's page and correct the
milestone, if set.

Code review
===========

`juju-core` operates on a two positive, no negative review process. You may not
submit your proposal until it has received two LGTM comments. If any NOT LGTM
comments are received, those comments should be resolved to the satisfaction
of the objecting reviewer before submitting. Once your have received at least
two positive reviews, you can submit your branch by going to the launchpad
merge proposal page and:

    - copy and paste the merge proposal description into the
    commit message.
    - mark the proposal as Approved.

The merge proposal will then be tested and merged into trunk assuming
all tests pass cleanly.

lbox hooks
----------

Before proposing, `lbox` runs a number of hooks to improve code quality and
ensure that code is properly formatted. These checks are in
`$GOPATH/src/launchpad.net/juju-core/.lbox.check`. They are run automatically
by `lbox` before proposing or submitting. If these hooks fail you will have
to resolve those errors before trying again. For example

    % lbox propose
    gofmt is sad:

        version/version.go

Dependency management
=====================

In the top-level directory, there is a file, dependencies.tsv, that
holds the revision ids of all the external projects that juju-core
depends on. The tab-separated columns in the file are
the project name, the type version control system used by
that project, and the revision id and number respectively.

This file is generated by running the godeps command (which you
can get with `go get launchpad.net/godeps') on a juju-core
installation with all freshly downloaded directories.

The bash commands used to generate it from scratch are as follows:

    % export GOPATH=/tmp/juju-build
    % go get launchpad.net/juju-core/...
    % go test launchpad.net/juju-core/...
    % godeps -t $(go list launchpad.net/juju-core/...) > dependencies.tsv