Buck: Allow to consume JGit from its own cell

Consume JGit as first third party library from its own cell. Normally
the cell is defined as lib/jgit directory. It can be easily replaced
with CLI:

  buck build --config repositories.jgit=path/to/dev/jgit gerrit

or tweaking the .buckconfig:

  [repositories]
    jgit = path/to/dev/jgit

The former approach is sufficient to build and run the test from the
CLI, the latter is needed to generate eclipse project.

To isolate the JGit rules in its own cell some refactoring was needed.
JGit patch for GWT module was moved to gerrit-patch-jgit project, and
some symlinks were needed for maven machinery to work. include_defs()
doesn't work for now across cell boundaries, and native `buck fetch`
feature still has some limitations: [1]. Moreover, excluding paths,
unsigning JARs and license linking should be re-implemented on top
of it.

[1] https://github.com/facebook/buck/issues/602

Test Plan:

Normal gerrit build and the build with hijacked JGit cell should work
in both standalone (gerrit.war) and Eclipse environment. Note, that
to test --config repositories.jgit=path/to/dev/jgit use case, the most
recent JGit tree must be used, that contains Buck driven build
implementation.

Change-Id: I39f2d5d75bbac88804406d6242b5e714f4916926
diff --git a/.buckconfig b/.buckconfig
index 7814eec..61c28e4 100644
--- a/.buckconfig
+++ b/.buckconfig
@@ -22,7 +22,7 @@
 
 [java]
   jar_spool_mode = direct_to_jar
-  src_roots = java, resources
+  src_roots = java, resources, src
 
 [project]
   ignore = .git, eclipse-out
@@ -34,3 +34,7 @@
 
 [test]
   excluded_labels = manual
+
+[repositories]
+  jgit = lib/jgit
+
diff --git a/gerrit-acceptance-framework/BUCK b/gerrit-acceptance-framework/BUCK
index 9ee1572..4e85d90 100644
--- a/gerrit-acceptance-framework/BUCK
+++ b/gerrit-acceptance-framework/BUCK
@@ -14,9 +14,9 @@
   '//lib/httpcomponents:httpclient',
   '//lib/httpcomponents:httpcore',
   '//lib/jetty:servlet',
-  '//lib/jgit:junit',
   '//lib/log:impl_log4j',
   '//lib/log:log4j',
+  '@jgit//:junit',
 ]
 
 PROVIDED = [
@@ -29,10 +29,10 @@
   '//gerrit-reviewdb:server',
   '//gerrit-server:server',
   '//lib:gson',
-  '//lib/jgit:jgit',
   '//lib:jsch',
   '//lib/mina:sshd',
   '//lib:servlet-api-3_1',
+  '@jgit//:jgit',
 ]
 
 java_binary(
diff --git a/gerrit-acceptance-tests/BUCK b/gerrit-acceptance-tests/BUCK
index 7f9ffa6..ebc5d00 100644
--- a/gerrit-acceptance-tests/BUCK
+++ b/gerrit-acceptance-tests/BUCK
@@ -32,9 +32,9 @@
     '//lib/guice:guice',
     '//lib/guice:guice-assistedinject',
     '//lib/guice:guice-servlet',
-    '//lib/jgit:jgit',
     '//lib/log:api',
     '//lib/mina:sshd',
+    '@jgit//:jgit',
   ],
   visibility = [
     '//gerrit-plugin-api/...',
diff --git a/gerrit-cache-h2/BUCK b/gerrit-cache-h2/BUCK
index 37c8b96..7790a23 100644
--- a/gerrit-cache-h2/BUCK
+++ b/gerrit-cache-h2/BUCK
@@ -8,8 +8,8 @@
     '//lib:guava',
     '//lib:h2',
     '//lib/guice:guice',
-    '//lib/jgit:jgit',
     '//lib/log:api',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-common/BUCK b/gerrit-common/BUCK
index a36a9b7..10bb754 100644
--- a/gerrit-common/BUCK
+++ b/gerrit-common/BUCK
@@ -44,9 +44,9 @@
     '//lib:gwtjsonrpc',
     '//lib:gwtorm',
     '//lib:guava',
-    '//lib/jgit:jgit',
     '//lib/joda:joda-time',
     '//lib/log:api',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-gpg/BUCK b/gerrit-gpg/BUCK
index 2b258a9..6d6579c 100644
--- a/gerrit-gpg/BUCK
+++ b/gerrit-gpg/BUCK
@@ -8,8 +8,8 @@
   '//lib/guice:guice',
   '//lib/guice:guice-assistedinject',
   '//lib/guice:guice-servlet',
-  '//lib/jgit:jgit',
   '//lib/log:api',
+  '@jgit//:jgit',
 ]
 
 java_library(
@@ -45,12 +45,12 @@
     ':gpg',
     ':testutil',
     '//gerrit-cache-h2:cache-h2',
-    '//gerrit-lucene:lucene',  
+    '//gerrit-lucene:lucene',
     '//gerrit-server:testutil',
     '//lib:truth',
     '//lib/bouncycastle:bcpg',
     '//lib/bouncycastle:bcprov',
-    '//lib/jgit:junit',
+    '@jgit//:junit',
   ],
   source_under_test = [':gpg'],
   visibility = ['//tools/eclipse:classpath'],
diff --git a/gerrit-gwtui-common/BUCK b/gerrit-gwtui-common/BUCK
index 436714a..6aa2d98 100644
--- a/gerrit-gwtui-common/BUCK
+++ b/gerrit-gwtui-common/BUCK
@@ -64,7 +64,7 @@
     ':client',
     '//lib:junit',
     '//lib/gwt:user',
-    '//lib/jgit:jgit',
+    '@jgit//:jgit',
   ],
   source_under_test = [':client'],
   vm_args = ['-Xmx512m'],
diff --git a/gerrit-httpd/BUCK b/gerrit-httpd/BUCK
index 7988cf6..3eff7d9 100644
--- a/gerrit-httpd/BUCK
+++ b/gerrit-httpd/BUCK
@@ -33,10 +33,10 @@
     '//lib/guice:guice',
     '//lib/guice:guice-assistedinject',
     '//lib/guice:guice-servlet',
-    '//lib/jgit:jgit',
-    '//lib/jgit:jgit-servlet',
     '//lib/log:api',
     '//lib/lucene:lucene-core-and-backward-codecs',
+    '@jgit//:jgit',
+    '@jgit//:jgit-servlet',
   ],
   provided_deps = ['//lib:servlet-api-3_1'],
   visibility = ['PUBLIC'],
@@ -69,9 +69,9 @@
     '//lib/easymock:easymock',
     '//lib/guice:guice',
     '//lib/guice:guice-servlet',
-    '//lib/jgit:jgit',
-    '//lib/jgit:junit',
     '//lib/joda:joda-time',
+    '@jgit//:jgit',
+    '@jgit//:junit',
   ],
   source_under_test = [':httpd'],
   # TODO(sop) Remove after Buck supports Eclipse
diff --git a/gerrit-lucene/BUCK b/gerrit-lucene/BUCK
index 5a6df97..7b524df 100644
--- a/gerrit-lucene/BUCK
+++ b/gerrit-lucene/BUCK
@@ -31,11 +31,11 @@
     '//lib:gwtorm',
     '//lib/guice:guice',
     '//lib/guice:guice-assistedinject',
-    '//lib/jgit:jgit',
     '//lib/log:api',
     '//lib/lucene:lucene-analyzers-common',
     '//lib/lucene:lucene-core-and-backward-codecs',
     '//lib/lucene:lucene-misc',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-openid/BUCK b/gerrit-openid/BUCK
index 0a6363b..9e99399 100644
--- a/gerrit-openid/BUCK
+++ b/gerrit-openid/BUCK
@@ -19,8 +19,8 @@
     '//lib/commons:codec',
     '//lib/guice:guice',
     '//lib/guice:guice-servlet',
-    '//lib/jgit:jgit',
     '//lib/log:api',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-patch-jgit/BUCK b/gerrit-patch-jgit/BUCK
index b54499f..434be37 100644
--- a/gerrit-patch-jgit/BUCK
+++ b/gerrit-patch-jgit/BUCK
@@ -9,12 +9,33 @@
   gwt_xml = SRC + 'JGit.gwt.xml',
   deps = [
     '//lib:gwtjsonrpc',
-    '//lib/jgit:Edit',
+    ':Edit',
   ],
   provided_deps = ['//lib/gwt:user'],
   visibility = ['PUBLIC'],
 )
 
+gwt_module(
+  name = 'Edit',
+  srcs = [':jgit_edit_src'],
+  deps = [':edit_src'],
+  visibility = ['PUBLIC'],
+)
+
+prebuilt_jar(
+  name = 'edit_src',
+  binary_jar = ':jgit_edit_src',
+)
+
+genrule(
+  name = 'jgit_edit_src',
+  cmd = 'unzip -qd $TMP $(location @jgit//:jgit_src) ' +
+    'org/eclipse/jgit/diff/Edit.java;' +
+    'cd $TMP;' +
+    'zip -Dq $OUT org/eclipse/jgit/diff/Edit.java',
+  out = 'edit.src.zip',
+)
+
 java_library(
   name = 'server',
   srcs = [
@@ -25,7 +46,7 @@
   ],
   deps = [
     '//lib:gson',
-    '//lib/jgit:jgit',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
@@ -35,8 +56,8 @@
   srcs = glob(['src/test/java/**/*.java']),
   deps = [
     ':server',
-    '//lib/jgit:jgit',
     '//lib:junit',
+    '@jgit//:jgit',
   ],
   source_under_test = [':server'],
   visibility = ['//tools/eclipse:classpath'],
diff --git a/gerrit-pgm/BUCK b/gerrit-pgm/BUCK
index 3a14ffd..8ea8eab 100644
--- a/gerrit-pgm/BUCK
+++ b/gerrit-pgm/BUCK
@@ -15,9 +15,9 @@
   '//lib/guice:guice',
   '//lib/guice:guice-assistedinject',
   '//lib/guice:guice-servlet',
-  '//lib/jgit:jgit',
   '//lib/log:api',
   '//lib/log:log4j',
+  '@jgit//:jgit',
 ]
 
 DEPS = BASE_JETTY_DEPS + [
@@ -176,8 +176,8 @@
     '//lib:junit',
     '//lib/easymock:easymock',
     '//lib/guice:guice',
-    '//lib/jgit:jgit',
-    '//lib/jgit:junit',
+    '@jgit//:jgit',
+    '@jgit//:junit',
   ],
   source_under_test = [':pgm'],
 )
diff --git a/gerrit-plugin-api/BUCK b/gerrit-plugin-api/BUCK
index b58c10a..a810157 100644
--- a/gerrit-plugin-api/BUCK
+++ b/gerrit-plugin-api/BUCK
@@ -39,10 +39,10 @@
     '//lib/guice:guice',
     '//lib/guice:guice-assistedinject',
     '//lib/guice:guice-servlet',
-    '//lib/jgit:jgit',
     '//lib/joda:joda-time',
     '//lib/log:api',
     '//lib/mina:sshd',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-prettify/BUCK b/gerrit-prettify/BUCK
index 9a0136e..b4d0844 100644
--- a/gerrit-prettify/BUCK
+++ b/gerrit-prettify/BUCK
@@ -17,10 +17,10 @@
   exported_deps = [
     '//gerrit-extension-api:client',
     '//gerrit-patch-jgit:client',
+    '//gerrit-patch-jgit:Edit',
     '//gerrit-reviewdb:client',
     '//lib:gwtjsonrpc',
     '//lib:gwtjsonrpc_src',
-    '//lib/jgit:Edit',
   ],
   provided_deps = ['//lib/gwt:user'],
   visibility = ['PUBLIC'],
@@ -44,7 +44,7 @@
     '//gerrit-reviewdb:server',
     '//lib:guava',
     '//lib:gwtjsonrpc',
-    '//lib/jgit:jgit',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-server/BUCK b/gerrit-server/BUCK
index 567754f..3fc4580 100644
--- a/gerrit-server/BUCK
+++ b/gerrit-server/BUCK
@@ -45,6 +45,7 @@
     '//lib:mime-util',
     '//lib:pegdown',
     '//lib:protobuf',
+    '//lib:tukaani-xz',
     '//lib:velocity',
     '//lib/antlr:java_runtime',
     '//lib/auto:auto-value',
@@ -58,8 +59,6 @@
     '//lib/guice:guice',
     '//lib/guice:guice-assistedinject',
     '//lib/guice:guice-servlet',
-    '//lib/jgit:jgit',
-    '//lib/jgit:jgit-archive',
     '//lib/joda:joda-time',
     '//lib/log:api',
     '//lib/log:jsonevent-layout',
@@ -71,6 +70,8 @@
     '//lib/ow2:ow2-asm-tree',
     '//lib/ow2:ow2-asm-util',
     '//lib/prolog:runtime',
+    '@jgit//:jgit',
+    '@jgit//:jgit-archive',
   ],
   provided_deps = [
     '//lib:servlet-api-3_1',
@@ -97,12 +98,12 @@
   '//lib:truth',
   '//lib/guice:guice',
   '//lib/guice:guice-servlet',
-  '//lib/jgit:jgit',
-  '//lib/jgit:junit',
   '//lib/joda:joda-time',
   '//lib/log:api',
   '//lib/log:impl_log4j',
   '//lib/log:log4j',
+  '@jgit//:jgit',
+  '@jgit//:junit',
 ]
 
 TESTUTIL = glob([
diff --git a/gerrit-sshd/BUCK b/gerrit-sshd/BUCK
index 457f12e..fa45746 100644
--- a/gerrit-sshd/BUCK
+++ b/gerrit-sshd/BUCK
@@ -28,8 +28,8 @@
     '//lib/log:log4j',
     '//lib/mina:core',
     '//lib/mina:sshd',
-    '//lib/jgit:jgit',
-    '//lib/jgit:jgit-archive',
+    '@jgit//:jgit',
+    '@jgit//:jgit-archive',
   ],
   provided_deps = [
     '//lib/bouncycastle:bcpkix',
diff --git a/gerrit-util-http/BUCK b/gerrit-util-http/BUCK
index e9b2a3d..328e7a4 100644
--- a/gerrit-util-http/BUCK
+++ b/gerrit-util-http/BUCK
@@ -15,7 +15,7 @@
     '//lib:guava',
     '//lib:servlet-api-3_1',
     '//lib/httpcomponents:httpclient',
-    '//lib/jgit:jgit',
+    '@jgit//:jgit',
   ],
   visibility = ['PUBLIC'],
 )
diff --git a/gerrit-war/BUCK b/gerrit-war/BUCK
index d5c85ad..71ce2c6 100644
--- a/gerrit-war/BUCK
+++ b/gerrit-war/BUCK
@@ -24,7 +24,7 @@
     '//lib/guice:guice',
     '//lib/guice:guice-servlet',
     '//lib/log:api',
-    '//lib/jgit:jgit',
+    '@jgit//:jgit',
   ],
   provided_deps = ['//lib:servlet-api-3_1'],
   visibility = [
diff --git a/lib/BUCK b/lib/BUCK
index cb6e65d..d6a8015 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -249,7 +249,7 @@
   sha1 = '18a9a2ce6abf32ea1b5fd31dae5210ad93f4e5e3',
   license = 'xz',
   attach_source = False,
-  visibility = ['//lib/jgit:jgit-archive'],
+  visibility = ['//gerrit-server:server'],
 )
 
 maven_jar(
diff --git a/lib/jgit/.buckconfig b/lib/jgit/.buckconfig
new file mode 100644
index 0000000..267958f
--- /dev/null
+++ b/lib/jgit/.buckconfig
@@ -0,0 +1,3 @@
+[cache]
+  mode = dir
+  dir = ~/.gerritcodereview/buck-cache/locally-built-artifacts
diff --git a/lib/jgit/.gitignore b/lib/jgit/.gitignore
new file mode 100644
index 0000000..0a0ddb2
--- /dev/null
+++ b/lib/jgit/.gitignore
@@ -0,0 +1 @@
+/buck-out
diff --git a/lib/jgit/BUCK b/lib/jgit/BUCK
index 87d3b2c..bf3e2a8 100644
--- a/lib/jgit/BUCK
+++ b/lib/jgit/BUCK
@@ -39,16 +39,13 @@
   sha1 = 'e599670a9b163182868e2e928e44eb93c5d2b1ab',
   license = 'jgit',
   repository = REPO,
-  deps = [':jgit',
-    '//lib/commons:compress',
-    '//lib:tukaani-xz',
-  ],
+  deps = [':jgit'],
   unsign = True,
   exclude = [
     'about.html',
     'plugin.properties',
   ],
-)
+ )
 
 maven_jar(
   name = 'junit',
@@ -66,24 +63,3 @@
   sha1 = 'eceaf316a8faf0e794296ebe158ae110c7d72a5a',
   license = 'Apache2.0',
 )
-
-gwt_module(
-  name = 'Edit',
-  srcs = [':jgit_edit_src'],
-  deps = [':edit_src'],
-  visibility = ['PUBLIC'],
-)
-
-prebuilt_jar(
-  name = 'edit_src',
-  binary_jar = ':jgit_edit_src',
-)
-
-genrule(
-  name = 'jgit_edit_src',
-  cmd = 'unzip -qd $TMP $(location :jgit_src) ' +
-    'org/eclipse/jgit/diff/Edit.java;' +
-    'cd $TMP;' +
-    'zip -Dq $OUT org/eclipse/jgit/diff/Edit.java',
-  out = 'edit.src.zip',
-)
diff --git a/lib/jgit/lib/BUCK b/lib/jgit/lib/BUCK
new file mode 100644
index 0000000..fe0bbb1
--- /dev/null
+++ b/lib/jgit/lib/BUCK
@@ -0,0 +1,6 @@
+include_defs('//lib/maven.defs')
+
+define_license(name = 'Apache2.0')
+define_license(name = 'jgit')
+
+define_license(name = 'DO_NOT_DISTRIBUTE')
diff --git a/lib/jgit/lib/LICENSE-Apache2.0 b/lib/jgit/lib/LICENSE-Apache2.0
new file mode 120000
index 0000000..de5a79a
--- /dev/null
+++ b/lib/jgit/lib/LICENSE-Apache2.0
@@ -0,0 +1 @@
+../../LICENSE-Apache2.0
\ No newline at end of file
diff --git a/lib/jgit/lib/LICENSE-DO_NOT_DISTRIBUTE b/lib/jgit/lib/LICENSE-DO_NOT_DISTRIBUTE
new file mode 120000
index 0000000..6b0859b
--- /dev/null
+++ b/lib/jgit/lib/LICENSE-DO_NOT_DISTRIBUTE
@@ -0,0 +1 @@
+../../LICENSE-DO_NOT_DISTRIBUTE
\ No newline at end of file
diff --git a/lib/jgit/lib/LICENSE-jgit b/lib/jgit/lib/LICENSE-jgit
new file mode 120000
index 0000000..bfa3da5
--- /dev/null
+++ b/lib/jgit/lib/LICENSE-jgit
@@ -0,0 +1 @@
+../../LICENSE-jgit
\ No newline at end of file
diff --git a/lib/jgit/lib/maven.defs b/lib/jgit/lib/maven.defs
new file mode 120000
index 0000000..7f9292f
--- /dev/null
+++ b/lib/jgit/lib/maven.defs
@@ -0,0 +1 @@
+../../maven.defs
\ No newline at end of file
diff --git a/lib/jgit/tools/BUCK b/lib/jgit/tools/BUCK
new file mode 120000
index 0000000..7e536d7
--- /dev/null
+++ b/lib/jgit/tools/BUCK
@@ -0,0 +1 @@
+../../../tools/BUCK
\ No newline at end of file
diff --git a/lib/jgit/tools/__init__.py b/lib/jgit/tools/__init__.py
new file mode 120000
index 0000000..737f585
--- /dev/null
+++ b/lib/jgit/tools/__init__.py
@@ -0,0 +1 @@
+../../../tools/__init__.py
\ No newline at end of file
diff --git a/lib/jgit/tools/download_file.py b/lib/jgit/tools/download_file.py
new file mode 120000
index 0000000..e49dc4c
--- /dev/null
+++ b/lib/jgit/tools/download_file.py
@@ -0,0 +1 @@
+../../../tools/download_file.py
\ No newline at end of file
diff --git a/lib/jgit/tools/merge_jars.py b/lib/jgit/tools/merge_jars.py
new file mode 120000
index 0000000..399e418
--- /dev/null
+++ b/lib/jgit/tools/merge_jars.py
@@ -0,0 +1 @@
+../../../tools/merge_jars.py
\ No newline at end of file
diff --git a/lib/jgit/tools/pack_war.py b/lib/jgit/tools/pack_war.py
new file mode 120000
index 0000000..8621a6c
--- /dev/null
+++ b/lib/jgit/tools/pack_war.py
@@ -0,0 +1 @@
+../../../tools/pack_war.py
\ No newline at end of file
diff --git a/lib/jgit/tools/util.py b/lib/jgit/tools/util.py
new file mode 120000
index 0000000..8041ac5
--- /dev/null
+++ b/lib/jgit/tools/util.py
@@ -0,0 +1 @@
+../../../tools/util.py
\ No newline at end of file
diff --git a/lib/jgit/tools/util_test.py b/lib/jgit/tools/util_test.py
new file mode 120000
index 0000000..b85ecbd
--- /dev/null
+++ b/lib/jgit/tools/util_test.py
@@ -0,0 +1 @@
+../../../tools/util_test.py
\ No newline at end of file
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index d36e503..a156cd0 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -128,7 +128,8 @@
       continue
 
     m = java_library.match(p)
-    if m:
+    # Don't grab the cross-cell JGit libraries as source
+    if m and not m.group(1).startswith('org.eclipse.jgit'):
       src.add(m.group(1))
     else:
       lib.add(p)
diff --git a/tools/pack_war.py b/tools/pack_war.py
index ca21790..cd836a8 100755
--- a/tools/pack_war.py
+++ b/tools/pack_war.py
@@ -28,6 +28,7 @@
 
 war = args.tmp
 jars = set()
+basenames = set()
 
 def prune(l):
   return [j for e in l for j in e.split(':')]
@@ -36,10 +37,19 @@
   makedirs(directory)
   for j in libs:
     if j not in jars:
+      # When jgit is consumed from its own cell,
+      # potential duplicates should be filtered.
+      # e.g. jsch.jar will be reached through:
+      # 1. /home/username/projects/gerrit/buck-out/gen/lib/jsch.jar
+      # 2. /home/username/projects/jgit/buck-out/gen/lib/jsch.jar
+      if (j.find('jgit/buck-out/gen/lib') > 0
+          and path.basename(j) in basenames):
+          continue
       jars.add(j)
       n = path.basename(j)
       if j.find('buck-out/gen/gerrit-') > 0:
         n = j[j.find('buck-out'):].split('/')[2] + '-' + n
+      basenames.add(n)
       symlink(j, path.join(directory, n))
 
 if args.lib: