blob: ce40a01c53d27bf13b2f15513e711e8f693bb3f4 [file] [log] [blame]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -08001= Gerrit Code Review - Building with Buck
David Pursehoused0525a72013-05-09 17:49:34 +01002
3
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -08004== Installation
David Pursehoused0525a72013-05-09 17:49:34 +01005
6There is currently no binary distribution of Buck, so it has to be manually
David Pursehouse64c16442013-05-14 10:49:03 +09007built and installed. Apache Ant is required. Currently only Linux and Mac
David Ostrovskye44706a2014-06-13 16:28:30 +02008OS are supported. Buck requires Python version 2.7 to be installed.
David Pursehoused0525a72013-05-09 17:49:34 +01009
10Clone the git and build it:
11
12----
13 git clone https://gerrit.googlesource.com/buck
14 cd buck
15 ant
16----
17
David Pursehousee9803ab2014-03-12 14:15:10 +090018If you don't have a `bin/` directory in your home directory, create one:
David Pursehoused0525a72013-05-09 17:49:34 +010019
20----
David Pursehouse64c16442013-05-14 10:49:03 +090021 mkdir ~/bin
David Pursehousee9803ab2014-03-12 14:15:10 +090022----
23
24Add the `~/bin` folder to the path:
25
26----
David Pursehouse64c16442013-05-14 10:49:03 +090027 PATH=~/bin:$PATH
David Pursehoused0525a72013-05-09 17:49:34 +010028----
29
David Pursehousee9803ab2014-03-12 14:15:10 +090030Note that the buck executable needs to be available in all shell sessions,
31so also make sure it is appended to the path globally.
32
David Pursehouse5c42b8c2013-05-17 13:25:47 +010033Add a symbolic link in `~/bin` to the buck executable:
David Pursehoused0525a72013-05-09 17:49:34 +010034
35----
David Pursehouse64c16442013-05-14 10:49:03 +090036 ln -s `pwd`/bin/buck ~/bin/
37----
38
David Pursehouse5c42b8c2013-05-17 13:25:47 +010039Verify that `buck` is accessible:
David Pursehouse64c16442013-05-14 10:49:03 +090040
41----
42 which buck
David Pursehoused0525a72013-05-09 17:49:34 +010043----
44
David Pursehousebe284992013-09-26 14:43:33 +090045To enable autocompletion of buck commands, install the autocompletion
46script from `./scripts/bash_completion` in the buck project. Refer to
47the script's header comments for installation instructions.
48
David Pursehoused0525a72013-05-09 17:49:34 +010049
David Pursehouse5861a9a2013-05-15 10:25:19 +090050[[eclipse]]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -080051== Eclipse Integration
David Pursehoused0525a72013-05-09 17:49:34 +010052
53
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -080054=== Generating the Eclipse Project
David Pursehoused0525a72013-05-09 17:49:34 +010055
Shawn Pearcea7a3ee12013-09-20 10:42:37 -070056Create the Eclipse project:
David Pursehoused0525a72013-05-09 17:49:34 +010057
58----
Shawn Pearcea7a3ee12013-09-20 10:42:37 -070059 tools/eclipse/project.py
David Pursehoused0525a72013-05-09 17:49:34 +010060----
61
62In Eclipse, choose 'Import existing project' and select the `gerrit` project
Edwin Kempin0d687ff2013-06-14 09:41:07 +020063from the current working directory.
David Pursehoused0525a72013-05-09 17:49:34 +010064
65Expand the `gerrit` project, right-click on the `buck-out` folder, select
66'Properties', and then under 'Attributes' check 'Derived'.
67
Shawn Pearcea7a3ee12013-09-20 10:42:37 -070068Note that if you make any changes in the project configuration
69that get saved to the `.project` file, for example adding Resource
70Filters on a folder, they will be overwritten the next time you run
71`tools/eclipse/project.py`.
David Pursehouse38ba8802013-05-17 13:42:03 +010072
David Pursehouseb46cf492013-05-14 09:41:30 +090073
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -080074=== Refreshing the Classpath
David Pursehoused0525a72013-05-09 17:49:34 +010075
Shawn Pearcea7a3ee12013-09-20 10:42:37 -070076If an updated classpath is needed, the Eclipse project can be
77refreshed and missing dependency JARs can be downloaded:
David Pursehoused0525a72013-05-09 17:49:34 +010078
79----
Shawn Pearcea7a3ee12013-09-20 10:42:37 -070080 tools/eclipse/project.py
David Pursehoused0525a72013-05-09 17:49:34 +010081----
82
83
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -080084=== Attaching Sources
Shawn Pearce7b553262013-05-13 21:25:13 -070085
86To save time and bandwidth source JARs are only downloaded by the buck
87build where necessary to compile Java source into JavaScript using the
88GWT compiler. Additional sources may be obtained, allowing Eclipse to
89show documentation or dive into the implementation of a library JAR:
90
91----
Shawn Pearcea7a3ee12013-09-20 10:42:37 -070092 tools/eclipse/project.py --src
Shawn Pearce7b553262013-05-13 21:25:13 -070093----
94
95
David Pursehouse6de7ee22013-05-20 11:08:51 +090096[[build]]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -080097== Building on the Command Line
David Pursehoused0525a72013-05-09 17:49:34 +010098
99
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800100=== Gerrit Development WAR File
David Pursehoused0525a72013-05-09 17:49:34 +0100101
102To build the Gerrit web application:
103
104----
105 buck build gerrit
106----
107
108The output executable WAR will be placed in:
109
110----
111 buck-out/gen/gerrit.war
112----
113
114
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800115=== Extension and Plugin API JAR Files
David Pursehoused0525a72013-05-09 17:49:34 +0100116
David Ostrovskye5487a02013-11-25 00:00:13 +0100117To build the extension, plugin and GWT API JAR files:
David Pursehoused0525a72013-05-09 17:49:34 +0100118
119----
120 buck build api
121----
122
David Ostrovskye5487a02013-11-25 00:00:13 +0100123Java binaries, Java sources and Java docs are generated into corresponding
David Pursehouse43dc7482013-12-13 14:54:42 +0900124project directories in `buck-out/gen`, here as example for plugin API:
David Pursehoused0525a72013-05-09 17:49:34 +0100125
126----
David Ostrovskye5487a02013-11-25 00:00:13 +0100127 buck-out/gen/gerrit-plugin-api/plugin-api.jar
128 buck-out/gen/gerrit-plugin-api/plugin-api-src.jar
129 buck-out/gen/gerrit-plugin-api/plugin-api-javadoc.jar
David Pursehoused0525a72013-05-09 17:49:34 +0100130----
131
David Ostrovsky358a4582014-05-13 23:55:04 +0200132Install {extension,plugin,gwt}-api to the local maven repository:
David Ostrovsky6e6a9672013-05-30 01:10:12 +0200133
134----
135 buck build api_install
136----
137
David Ostrovsky358a4582014-05-13 23:55:04 +0200138Install gerrit.war to the local maven repository:
139
140----
141 buck build war_install
142----
143
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800144=== Plugins
David Pursehouse0bc51db2013-05-14 12:46:49 +0900145
146To build all core plugins:
147
148----
149 buck build plugins:core
150----
151
152The output JAR files for individual plugins will be placed in:
153
154----
155 buck-out/gen/plugins/<name>/<name>.jar
156----
157
158The JAR files will also be packaged in:
159
160----
161 buck-out/gen/plugins/core.zip
162----
163
164To build a specific plugin:
165
166----
Shawn Pearce6586c202013-11-09 08:54:48 -0800167 buck build plugins/<name>:<name>
David Pursehouse0bc51db2013-05-14 12:46:49 +0900168----
169
170The output JAR file will be be placed in:
171
172----
173 buck-out/gen/plugins/<name>/<name>.jar
174----
175
176Note that when building an individual plugin, the `core.zip` package
177is not regenerated.
178
Shawn Pearce6586c202013-11-09 08:54:48 -0800179Additional plugins with BUCK files can be added to the build
180environment by cloning the source repository into the plugins
181subdirectory:
182
183----
184 git clone https://gerrit.googlesource.com/plugins/<name> plugins/<name>
185 echo /plugins/<name> >>.git/info/exclude
186----
187
188Additional plugin sources will be automatically added to Eclipse the
189next time project.py is run:
190
191----
192 tools/eclipse/project.py
193----
194
David Pursehouse90a9c102013-09-06 18:42:10 +0900195
196[[documentation]]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800197=== Documentation
David Pursehouse90a9c102013-09-06 18:42:10 +0900198
David Pursehousec08d03e2013-12-10 18:16:10 +0900199To build only the documentation:
David Pursehouse90a9c102013-09-06 18:42:10 +0900200
201----
202 buck build docs
203----
204
205The generated html files will be placed in:
206
207----
David Ostrovsky7cd233e2013-09-26 07:21:31 +0200208 buck-out/gen/Documentation/html__tmp/Documentation
David Pursehouse90a9c102013-09-06 18:42:10 +0900209----
210
David Ostrovsky7cd233e2013-09-26 07:21:31 +0200211The html files will also be bundled into `html.zip` in this location:
David Pursehouse90a9c102013-09-06 18:42:10 +0900212
David Ostrovsky7cd233e2013-09-26 07:21:31 +0200213----
214 buck-out/gen/Documentation/html.zip
215----
David Pursehouse90a9c102013-09-06 18:42:10 +0900216
David Pursehousec08d03e2013-12-10 18:16:10 +0900217To build the executable WAR with the documentation included:
218
219----
220 buck build withdocs
221----
222
223The WAR file will be placed in:
224
225----
226 buck-out/gen/withdocs.war
227----
228
David Ostrovsky811e6032013-09-06 08:35:45 +0200229[[release]]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800230=== Gerrit Release WAR File
David Ostrovsky811e6032013-09-06 08:35:45 +0200231
232To build the release of the Gerrit web application, including documentation and
233all core plugins:
234
235----
236 buck build release
237----
238
239The output release WAR will be placed in:
240
241----
242 buck-out/gen/release.war
243----
David Pursehouse0bc51db2013-05-14 12:46:49 +0900244
David Ostrovskye64e30d2014-03-25 06:25:56 -0700245[[all]]
246=== Combined build target
247
248To build release and api targets, a combined build target is provided:
249
250----
251 buck build all
252----
253
David Pursehouse5861a9a2013-05-15 10:25:19 +0900254[[tests]]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800255== Running Unit Tests
David Pursehoused0525a72013-05-09 17:49:34 +0100256
257To run all tests including acceptance tests:
258
259----
David Ostrovsky530a4c32014-06-25 00:36:59 +0200260 buck test
David Pursehoused0525a72013-05-09 17:49:34 +0100261----
262
263To exclude slow tests:
264
265----
Shawn Pearce11d27c82013-07-24 08:09:31 -0700266 buck test --all --exclude slow
David Pursehoused0525a72013-05-09 17:49:34 +0100267----
268
David Ostrovskyc4e0ac62014-04-21 18:25:18 +0200269To include a specific group of acceptance tests:
270
271----
272 buck test --all --include api
273----
274
275The following groups of tests are currently supported:
276
277* api
278* git
279* pgm
280* rest
281* server
282* ssh
283
Edwin Kempin674078a2013-08-20 11:37:14 +0200284To run a specific test, e.g. the acceptance test
285`com.google.gerrit.acceptance.git.HttpPushForReviewIT`:
286
287----
288 buck test //gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git:HttpPushForReviewIT
289----
290
David Pursehoused0525a72013-05-09 17:49:34 +0100291
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800292== Dependencies
David Pursehoused0525a72013-05-09 17:49:34 +0100293
294Dependency JARs are normally downloaded automatically, but Buck can inspect
295its graph and download any missing JAR files. This is useful to enable
Shawn Pearcea7a3ee12013-09-20 10:42:37 -0700296subsequent builds to run without network access:
David Pursehoused0525a72013-05-09 17:49:34 +0100297
298----
Shawn Pearcea7a3ee12013-09-20 10:42:37 -0700299 tools/download_all.py
David Pursehoused0525a72013-05-09 17:49:34 +0100300----
301
David Pursehouseb46cf492013-05-14 09:41:30 +0900302When downloading from behind a proxy (which is common in some corporate
303environments), it might be necessary to explicitly specify the proxy that
304is then used by `curl`:
305
306----
307 export http_proxy=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
308----
309
Shawn Pearce1b89f852013-05-13 20:26:34 -0700310Redirection to local mirrors of Maven Central and the Gerrit storage
311bucket is supported by defining specific properties in
312`local.properties`, a file that is not tracked by Git:
313
314----
315 echo download.GERRIT = http://nexus.my-company.com/ >>local.properties
316 echo download.MAVEN_CENTRAL = http://nexus.my-company.com/ >>local.properties
317----
318
David Pursehouse6fb2c4d2013-05-16 16:51:46 +0900319The `local.properties` file may be placed in the root of the gerrit repository
320being built, or in `~/.gerritcodereview/`. The file in the root of the gerrit
321repository has precedence.
322
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800323== Building against unpublished Maven JARs
David Ostrovskyee9f9922013-08-15 00:21:04 +0200324
325To build against unpublished Maven JARs, like gwtorm or PrologCafe, the custom
David Pursehouseb99db5c2013-09-26 11:34:42 +0900326JARs must be installed in the local Maven repository (`mvn clean install`) and
327`maven_jar()` must be updated to point to the `MAVEN_LOCAL` Maven repository for
David Ostrovskyee9f9922013-08-15 00:21:04 +0200328that artifact:
329
David Pursehouseb99db5c2013-09-26 11:34:42 +0900330[source,python]
David Ostrovskyee9f9922013-08-15 00:21:04 +0200331----
332 maven_jar(
333 name = 'gwtorm',
334 id = 'gwtorm:gwtorm:42',
David Ostrovskyee9f9922013-08-15 00:21:04 +0200335 license = 'Apache2.0',
336 repository = MAVEN_LOCAL,
337 )
338----
339
David Ostrovsky07df9592014-02-01 23:47:22 +0100340== Building against unpublished JARs, that change frequently
341
342If a dependent Gerrit library is undergoing active development it must be
343recompiled and the change must be reflected in the Buck build process. For
344example testing Gerrit against changed JGit snapshot version. After building
345JGit library, the artifacts are created in local Maven build directory, e. g.:
346
347----
348 mvn package
349 /home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT.jar
350 /home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT-sources.jar
351----
352
353If as usual, installation of the build artifacts takes place in local maven
354repository, then the Buck build must fetch them from there with normal
355`download_file.py` process. Disadvantage of this approach is that Buck cache
356invalidation must occur to refresh the artifacts after next
357change-compile-install round trip.
358
359To shorten that workflow and take the installation of the artifacts to the
360local Maven repository and fetching it again from there out of the picture,
361`local_jar()` method is used instead of `maven_jar()`:
362
363[source,python]
364----
365 local_jar(
366 name = 'jgit',
367 jar = '/home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT.jar',
368 src = '/home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT-sources.jar',
369 deps = [':ewah']
370 )
371----
372
373This creates a symlink to the Buck targets direct against artifacts in
374another project's Maven target directory:
375
376----
377 buck-out/gen/lib/jgit/jgit.jar ->
378 /home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT.jar
379----
380
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800381== Building against artifacts from custom Maven repositories
David Ostrovsky2536d062013-11-14 00:35:07 +0100382
383To build against custom Maven repositories, two modes of operations are
384supported: with rewrite in local.properties and without.
385
386Without rewrite the URL of custom Maven repository can be directly passed
387to the maven_jar() function:
388
389[source,python]
390----
391 GERRIT_FORGE = 'http://gerritforge.com/snapshot'
392
393 maven_jar(
394 name = 'gitblit',
395 id = 'com.gitblit:gitblit:1.4.0',
396 sha1 = '1b130dbf5578ace37507430a4a523f6594bf34fa',
397 license = 'Apache2.0',
398 repository = GERRIT_FORGE,
399 )
400----
401
402When the custom URL has to be rewritten, then the same logic as with Gerrit
403known Maven repository is used: Repo name must be defined that matches an entry
404in local.properties file:
405
406----
407 download.GERRIT_FORGE = http://my.company.mirror/gerrit-forge
408----
409
410And corresponding BUCK excerpt:
411
412[source,python]
413----
414 GERRIT_FORGE = 'GERRIT_FORGE:'
415
416 maven_jar(
417 name = 'gitblit',
418 id = 'com.gitblit:gitblit:1.4.0',
419 sha1 = '1b130dbf5578ace37507430a4a523f6594bf34fa',
420 license = 'Apache2.0',
421 repository = GERRIT_FORGE,
422 )
423----
424
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800425=== Caching Build Results
Shawn Pearce9e4e2432013-05-30 13:09:29 -0700426
427Build results can be locally cached, saving rebuild time when
428switching between Git branches. Buck's documentation covers
429caching in link:http://facebook.github.io/buck/concept/buckconfig.html[buckconfig].
430The trivial case using a local directory is:
431
432----
433 cat >.buckconfig.local <<EOF
434 [cache]
435 mode = dir
436 dir = buck-cache
437 EOF
438----
439
Edwin Kempin9a8b1dc2013-09-16 09:08:34 +0200440[[buck-daemon]]
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800441=== Using Buck daemon
David Ostrovskyd5ae8d32013-09-15 20:10:17 +0200442
David Pursehouseb99db5c2013-09-26 11:34:42 +0900443Buck ships with a daemon command `buckd`, which uses the
David Ostrovskyd5ae8d32013-09-15 20:10:17 +0200444link:https://github.com/martylamb/nailgun[Nailgun] protocol for running
445Java programs from the command line without incurring the JVM startup
David Pursehouseb99db5c2013-09-26 11:34:42 +0900446overhead.
447
448Using a Buck daemon can save significant amounts of time as it avoids the
449overhead of starting a Java virtual machine, loading the buck class files
450and parsing the build files for each command.
451
452It is safe to run several buck daemons started from different project
453directories and they will not interfere with each other. Buck's documentation
454covers daemon in http://facebook.github.io/buck/command/buckd.html[buckd].
455
David Ostrovsky26e3be62014-05-23 08:34:07 +0200456To use `buckd` the additional
457link:https://facebook.github.io/watchman[watchman] program must be installed.
458
459[[watchman]]
460=== Installing watchman
461
462Watchman is used internally by Buck to monitor directory trees and is needed
463for buck daemon to work properly. Because buckd is activated by default in the
464latest version of Buck, it searches for the watchman executable in the
465path and issues a warning when it is not found and kills buckd.
466
467To prepare watchman installation on Linux:
David Ostrovskyd5ae8d32013-09-15 20:10:17 +0200468
469----
David Ostrovsky26e3be62014-05-23 08:34:07 +0200470 git clone https://github.com/facebook/watchman.git
471 cd watchman
472 ./autogen.sh
David Ostrovskyd5ae8d32013-09-15 20:10:17 +0200473----
474
David Ostrovsky26e3be62014-05-23 08:34:07 +0200475To install it in user home directory (without root privileges):
476
477----
478 ./configure --prefix $HOME/watchman
479 make install
480----
481
482To install it system wide:
483
484----
485 ./configure
486 make
487 sudo make install
488----
489
490Put $HOME/watchman/bin/watchman in path or link to $HOME/bin/watchman.
491
492To install watchman on OS X:
493
494----
495 brew install --HEAD watchman
496----
497
498See the original documentation for more information:
499link:https://facebook.github.io/watchman/docs/install.html[Watchman
500installation].
501
Yuxuan 'fishy' Wang61698b12013-12-20 12:55:51 -0800502=== Override Buck's settings
David Ostrovskyefaff302013-09-20 22:36:14 +0200503
Shawn Pearce4e1a8bc2013-11-28 18:38:30 -0800504Additional JVM args for Buck can be set in `.buckjavaargs` in the
505project root directory. For example to override Buck's default 1GB
506heap size:
David Ostrovskyefaff302013-09-20 22:36:14 +0200507
508----
Shawn Pearce4e1a8bc2013-11-28 18:38:30 -0800509 cat > .buckjavaargs <<EOF
510 -XX:MaxPermSize=512m -Xms8000m -Xmx16000m
David Ostrovskyefaff302013-09-20 22:36:14 +0200511 EOF
512----
513
David Ostrovskyfe2934e2014-04-22 00:36:12 +0200514== Rerun unit tests
David Ostrovskya4ea92e72014-03-25 06:42:33 -0700515
David Pursehouse56f60a42014-07-10 11:20:33 +0900516Test execution results are cached by Buck. If a test that was already run
517needs to be repeated, the unit test cache for that test must be removed first:
David Ostrovskya4ea92e72014-03-25 06:42:33 -0700518
519----
520 $ rm -rf buck-out/bin/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/.AddRemoveGroupMembersIT/
521----
522
David Pursehouse56f60a42014-07-10 11:20:33 +0900523After clearing the cache, the test can be run again:
David Ostrovskya4ea92e72014-03-25 06:42:33 -0700524
525----
526 $ buck test //gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group:AddRemoveGroupMembersIT
527 TESTING //gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group:AddRemoveGroupMembersIT
528 PASS 14,9s 8 Passed 0 Failed com.google.gerrit.acceptance.rest.group.AddRemoveGroupMembersIT
529 TESTS PASSED
530----
531
David Pursehouse56f60a42014-07-10 11:20:33 +0900532An alternative approach is to use Buck's `--filters` (`-f`) option:
David Ostrovskya4ea92e72014-03-25 06:42:33 -0700533
534----
David Pursehouse56f60a42014-07-10 11:20:33 +0900535 buck test -f 'com.google.gerrit.acceptance.rest.change.SubmitByMergeAlwaysIT'
David Ostrovskya4ea92e72014-03-25 06:42:33 -0700536 TESTING SELECTED TESTS
537 PASS 14,5s 6 Passed 0 Failed com.google.gerrit.acceptance.rest.change.SubmitByMergeAlwaysIT
538 TESTS PASSED
539----
540
David Pursehouse56f60a42014-07-10 11:20:33 +0900541When this option is used, the cache is disabled per design and doesn't need to
542be explicitly deleted.
543
544Note that when this option is used, the whole unit test cache is dropped, so
David Ostrovsky074859e2014-04-19 22:52:47 +0200545repeating the
546
547----
David Pursehouse56f60a42014-07-10 11:20:33 +0900548buck test
David Ostrovsky074859e2014-04-19 22:52:47 +0200549----
550
David Pursehouse56f60a42014-07-10 11:20:33 +0900551causes all tests to be executed again.
552
553To run tests without using cached results at all, use the `--no-results-cache`
554option:
555
556----
557buck test --no-results-cache
558----
David Ostrovskya4ea92e72014-03-25 06:42:33 -0700559
David Pursehoused0525a72013-05-09 17:49:34 +0100560GERRIT
561------
562Part of link:index.html[Gerrit Code Review]
Yuxuan 'fishy' Wang99cb68d2013-10-31 17:26:00 -0700563
564SEARCHBOX
565---------