Support AutoValue
AutoValue[1] is a lightweight annotation-processor-based library for implementing classes with simple, obvious value semantics. Add support for AutoValue to build rules and Eclipse project generation. Buck does not currently have an officially-supported interface for specifying annotation processor dependencies[2], so we have to take the slightly ugly approach of monkey-patching java_library and java_test to add annotation processor arguments to each rule that requires annotation processing; hopefully this ugliness can be reduced in the future. [1] https://github.com/google/auto/tree/master/value [2] https://github.com/facebook/buck/issues/85 Change-Id: I8b49d6f9f25d61688b667d964848c6ce106ae4ec
This commit is contained in:
		
				
					committed by
					
						
						Shawn Pearce
					
				
			
			
				
	
			
			
			
						parent
						
							f4893d3d42
						
					
				
				
					commit
					08180de4de
				
			
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,6 @@
 | 
				
			|||||||
 | 
					/.apt_generated
 | 
				
			||||||
/.classpath
 | 
					/.classpath
 | 
				
			||||||
 | 
					/.factorypath
 | 
				
			||||||
/.project
 | 
					/.project
 | 
				
			||||||
/.settings/org.maven.ide.eclipse.prefs
 | 
					/.settings/org.maven.ide.eclipse.prefs
 | 
				
			||||||
/.settings/org.eclipse.m2e.core.prefs
 | 
					/.settings/org.eclipse.m2e.core.prefs
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,6 +89,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
 | 
				
			|||||||
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
 | 
					org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
 | 
				
			||||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 | 
					org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 | 
				
			||||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
 | 
					org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.processAnnotations=enabled
 | 
				
			||||||
org.eclipse.jdt.core.compiler.source=1.7
 | 
					org.eclipse.jdt.core.compiler.source=1.7
 | 
				
			||||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 | 
					org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 | 
				
			||||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 | 
					org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,9 +55,12 @@ java_library(
 | 
				
			|||||||
  visibility = ['PUBLIC'],
 | 
					  visibility = ['PUBLIC'],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST = 'src/test/java/com/google/gerrit/common/'
 | 
				
			||||||
 | 
					AUTO_VALUE_TEST_SRCS = [TEST + 'AutoValueTest.java']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
java_test(
 | 
					java_test(
 | 
				
			||||||
  name = 'client_tests',
 | 
					  name = 'client_tests',
 | 
				
			||||||
  srcs = glob(['src/test/java/**/*.java']),
 | 
					  srcs = glob(['src/test/java/**/*.java'], excludes = AUTO_VALUE_TEST_SRCS),
 | 
				
			||||||
  deps = [
 | 
					  deps = [
 | 
				
			||||||
    ':client',
 | 
					    ':client',
 | 
				
			||||||
    '//lib:guava',
 | 
					    '//lib:guava',
 | 
				
			||||||
@@ -65,3 +68,14 @@ java_test(
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  source_under_test = [':client'],
 | 
					  source_under_test = [':client'],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					java_test(
 | 
				
			||||||
 | 
					  name = 'auto_value_tests',
 | 
				
			||||||
 | 
					  srcs = AUTO_VALUE_TEST_SRCS,
 | 
				
			||||||
 | 
					  deps = [
 | 
				
			||||||
 | 
					    '//lib:guava',
 | 
				
			||||||
 | 
					    '//lib:junit',
 | 
				
			||||||
 | 
					    '//lib:truth',
 | 
				
			||||||
 | 
					    '//lib/auto:auto-value',
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2014 The Android Open Source Project
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					// you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					// You may obtain a copy of the License at
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package com.google.gerrit.common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static com.google.common.truth.Truth.assertThat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.auto.value.AutoValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class AutoValueTest {
 | 
				
			||||||
 | 
					  @AutoValue
 | 
				
			||||||
 | 
					  abstract static class Auto {
 | 
				
			||||||
 | 
					    static Auto create(String val) {
 | 
				
			||||||
 | 
					      return new AutoValue_AutoValueTest_Auto(val);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    abstract String val();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Test
 | 
				
			||||||
 | 
					  public void autoValue() {
 | 
				
			||||||
 | 
					    Auto a = Auto.create("foo");
 | 
				
			||||||
 | 
					    assertThat(a.val()).isEqualTo("foo");
 | 
				
			||||||
 | 
					    assertThat(a.toString()).isEqualTo("Auto{val=foo}");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								lib/auto/BUCK
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lib/auto/BUCK
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					include_defs('//lib/maven.defs')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# TODO(dborowitz): All rules but auto-value are public only because of the hacky
 | 
				
			||||||
 | 
					# way we have to include them via auto_value.defs.
 | 
				
			||||||
 | 
					maven_jar(
 | 
				
			||||||
 | 
					  name = 'auto-common',
 | 
				
			||||||
 | 
					  id = 'com.google.auto:auto-common:0.3',
 | 
				
			||||||
 | 
					  sha1 = '4073ab16ab4aceb9a217273da6442166bf51ae16',
 | 
				
			||||||
 | 
					  license = 'Apache2.0',
 | 
				
			||||||
 | 
					  deps = ['//lib:guava'],
 | 
				
			||||||
 | 
					  visibility = ['PUBLIC'],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					maven_jar(
 | 
				
			||||||
 | 
					  name = 'auto-service',
 | 
				
			||||||
 | 
					  id = 'com.google.auto.service:auto-service:1.0-rc2',
 | 
				
			||||||
 | 
					  sha1 = '51033a5b8fcf7039159e35b6878f106ccd5fb35f',
 | 
				
			||||||
 | 
					  license = 'Apache2.0',
 | 
				
			||||||
 | 
					  deps = [
 | 
				
			||||||
 | 
					    ':auto-common',
 | 
				
			||||||
 | 
					    '//lib:guava',
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  visibility = ['PUBLIC'],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					maven_jar(
 | 
				
			||||||
 | 
					  name = 'auto-value',
 | 
				
			||||||
 | 
					  id = 'com.google.auto.value:auto-value:1.0-rc2',
 | 
				
			||||||
 | 
					  sha1 = '73141b5aa77021f058d1a5391595d04ef17e8602',
 | 
				
			||||||
 | 
					  license = 'Apache2.0',
 | 
				
			||||||
 | 
					  deps = [
 | 
				
			||||||
 | 
					    ':auto-common',
 | 
				
			||||||
 | 
					    ':auto-service',
 | 
				
			||||||
 | 
					    '//lib:guava',
 | 
				
			||||||
 | 
					    '//lib:velocity',
 | 
				
			||||||
 | 
					    '//lib/ow2:ow2-asm',
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  visibility = ['PUBLIC'],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										25
									
								
								lib/auto/auto_value.defs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/auto/auto_value.defs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					# NOTE: Do not use this file in your build rules; automatically supported by
 | 
				
			||||||
 | 
					# our implementation of java_library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AUTO_VALUE_DEP = '//lib/auto:auto-value'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Annotation processor classpath requires transitive dependencies.
 | 
				
			||||||
 | 
					# TODO(dborowitz): Clean this up when buck issue is closed and there is a
 | 
				
			||||||
 | 
					# better supported interface:
 | 
				
			||||||
 | 
					# https://github.com/facebook/buck/issues/85
 | 
				
			||||||
 | 
					AUTO_VALUE_PROCESSOR_DEPS = [
 | 
				
			||||||
 | 
					  '//lib:guava',
 | 
				
			||||||
 | 
					  '//lib:velocity',
 | 
				
			||||||
 | 
					  '//lib/auto:auto-common',
 | 
				
			||||||
 | 
					  '//lib/auto:auto-service',
 | 
				
			||||||
 | 
					  '//lib/auto:auto-value',
 | 
				
			||||||
 | 
					  '//lib/commons:collections',
 | 
				
			||||||
 | 
					  '//lib/commons:lang',
 | 
				
			||||||
 | 
					  '//lib/commons:oro',
 | 
				
			||||||
 | 
					  '//lib/ow2:ow2-asm',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AUTO_VALUE_PROCESSORS = [
 | 
				
			||||||
 | 
					  'com.google.auto.value.processor.AutoAnnotationProcessor',
 | 
				
			||||||
 | 
					  'com.google.auto.value.processor.AutoValueProcessor',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
@@ -14,11 +14,39 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Rule definitions loaded by default into every BUCK file.
 | 
					# Rule definitions loaded by default into every BUCK file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include_defs('//lib/auto/auto_value.defs')
 | 
				
			||||||
include_defs('//tools/gwt-constants.defs')
 | 
					include_defs('//tools/gwt-constants.defs')
 | 
				
			||||||
include_defs('//tools/java_doc.defs')
 | 
					include_defs('//tools/java_doc.defs')
 | 
				
			||||||
include_defs('//tools/java_sources.defs')
 | 
					include_defs('//tools/java_sources.defs')
 | 
				
			||||||
import copy
 | 
					import copy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add AutoValue support to java_library.
 | 
				
			||||||
 | 
					_buck_java_library = java_library
 | 
				
			||||||
 | 
					def java_library(*args, **kwargs):
 | 
				
			||||||
 | 
					  _set_auto_value(kwargs)
 | 
				
			||||||
 | 
					  _buck_java_library(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add AutoValue support to java_test.
 | 
				
			||||||
 | 
					_buck_java_test = java_test
 | 
				
			||||||
 | 
					def java_test(*args, **kwargs):
 | 
				
			||||||
 | 
					  _set_auto_value(kwargs)
 | 
				
			||||||
 | 
					  _buck_java_test(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _set_auto_value(kwargs):
 | 
				
			||||||
 | 
					  apk = 'annotation_processors'
 | 
				
			||||||
 | 
					  if apk not in kwargs:
 | 
				
			||||||
 | 
					    kwargs[apk] = []
 | 
				
			||||||
 | 
					  aps = kwargs.get(apk, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  apdk = 'annotation_processor_deps'
 | 
				
			||||||
 | 
					  if apdk not in kwargs:
 | 
				
			||||||
 | 
					    kwargs[apdk] = []
 | 
				
			||||||
 | 
					  apds = kwargs.get(apdk, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AUTO_VALUE_DEP in kwargs.get('deps', []):
 | 
				
			||||||
 | 
					    aps.extend(AUTO_VALUE_PROCESSORS)
 | 
				
			||||||
 | 
					    apds.extend(AUTO_VALUE_PROCESSOR_DEPS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def genantlr(
 | 
					def genantlr(
 | 
				
			||||||
    name,
 | 
					    name,
 | 
				
			||||||
    srcs,
 | 
					    srcs,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ java_library(
 | 
				
			|||||||
    '//gerrit-server:server_tests',
 | 
					    '//gerrit-server:server_tests',
 | 
				
			||||||
    '//lib/asciidoctor:asciidoc_lib',
 | 
					    '//lib/asciidoctor:asciidoc_lib',
 | 
				
			||||||
    '//lib/asciidoctor:doc_indexer_lib',
 | 
					    '//lib/asciidoctor:doc_indexer_lib',
 | 
				
			||||||
 | 
					    '//lib/auto:auto-value',
 | 
				
			||||||
    '//lib/bouncycastle:bcprov',
 | 
					    '//lib/bouncycastle:bcprov',
 | 
				
			||||||
    '//lib/bouncycastle:bcpg',
 | 
					    '//lib/bouncycastle:bcpg',
 | 
				
			||||||
    '//lib/bouncycastle:bcpkix',
 | 
					    '//lib/bouncycastle:bcpkix',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,17 @@ opts.add_option('--plugins', help='create eclipse projects for plugins',
 | 
				
			|||||||
                action='store_true')
 | 
					                action='store_true')
 | 
				
			||||||
args, _ = opts.parse_args()
 | 
					args, _ = opts.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _query_classpath(targets):
 | 
				
			||||||
 | 
					  deps = []
 | 
				
			||||||
 | 
					  p = Popen(['buck', 'audit', 'classpath'] + targets, stdout=PIPE)
 | 
				
			||||||
 | 
					  for line in p.stdout:
 | 
				
			||||||
 | 
					    deps.append(line.strip())
 | 
				
			||||||
 | 
					  s = p.wait()
 | 
				
			||||||
 | 
					  if s != 0:
 | 
				
			||||||
 | 
					    exit(s)
 | 
				
			||||||
 | 
					  return deps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def gen_project(name='gerrit', dir=ROOT):
 | 
					def gen_project(name='gerrit', dir=ROOT):
 | 
				
			||||||
  p = path.join(dir, '.project')
 | 
					  p = path.join(dir, '.project')
 | 
				
			||||||
  with open(p, 'w') as fd:
 | 
					  with open(p, 'w') as fd:
 | 
				
			||||||
@@ -76,17 +87,8 @@ def gen_plugin_classpath(dir):
 | 
				
			|||||||
  <classpathentry combineaccessrules="false" kind="src" path="/gerrit"/>
 | 
					  <classpathentry combineaccessrules="false" kind="src" path="/gerrit"/>
 | 
				
			||||||
  <classpathentry kind="output" path="buck-out/eclipse/classes"/>
 | 
					  <classpathentry kind="output" path="buck-out/eclipse/classes"/>
 | 
				
			||||||
</classpath>""" % {"testpath": testpath}, file=fd)
 | 
					</classpath>""" % {"testpath": testpath}, file=fd)
 | 
				
			||||||
def gen_classpath():
 | 
					 | 
				
			||||||
  def query_classpath(targets):
 | 
					 | 
				
			||||||
    deps = []
 | 
					 | 
				
			||||||
    p = Popen(['buck', 'audit', 'classpath'] + targets, stdout=PIPE)
 | 
					 | 
				
			||||||
    for line in p.stdout:
 | 
					 | 
				
			||||||
      deps.append(line.strip())
 | 
					 | 
				
			||||||
    s = p.wait()
 | 
					 | 
				
			||||||
    if s != 0:
 | 
					 | 
				
			||||||
      exit(s)
 | 
					 | 
				
			||||||
    return deps
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def gen_classpath():
 | 
				
			||||||
  def make_classpath():
 | 
					  def make_classpath():
 | 
				
			||||||
    impl = minidom.getDOMImplementation()
 | 
					    impl = minidom.getDOMImplementation()
 | 
				
			||||||
    return impl.createDocument(None, 'classpath', None)
 | 
					    return impl.createDocument(None, 'classpath', None)
 | 
				
			||||||
@@ -111,7 +113,7 @@ def gen_classpath():
 | 
				
			|||||||
  plugins = set()
 | 
					  plugins = set()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  java_library = re.compile(r'[^/]+/gen/(.*)/lib__[^/]+__output/[^/]+[.]jar$')
 | 
					  java_library = re.compile(r'[^/]+/gen/(.*)/lib__[^/]+__output/[^/]+[.]jar$')
 | 
				
			||||||
  for p in query_classpath(MAIN):
 | 
					  for p in _query_classpath(MAIN):
 | 
				
			||||||
    if p.endswith('-src.jar'):
 | 
					    if p.endswith('-src.jar'):
 | 
				
			||||||
      # gwt_module() depends on -src.jar for Java to JavaScript compiles.
 | 
					      # gwt_module() depends on -src.jar for Java to JavaScript compiles.
 | 
				
			||||||
      gwt_lib.add(p)
 | 
					      gwt_lib.add(p)
 | 
				
			||||||
@@ -130,7 +132,7 @@ def gen_classpath():
 | 
				
			|||||||
    else:
 | 
					    else:
 | 
				
			||||||
      lib.add(p)
 | 
					      lib.add(p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for p in query_classpath(GWT):
 | 
					  for p in _query_classpath(GWT):
 | 
				
			||||||
    m = java_library.match(p)
 | 
					    m = java_library.match(p)
 | 
				
			||||||
    if m:
 | 
					    if m:
 | 
				
			||||||
      gwt_src.add(m.group(1))
 | 
					      gwt_src.add(m.group(1))
 | 
				
			||||||
@@ -195,6 +197,20 @@ def gen_classpath():
 | 
				
			|||||||
        print('error generating project for %s: %s' % (plugin, err),
 | 
					        print('error generating project for %s: %s' % (plugin, err),
 | 
				
			||||||
              file=sys.stderr)
 | 
					              file=sys.stderr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def gen_factorypath():
 | 
				
			||||||
 | 
					  doc = minidom.getDOMImplementation().createDocument(None, 'factorypath', None)
 | 
				
			||||||
 | 
					  for jar in _query_classpath(['//lib/auto:auto-value']):
 | 
				
			||||||
 | 
					    e = doc.createElement('factorypathentry')
 | 
				
			||||||
 | 
					    e.setAttribute('kind', 'EXTJAR')
 | 
				
			||||||
 | 
					    e.setAttribute('id', path.join(ROOT, jar))
 | 
				
			||||||
 | 
					    e.setAttribute('enabled', 'true')
 | 
				
			||||||
 | 
					    e.setAttribute('runInBatchMode', 'false')
 | 
				
			||||||
 | 
					    doc.documentElement.appendChild(e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  p = path.join(ROOT, '.factorypath')
 | 
				
			||||||
 | 
					  with open(p, 'w') as fd:
 | 
				
			||||||
 | 
					    doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
  if args.src:
 | 
					  if args.src:
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
@@ -204,6 +220,7 @@ try:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  gen_project()
 | 
					  gen_project()
 | 
				
			||||||
  gen_classpath()
 | 
					  gen_classpath()
 | 
				
			||||||
 | 
					  gen_factorypath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  try:
 | 
					  try:
 | 
				
			||||||
    targets = ['//tools:buck.properties'] + MAIN + GWT
 | 
					    targets = ['//tools:buck.properties'] + MAIN + GWT
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user