diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2017-12-28 00:16:03 -0800 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2017-12-28 00:16:03 -0800 |
commit | 1e6baf44761267a0588561a59402f012a2d51e16 (patch) | |
tree | e6234e232e1c4c1e7972583c4918c124ca874693 /shared.sc | |
parent | b2cca82786a5fdf0818b4e6be5885855a95f637e (diff) | |
download | mill-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.sc | 125 |
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 |