-
-
Save chrisfesler/1756062 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.gradle.api.DefaultTask | |
import org.gradle.api.Project | |
import org.gradle.api.plugins.BasePlugin | |
/** | |
* apply this plugin after doing all dependency and repo stuff. It will create two idea 'libraries' per subproject | |
* and add them to your .iml files | |
* | |
* Forked from https://gist.github.com/360092 | |
* | |
* Plugin-ified and made to support multiple modules per root build.gradle and multiple build.gradles per idea project. | |
*/ | |
class IntelliJSync extends BasePlugin { | |
def sep = File.separator | |
@Override | |
void apply(Project project) { | |
configureIntellijSync(project) | |
configureIntellijLibrarySync(project) | |
configureIntellijModuleSync(project) | |
} | |
def configureIntellijSync(Project project) { | |
project.tasks.add('intellijSync', DefaultTask.class).with { | |
description = "Sync libraries and modules with gradle dependencies" | |
dependsOn 'intellijLibrarySync' | |
dependsOn 'intellijModuleSync' | |
} | |
} | |
def configureIntellijLibrarySync(Project project) { | |
project.tasks.add('intellijLibrarySync', DefaultTask.class).with { | |
description = "Add gradle dependecies to IntelliJ project libraries in ${findIdeaLibrariesDir()}" | |
doLast { | |
final File librariesDir = findIdeaLibrariesDir() | |
librariesDir.mkdirs() | |
final def userHomeGradle = project.gradle.gradleUserHomeDir | |
logger.info("In IDEA's settings->path variables, ensure that USER_HOME_GRADLE is set to '$userHomeGradle.path'") | |
def makeJarList = { path -> | |
path.split(File.pathSeparator).collect { | |
it.replaceAll userHomeGradle.path, "\\\$USER_HOME_GRADLE\\\$" | |
} | |
} | |
final def compileJars = makeJarList(project.configurations.compile.asPath) | |
final def testJars = makeJarList(project.configurations.testCompile.asPath) - compileJars | |
def createLibrary = { fileName, libraryName, jars -> | |
final def gradleLibXml = new File(librariesDir, fileName) | |
gradleLibXml.write """ | |
<component name="libraryTable"> | |
<library name="$libraryName"/> | |
</component>""" | |
final def xmlRoot = new XmlParser().parse(gradleLibXml) | |
final def classesNode = xmlRoot.library[0].appendNode('CLASSES') | |
jars.each { jar -> | |
classesNode.appendNode('root', [url: "jar://$jar!/"]) | |
} | |
def writer = new StringWriter() | |
new XmlNodePrinter(new PrintWriter(writer)).print(xmlRoot) | |
gradleLibXml.write writer.toString() | |
logger.info("File '${gradleLibXml.canonicalPath}' updated") | |
} | |
createLibrary libFile(project), libName(project), compileJars | |
createLibrary testFile(project), testName(project), testJars | |
} | |
} | |
} | |
def configureIntellijModuleSync(Project project) { | |
project.tasks.add('intellijModuleSync', DefaultTask.class).with { | |
description = "Add to generated project libraries to IntelliJ .iml files" | |
doLast { | |
final def moduleFile = new File("${project.name}.iml") | |
if (moduleFile.exists()) { | |
def root = new XmlParser().parse(moduleFile) | |
def newModuleRootManager = root.component.find {it.'@name' == 'NewModuleRootManager'} | |
// find and remove old entries for test and lib | |
[libName(project), testName(project)].each { orderEntryName -> | |
def orderEntry = newModuleRootManager.orderEntry.find { | |
it.'@type' == 'library' && it.'@name' == orderEntryName | |
} | |
if (orderEntry) { | |
newModuleRootManager.remove(orderEntry) | |
} | |
} | |
// make the new entries | |
newModuleRootManager.appendNode('orderEntry', [type: 'library', scope: 'TEST', name: testName(project), level: 'project']) | |
newModuleRootManager.appendNode('orderEntry', [type: 'library', exported: '', name: libName(project), level: 'project']) | |
def writer = new StringWriter() | |
new XmlNodePrinter(new PrintWriter(writer)).print(root) | |
moduleFile.write writer.toString() | |
logger.info("File '${moduleFile.canonicalPath}' updated") | |
} | |
else { | |
logger.info("skipping module ${moduleFile}") | |
} | |
} | |
} | |
} | |
// //////////////////////// | |
// MINIONS | |
// //////////////////////// | |
def libName(Project project) { | |
"${project.name} Gradle Libs" | |
} | |
def libFile(Project project) { | |
toFile(libName(project)) | |
} | |
def testName(Project project) { | |
"${project.name} Gradle Test Libs" | |
} | |
def testFile(Project project) { | |
toFile(testName(project)) | |
} | |
def toFile(String libName) { | |
libName.replace(' ', "_") + ".xml" | |
} | |
def findIdeaLibrariesDir() { | |
// walk up the current path, looking for .idea/workspace.xml, rather than simply using .idea in the current | |
// directory. This is to support cases where one idea project contains multiple root-level build.gradle files | |
def start = new File(".") | |
def dotIdea = findDotIdea(start) | |
if (!dotIdea) { | |
// we tried -- no pre-existing .idea project file above us. We'll just suppose that it hasn't been created yet, and | |
// belongs in the current directory. | |
dotIdea = start | |
} | |
new File("${dotIdea}${sep}libraries") | |
} | |
def findDotIdea(File ideaProjectRoot) { | |
// use canonicalPath to ensure .parent works reliably. | |
ideaProjectRoot = new File(ideaProjectRoot.canonicalPath) | |
// for back-compatibility, look for a .idea/workspace.xml, not just .idea | |
File dotIdea = new File("${ideaProjectRoot.path}${sep}.idea") | |
File workspace = new File("${dotIdea.path}${sep}workspace.xml") | |
if (workspace.exists()) { | |
dotIdea | |
} | |
else if (ideaProjectRoot.parent) { | |
findDotIdea(new File(ideaProjectRoot.parent)) | |
} | |
else { | |
null | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment