// 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 } } } } }