summaryrefslogtreecommitdiff
path: root/shared.sc
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-12-28 00:16:03 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-12-28 00:16:03 -0800
commit1e6baf44761267a0588561a59402f012a2d51e16 (patch)
treee6234e232e1c4c1e7972583c4918c124ca874693 /shared.sc
parentb2cca82786a5fdf0818b4e6be5885855a95f637e (diff)
downloadmill-1e6baf44761267a0588561a59402f012a2d51e16.tar.gz
mill-1e6baf44761267a0588561a59402f012a2d51e16.tar.bz2
mill-1e6baf44761267a0588561a59402f012a2d51e16.zip
Move all the source generation logic into a `shared.sc` file to avoid duplication
DRY it up internally Move the Bridge downloading logic into `shared.sc` as well, and swap the subprocesses for in-memory processing using scalaj-http and ZipInputStream
Diffstat (limited to 'shared.sc')
-rw-r--r--shared.sc125
1 files changed, 125 insertions, 0 deletions
diff --git a/shared.sc b/shared.sc
new file mode 100644
index 00000000..17b82595
--- /dev/null
+++ b/shared.sc
@@ -0,0 +1,125 @@
+/**
+ * Utility code that is shared between our SBT build and our Mill build. SBT
+ * calls this by shelling out to Ammonite in a subprocess, while Mill loads it
+ * via import $file
+ */
+
+import ammonite.ops.{write, Path, mkdir, RelPath, up}
+
+def argNames(n: Int) = {
+ val uppercases = (0 until n).map("T" + _)
+ val lowercases = uppercases.map(_.toLowerCase)
+ val typeArgs = uppercases.mkString(", ")
+ val zipArgs = lowercases.mkString(", ")
+ (lowercases, uppercases, typeArgs, zipArgs)
+}
+def generateApplyer(dir: Path) = {
+ def generate(n: Int) = {
+ val (lowercases, uppercases, typeArgs, zipArgs) = argNames(n)
+ val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: TT[$upper]" }.mkString(", ")
+
+ val body = s"mapCtx(zip($zipArgs)) { case (($zipArgs), z) => cb($zipArgs, z) }"
+ val zipmap = s"def zipMap[$typeArgs, Res]($parameters)(cb: ($typeArgs, Ctx) => Z[Res]) = $body"
+ val zip = s"def zip[$typeArgs]($parameters): TT[($typeArgs)]"
+
+ if (n < 22) List(zipmap, zip).mkString("\n") else zip
+ }
+ write(
+ dir / "ApplicativeGenerated.scala",
+ s"""package mill.define
+ |import scala.language.higherKinds
+ |trait ApplyerGenerated[TT[_], Z[_], Ctx] {
+ | def mapCtx[A, B](a: TT[A])(f: (A, Ctx) => Z[B]): TT[B]
+ | ${(2 to 22).map(generate).mkString("\n")}
+ |}""".stripMargin
+ )
+}
+
+def generateTarget(dir: Path) = {
+ def generate(n: Int) = {
+ val (lowercases, uppercases, typeArgs, zipArgs) = argNames(n)
+ val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: TT[$upper]" }.mkString(", ")
+ val body = uppercases.zipWithIndex.map { case (t, i) => s"args[$t]($i)" }.mkString(", ")
+
+ s"def zip[$typeArgs]($parameters) = makeT[($typeArgs)](Seq($zipArgs), (args: mill.util.Ctx) => ($body))"
+ }
+
+ write(
+ dir / "TaskGenerated.scala",
+ s"""package mill.define
+ |import scala.language.higherKinds
+ |trait TargetGenerated {
+ | type TT[+X]
+ | def makeT[X](inputs: Seq[TT[_]], evaluate: mill.util.Ctx => mill.eval.Result[X]): TT[X]
+ | ${(3 to 22).map(generate).mkString("\n")}
+ |}""".stripMargin
+ )
+}
+
+def generateApplicativeTest(dir: Path) = {
+ def generate(n: Int): String = {
+ val (lowercases, uppercases, typeArgs, zipArgs) = argNames(n)
+ val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: Option[$upper]" }.mkString(", ")
+ val forArgs = lowercases.map(i => s"$i <- $i").mkString("; ")
+ s"def zip[$typeArgs]($parameters) = { for ($forArgs) yield ($zipArgs) }"
+ }
+
+ write(
+ dir / "ApplicativeTestsGenerated.scala",
+ s"""package mill.define
+ |trait OptGenerated {
+ | ${(2 to 22).map(generate).mkString("\n")}
+ |}
+ """.stripMargin
+ )
+}
+
+@main
+def generateSources(p: Path) = {
+ generateApplyer(p)
+ generateTarget(p)
+}
+
+@main
+def generateTests(p: Path) = {
+ generateApplicativeTest(p)
+}
+
+@main
+def downloadBridgeSource(curlDest: Path, crossVersion: String) = {
+ val v = crossVersion.split('.').dropRight(1).mkString(".")
+ val url =
+ s"http://repo1.maven.org/maven2/org/scala-sbt/compiler-bridge_$v/1.0.5/compiler-bridge_$v-1.0.5-sources.jar"
+
+ mkdir(curlDest)
+
+ val bytes = scalaj.http.Http.apply(url).asBytes.body
+ val byteStream = new java.io.ByteArrayInputStream(bytes)
+ val zipStream = new java.util.zip.ZipInputStream(byteStream)
+ while({
+ zipStream.getNextEntry match{
+ case null => false
+ case entry =>
+ if (!entry.isDirectory) {
+ val dest = curlDest / RelPath(entry.getName)
+ mkdir(dest / up)
+ val fileOut = new java.io.FileOutputStream(dest.toString)
+ val buffer = new Array[Byte](4096)
+ while ( {
+ zipStream.read(buffer) match {
+ case -1 => false
+ case n =>
+ fileOut.write(buffer, 0, n)
+ true
+ }
+ }) ()
+ fileOut.close()
+ }
+ zipStream.closeEntry()
+ true
+ }
+ })()
+
+
+ curlDest
+} \ No newline at end of file