summaryrefslogtreecommitdiff
path: root/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-11-14 21:40:49 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-11-14 21:40:49 -0800
commitd2598aa69c866236c9b5eddac2e03161b2456848 (patch)
tree5f002510d8bc02cf9de61c9368954eac908cefc7 /scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
parentec4486c3700c421311d190c36e01faf2fd011e4e (diff)
downloadmill-d2598aa69c866236c9b5eddac2e03161b2456848.tar.gz
mill-d2598aa69c866236c9b5eddac2e03161b2456848.tar.bz2
mill-d2598aa69c866236c9b5eddac2e03161b2456848.zip
First pass at IntelliJ project generation for a Mill build. Run using `sbt scalaplugin/assembly && amm build.sc idea`
Diffstat (limited to 'scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala')
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala135
1 files changed, 135 insertions, 0 deletions
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala b/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
new file mode 100644
index 00000000..b756d227
--- /dev/null
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/GenIdea.scala
@@ -0,0 +1,135 @@
+package mill.scalaplugin
+
+import ammonite.ops.{Path, pwd, rm, write}
+import mill.discover.{Discovered, Hierarchy}
+import mill.eval.{Evaluator, PathRef}
+import mill.util.OSet
+
+object GenIdea {
+ def apply[T: Discovered](obj: T) = {
+ val pp = new scala.xml.PrettyPrinter(999, 4)
+ val discovered = implicitly[Discovered[T]]
+ def rec(x: Hierarchy[T]): Seq[(Seq[String], Module)] = {
+ val node = x.node(obj)
+ val self = node match{
+ case m: Module => Seq(x.path -> m)
+ case _ => Nil
+ }
+
+ self ++ x.children.flatMap(rec)
+ }
+ val mapping = Discovered.mapping(obj)(discovered)
+ val workspacePath = pwd / 'out
+ 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 allResolved = resolved.flatMap(_._2).distinct
+ val minResolvedLength = allResolved.map(_.segments.length).min
+ val commonPrefix = allResolved.map(_.segments.take(minResolvedLength))
+ .transpose
+ .takeWhile(_.distinct.length == 1)
+ .length
+
+ val libraryFiles = for(path <- allResolved) yield {
+ 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))
+ }
+
+ def relify(p: Path) = {
+ val r = p.relativeTo(moduleDir)
+ (Seq.fill(r.ups)("..") ++ r.segments).mkString("/")
+ }
+ 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" />
+
+ {
+ 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="" />
+ }
+ }
+ </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))
+
+ }
+
+}