diff options
Diffstat (limited to 'scalaplugin')
-rw-r--r-- | scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala | 205 |
1 files changed, 118 insertions, 87 deletions
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala b/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala index b756d227..c503aae7 100644 --- a/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala +++ b/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala @@ -1,13 +1,23 @@ package mill.scalaplugin -import ammonite.ops.{Path, pwd, rm, write} +import ammonite.ops._ import mill.discover.{Discovered, Hierarchy} import mill.eval.{Evaluator, PathRef} import mill.util.OSet object GenIdea { - def apply[T: Discovered](obj: T) = { + + def apply[T: Discovered](obj: T): Unit = { val pp = new scala.xml.PrettyPrinter(999, 4) + rm! pwd/".idea" + rm! pwd/".idea_modules" + + for((relPath, xml) <- xmlFileLayout(obj)){ + write(pwd/relPath, pp.format(xml)) + } + } + + def xmlFileLayout[T: Discovered](obj: T): Seq[(RelPath, scala.xml.Node)] = { val discovered = implicitly[Discovered[T]] def rec(x: Hierarchy[T]): Seq[(Seq[String], Module)] = { val node = x.node(obj) @@ -23,48 +33,27 @@ object GenIdea { val evaluator = new Evaluator(workspacePath, mapping) val modules = rec(discovered.hierarchy) - println(modules) - - rm! pwd/".idea" - rm! pwd/".idea_modules" - val moduleDir = pwd/".idea_modules" - write( - pwd/".idea"/"misc.xml", - pp.format( - <project version="4"> - <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8 (1)" project-jdk-type="JavaSDK"> - <output url="file://$PROJECT_DIR$/target/idea_output" /> - </component> - </project> - ) - ) - val allModulesFile = - <project version="4"> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/.idea_modules/root.iml" filepath="$PROJECT_DIR$/.idea_modules/root.iml" /> - { - for((path, mod) <- modules) - yield { - val selector = path.mkString(".") - val filepath = "$PROJECT_DIR$/.idea_modules/" + selector.toLowerCase() + ".iml" - val fileurl = "file://" + filepath - <module fileurl={fileurl} filepath={filepath} /> - } - } - </modules> - </component> - </project> - - write(pwd/".idea"/"modules.xml", pp.format(allModulesFile)) val resolved = for((path, mod) <- modules) yield { val Seq(resolvedCp: Seq[PathRef], resolvedSrcs: Seq[PathRef]) = evaluator.evaluate(OSet(mod.externalCompileDepClasspath, mod.externalCompileDepSources)) .values - (path, resolvedCp.map(_.path).filter(_.ext == "jar") ++ resolvedSrcs.map(_.path), mod) } + val moduleLabels = modules.map(_.swap).toMap + + val fixedFiles = Seq( + Tuple2(".idea"/"misc.xml", miscXmlTemplate()), + Tuple2( + ".idea"/"modules.xml", + modulesXmlTemplate( + for((path, mod) <- modules) + yield path.mkString(".").toLowerCase + ) + ), + Tuple2(".idea_modules"/"root.iml", rootXmlTemplate()) + ) + val allResolved = resolved.flatMap(_._2).distinct val minResolvedLength = allResolved.map(_.segments.length).min val commonPrefix = allResolved.map(_.segments.take(minResolvedLength)) @@ -72,64 +61,106 @@ object GenIdea { .takeWhile(_.distinct.length == 1) .length - val libraryFiles = for(path <- allResolved) yield { + val pathToLibName = allResolved + .map{p => (p, p.segments.drop(commonPrefix).mkString("_"))} + .toMap + + val libraries = allResolved.map{path => val url = "jar://" + path + "!/" - val name = path.segments.drop(commonPrefix).mkString("_") - val elem = <component name="libraryTable"> - <library name={name}> - <CLASSES> - <root url={url}/> - </CLASSES> - </library> - </component> - write(pwd/".idea"/'libraries/s"$name.xml", pp.format(elem)) + val name = pathToLibName(path) + Tuple2(".idea"/'libraries/s"$name.xml", libraryXmlTemplate(name, url)) } - def relify(p: Path) = { - val r = p.relativeTo(moduleDir) - (Seq.fill(r.ups)("..") ++ r.segments).mkString("/") + val moduleFiles = resolved.map{ case (path, resolvedDeps, mod) => + val Seq(sourcePath: PathRef, outputPath: PathRef) = + evaluator.evaluate(OSet(mod.sources, mod.compile)).values + + val elem = moduleXmlTemplate( + sourcePath.path, + outputPath.path, + resolvedDeps.map(pathToLibName), + for(m <- mod.projectDeps) + yield moduleLabels(m).mkString(".").toLowerCase + ) + Tuple2(".idea_modules"/s"${path.mkString(".").toLowerCase}.iml", elem) } - val moduleFiles = for((path, resolvedDeps, mod) <- resolved) yield { - val sourcePath = evaluator.evaluate(OSet(mod.sources)).values.head.asInstanceOf[PathRef].path - val outputPath = evaluator.evaluate(OSet(mod.compile)).values.head.asInstanceOf[PathRef].path - val base = mod.getClass.getName.stripSuffix("$").split('.').last.split('$').last.toLowerCase - val elem = <module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager"> - <output url={"file://$MODULE_DIR$/" + relify(outputPath)} /> - <exclude-output /> - <content url={"file://$MODULE_DIR$/" + relify(sourcePath)}> - <sourceFolder url={"file://$MODULE_DIR$/" + relify(sourcePath)} isTestSource="false" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> + fixedFiles ++ libraries ++ moduleFiles + } + + def relify(p: Path) = { + val r = p.relativeTo(pwd/".idea_modules") + (Seq.fill(r.ups)("..") ++ r.segments).mkString("/") + } + def miscXmlTemplate() = { + <project version="4"> + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8 (1)" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/target/idea_output"/> + </component> + </project> + } + + def modulesXmlTemplate(selectors: Seq[String]) = { + <project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea_modules/root.iml" filepath="$PROJECT_DIR$/.idea_modules/root.iml" /> { - for(r <- resolvedDeps) yield { - <orderEntry type="library" name={r.segments.drop(commonPrefix).mkString("_")} level="project" /> - } - } - { - for(m <- mod.projectDeps) yield { - val depName = resolved.find(_._3 eq m).get._1.mkString(".").toLowerCase - <orderEntry type="module" module-name={depName} exported="" /> + for(selector <- selectors) + yield { + val filepath = "$PROJECT_DIR$/.idea_modules/" + selector + ".iml" + val fileurl = "file://" + filepath + <module fileurl={fileurl} filepath={filepath} /> } } - </component> - </module> - write(pwd/".idea_modules"/s"${path.mkString(".").toLowerCase}.iml", pp.format(elem)) - } - val rootModule = - <module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager"> - <output url="file://$MODULE_DIR$/../out"/> - <content url="file://$MODULE_DIR$/.." /> - <exclude-output/> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - </component> - </module> - write(pwd/".idea_modules"/"root.iml", pp.format(rootModule)) - + </modules> + </component> + </project> + } + def rootXmlTemplate() = { + <module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager"> + <output url="file://$MODULE_DIR$/../out"/> + <content url="file://$MODULE_DIR$/.." /> + <exclude-output/> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> + </module> } + def libraryXmlTemplate(name: String, url: String) = { + <component name="libraryTable"> + <library name={name}> + <CLASSES> + <root url={url}/> + </CLASSES> + </library> + </component> + } + def moduleXmlTemplate(sourcePath: Path, + outputPath: Path, + libNames: Seq[String], + depNames: Seq[String]) = { + <module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager"> + <output url={"file://$MODULE_DIR$/" + relify(outputPath)} /> + <exclude-output /> + <content url={"file://$MODULE_DIR$/" + relify(sourcePath)}> + <sourceFolder url={"file://$MODULE_DIR$/" + relify(sourcePath)} isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + + { + for(name <- libNames) + yield <orderEntry type="library" name={name} level="project" /> + } + { + for(depName <- depNames) + yield <orderEntry type="module" module-name={depName} exported="" /> + } + </component> + </module> + } } |