Skip to content

Instantly share code, notes, and snippets.

@lihaoyi
Created October 30, 2017 13:49
Show Gist options
  • Save lihaoyi/e1407272a3239ed10ba966d71971a37a to your computer and use it in GitHub Desktop.
Save lihaoyi/e1407272a3239ed10ba966d71971a37a to your computer and use it in GitHub Desktop.
Resolving jars with Coursier and compiling Scala with the Zinc incremental compiler, in a self-contained Ammonite script
import play.api.libs.json.Json
object Main{
def main(args: Array[String]): Unit = {
println(
Json.prettyPrint(
Json.toJson(Seq("Hello", "World", "Cow"))
)
)
}
}
import $ivy.`org.scala-sbt::zinc:1.0.3`
import ammonite.ops._
import java.io.File
import coursier._
import sbt.internal.inc.{FreshCompilerCache, ScalaInstance, ZincUtil}
import sbt.internal.util.{ConsoleOut, MainAppender}
import sbt.util.LogExchange
import xsbti.api.{ClassLike, DependencyContext}
import xsbti.compile._
import scalaz.concurrent.Task
val scalaVersion = scala.util.Properties.versionNumberString
val binaryScalaVersion = scalaVersion.split('.').dropRight(1).mkString(".")
val start = Resolution(
Set(
Dependency(Module("org.scala-lang", "scala-compiler"), scalaVersion),
Dependency(Module("org.scala-lang", "scala-library"), scalaVersion),
Dependency(Module("org.scala-sbt", s"compiler-bridge_$binaryScalaVersion"), "1.0.3"),
// Example third-party library, with dependencies
Dependency(Module("com.typesafe.play", s"play-json_$binaryScalaVersion"), "2.6.6")
)
)
val repositories = Seq(
Cache.ivy2Local,
MavenRepository("https://repo1.maven.org/maven2")
)
val fetch = Fetch.from(repositories, Cache.fetch())
val resolution = start.process.run(fetch).unsafePerformSync
val localArtifacts: Seq[File] = Task.gatherUnordered(
resolution.artifacts.map(Cache.file(_).run)
).unsafePerformSync.flatMap(_.toOption)
pprint.log(localArtifacts)
def grepJar(s: String) = localArtifacts.find(_.toString.endsWith(s)).get
val scalac = ZincUtil.scalaCompiler(
new ScalaInstance(
version = scalaVersion,
loader = getClass.getClassLoader,
libraryJar = grepJar(s"scala-library-$scalaVersion.jar"),
compilerJar = grepJar(s"scala-compiler-$scalaVersion.jar"),
allJars = localArtifacts.toArray,
explicitActual = None
),
grepJar(s"compiler-bridge_$binaryScalaVersion-1.0.3.jar")
)
val outputDir = pwd/'target/'zinc
mkdir(outputDir)
val scalaFiles = Array(pwd/"Test.scala")
scalac.apply(
sources = scalaFiles.map(_.toIO),
changes = new DependencyChanges {
def isEmpty = true
def modifiedBinaries() = Array[File]()
def modifiedClasses() = Array[String]()
},
classpath = localArtifacts.toArray,
singleOutput = outputDir.toIO,
options = Array(),
callback = new xsbti.AnalysisCallback {
def startSource(source: File) = ()
def apiPhaseCompleted() = ()
def enabled() = true
def binaryDependency(onBinaryEntry: File, onBinaryClassName: String, fromClassName: String, fromSourceFile: File, context: DependencyContext) = ()
def generatedNonLocalClass(source: File, classFile: File, binaryClassName: String, srcClassName: String) = ()
def problem(what: String, pos: xsbti.Position, msg: String, severity: xsbti.Severity, reported: Boolean) = ()
def dependencyPhaseCompleted() = ()
def classDependency(onClassName: String, sourceClassName: String, context: DependencyContext) = ()
def generatedLocalClass(source: File, classFile: File) = ()
def api(sourceFile: File, classApi: ClassLike) = ()
def mainClass(sourceFile: File, className: String) = ()
def usedName(className: String, name: String, useScopes: java.util.EnumSet[xsbti.UseScope]) = ()
},
maximumErrors = 10,
cache = new FreshCompilerCache(),
log = {
val console = ConsoleOut.systemOut
val consoleAppender = MainAppender.defaultScreen(console)
val l = LogExchange.logger("Hello")
LogExchange.unbindLoggerAppenders("Hello")
LogExchange.bindLoggerAppenders("Hello", (consoleAppender -> sbt.util.Level.Warn) :: Nil)
l
}
)
%('java,"-cp", localArtifacts.mkString(":") + ":.", "Test")(pwd/'target/'zinc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment