From 29839c97b7a31af2a97dcea4569c2167de962cdd Mon Sep 17 00:00:00 2001 From: adriancole Date: Sat, 17 Aug 2013 15:20:28 -0700 Subject: [PATCH] added dagger IDE setup for annotation parsing via gradle idea and eclipse plugins --- .gitignore | 2 + build.gradle | 9 +-- dagger.gradle | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 dagger.gradle diff --git a/.gitignore b/.gitignore index 5b07c032..7adeb751 100644 --- a/.gitignore +++ b/.gitignore @@ -63,6 +63,8 @@ atlassian-ide-plugin.xml .project .settings .metadata +.factorypath +.generated # NetBeans specific files/directories .nbattrs diff --git a/build.gradle b/build.gradle index df7ad91b..7168bfff 100644 --- a/build.gradle +++ b/build.gradle @@ -22,8 +22,10 @@ apply from: file('gradle/maven.gradle') apply from: file('gradle/check.gradle') apply from: file('gradle/license.gradle') apply from: file('gradle/release.gradle') +apply plugin: 'idea' subprojects { + apply from: rootProject.file('dagger.gradle') group = "com.netflix.${githubProjectName}" // TEMPLATE: Set to organization of project } @@ -35,8 +37,6 @@ project(':feign-core') { } dependencies { - compile 'com.squareup.dagger:dagger:1.1.0' - provided 'com.squareup.dagger:dagger-compiler:1.1.0' testCompile 'com.google.guava:guava:14.0.1' testCompile 'com.google.code.gson:gson:2.2.4' testCompile 'com.fasterxml.jackson.core:jackson-databind:2.2.2' @@ -55,7 +55,6 @@ project(':feign-gson') { dependencies { compile project(':feign-core') compile 'com.google.code.gson:gson:2.2.4' - provided 'com.squareup.dagger:dagger-compiler:1.1.0' testCompile 'org.testng:testng:6.8.5' } } @@ -70,9 +69,6 @@ project(':feign-jaxrs') { dependencies { compile project(':feign-core') compile 'javax.ws.rs:jsr311-api:1.1.1' - provided 'com.squareup.dagger:dagger-compiler:1.1.0' - // for example classes - testCompile project(':feign-core').sourceSets.test.output testCompile project(':feign-gson') testCompile 'com.google.guava:guava:14.0.1' testCompile 'org.testng:testng:6.8.5' @@ -89,7 +85,6 @@ project(':feign-ribbon') { dependencies { compile project(':feign-core') compile 'com.netflix.ribbon:ribbon-core:0.2.0' - provided 'com.squareup.dagger:dagger-compiler:1.1.0' testCompile 'org.testng:testng:6.8.5' testCompile 'com.google.mockwebserver:mockwebserver:20130706' } diff --git a/dagger.gradle b/dagger.gradle new file mode 100644 index 00000000..59996026 --- /dev/null +++ b/dagger.gradle @@ -0,0 +1,178 @@ +// Manages classpath and IDE annotation processing config for dagger. +// +// setup: +// Add the following to your root build.gradle +// +// apply plugin: 'idea' +// subprojects { +// apply from: rootProject.file('dagger.gradle') +// } +// +// do not use gradle integration of the ide. instead generate and import like so: +// +// ./gradlew clean cleanEclipse cleanIdea eclipse idea +// +// known limitations: +// as output folders include generated classes, you may need to run clean a few times. +// incompatible with android plugin as it applies the java plugin +// unnecessarily applies both eclipse and idea plugins even if you don't use them +// suffers from the normal non-IDE eclipse integration where nested projects don't import properly. +// change your structure to flattened to avoid this. +// +// deprecated by: https://github.com/Netflix/gradle-template/issues/8 +// +// original design: cfieber +apply plugin: 'java' +apply plugin: 'eclipse' +apply plugin: 'idea' + +if (!project.hasProperty('daggerVersion')) { + ext { + daggerVersion = "1.1.0" + } +} + +configurations { + daggerCompiler { + visible false + } +} + +configurations.all { + resolutionStrategy { + eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'com.squareup.dagger') { + details.useVersion daggerVersion + } + } + } +} + +def annotationGeneratedSources = file('.generated/src') +def annotationGeneratedTestSources = file('.generated/test') + +task prepareAnnotationGeneratedSourceDirs(overwrite: true) << { + annotationGeneratedSources.mkdirs() + annotationGeneratedTestSources.mkdirs() + sourceSets*.java.srcDirs*.each { it.mkdirs() } + sourceSets*.resources.srcDirs*.each { it.mkdirs() } +} + +sourceSets { + main { + java { + compileClasspath += configurations.daggerCompiler + } + } + test { + java { + compileClasspath += configurations.daggerCompiler + } + } +} + +dependencies { + compile "com.squareup.dagger:dagger:${project.daggerVersion}" + daggerCompiler "com.squareup.dagger:dagger-compiler:${project.daggerVersion}" +} + +rootProject.idea.project.ipr.withXml { projectXml -> + projectXml.asNode().component.find { it.@name == 'CompilerConfiguration' }.annotationProcessing[0].replaceNode { + annotationProcessing { + profile(default: true, name: 'Default', enabled: true) { + sourceOutputDir name: relativePath(annotationGeneratedSources) + sourceTestOutputDir name: relativePath(annotationGeneratedTestSources) + outputRelativeToContentRoot value: true + processorPath useClasspath: true + } + } + } +} + +tasks.ideaModule.dependsOn(prepareAnnotationGeneratedSourceDirs) + +idea.module { + scopes.PROVIDED.plus += project.configurations.daggerCompiler + iml.withXml { xml-> + def moduleSource = xml.asNode().component.find { it.@name = 'NewModuleRootManager' }.content[0] + moduleSource.appendNode('sourceFolder', [url: "file://\$MODULE_DIR\$/${relativePath(annotationGeneratedSources)}", isTestSource: false]) + moduleSource.appendNode('sourceFolder', [url: "file://\$MODULE_DIR\$/${relativePath(annotationGeneratedTestSources)}", isTestSource: true]) + } +} + +tasks.eclipseClasspath.dependsOn(prepareAnnotationGeneratedSourceDirs) + +eclipse.classpath { + plusConfigurations += project.configurations.daggerCompiler +} + +tasks.eclipseClasspath { + doLast { + eclipse.classpath.file.withXml { + it.asNode().children()[0] + { + classpathentry(kind: 'src', path: relativePath(annotationGeneratedSources)) { + attributes { + attribute name: 'optional', value: true + } + } + } + } + } +} + +// http://forums.gradle.org/gradle/topics/eclipse_generated_files_should_be_put_in_the_same_place_as_the_gradle_generated_files +Map pathMappings = [:]; +SourceSetContainer sourceSets = project.sourceSets; +sourceSets.each { SourceSet sourceSet -> + String relativeJavaOutputDirectory = project.relativePath(sourceSet.output.classesDir); + String relativeResourceOutputDirectory = project.relativePath(sourceSet.output.resourcesDir); + sourceSet.java.getSrcDirTrees().each { DirectoryTree sourceDirectory -> + String relativeSrcPath = project.relativePath(sourceDirectory.dir.absolutePath); + + pathMappings[relativeSrcPath] = relativeJavaOutputDirectory; + } + sourceSet.resources.getSrcDirTrees().each { DirectoryTree resourceDirectory -> + String relativeResourcePath = project.relativePath(resourceDirectory.dir.absolutePath); + + pathMappings[relativeResourcePath] = relativeResourceOutputDirectory; + } +} + +project.eclipse.classpath.file { + whenMerged { classpath -> + classpath.entries.findAll { entry -> + return entry.kind == 'src'; + }.each { entry -> + if(pathMappings.containsKey(entry.path)) { + entry.output = pathMappings[entry.path]; + } + } + } +} + +eclipse.jdt.file.withProperties { props -> + props.setProperty('org.eclipse.jdt.core.compiler.processAnnotations', 'enabled') +} + +tasks.eclipseJdt { + doFirst { + def aptPrefs = file('.settings/org.eclipse.jdt.apt.core.prefs') + aptPrefs.parentFile.mkdirs() + + aptPrefs.text = """\ + eclipse.preferences.version=1 + org.eclipse.jdt.apt.aptEnabled=true + org.eclipse.jdt.apt.genSrcDir=${relativePath(annotationGeneratedSources)} + org.eclipse.jdt.apt.reconcileEnabled=true + """.stripIndent() + + file('.factorypath').withWriter { + new groovy.xml.MarkupBuilder(it).'factorypath' { + project.configurations.daggerCompiler.files.each { dep -> + 'factorypathentry' kind: 'EXTJAR', id: dep.absolutePath, enabled: true, runInBatchMode: false + } + } + } + } +} +