From 01463f7024513a979aeed802173364a524c9ff04 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 7 Jun 2016 19:38:19 +0200 Subject: [PATCH 1/9] Add virtual project `dotty-core` to aggregate publishing of necessary artifacts --- project/Build.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index db358777228b..4a8bfd522c5d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -50,7 +50,8 @@ object DottyBuild extends Build { autoScalaLibrary := false, //Remove javac invalid options in Compile doc javacOptions in (Compile, doc) --= Seq("-Xlint:unchecked", "-Xlint:deprecation") - ) + ). + settings(publishing) lazy val dotty = project.in(file(".")). dependsOn(`dotty-interfaces`). @@ -244,7 +245,8 @@ object DottyInjectedPlugin extends AutoPlugin { """) } */ - ) + ). + settings(publishing) /** A sandbox to play with the Scala.js back-end of dotty. @@ -349,6 +351,13 @@ object DottyInjectedPlugin extends AutoPlugin { ) ) + lazy val `dotty-core` = project + .dependsOn(`dotty-interfaces`) + .dependsOn(dotty) + .dependsOn(`dotty-bridge`) + .settings(publishing) + .aggregate(dotty, `dotty-interfaces`, `dotty-bridge`) + // Partest tasks lazy val lockPartestFile = TaskKey[Unit]("lockPartestFile", "Creates the lock file at ./tests/locks/partest-.lock") lazy val partestLockFile = new File("." + File.separator + "tests" + File.separator + "locks" + File.separator + s"partest-$pid.lock") From 1f1b3577bb1f05a237282ab7682f8a8c7bf406d1 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 7 Jun 2016 20:01:55 +0200 Subject: [PATCH 2/9] Add console interface for sbt --- .../main/scala/xsbt/ConsoleInterface.scala | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 bridge/src/main/scala/xsbt/ConsoleInterface.scala diff --git a/bridge/src/main/scala/xsbt/ConsoleInterface.scala b/bridge/src/main/scala/xsbt/ConsoleInterface.scala new file mode 100644 index 000000000000..1aec2a24193c --- /dev/null +++ b/bridge/src/main/scala/xsbt/ConsoleInterface.scala @@ -0,0 +1,68 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import xsbti.Logger +import scala.tools.nsc.{ GenericRunnerCommand, Interpreter, InterpreterLoop, ObjectRunner, Settings } +import scala.tools.nsc.interpreter.InteractiveReader +import scala.tools.nsc.reporters.Reporter +import scala.tools.nsc.util.ClassPath + +import dotty.tools.dotc.repl.REPL +import dotty.tools.dotc.repl.REPL.Config + +class ConsoleInterface { + def commandArguments( + args: Array[String], + bootClasspathString: String, + classpathString: String, + log: Logger + ): Array[String] = args + + def run(args: Array[String], + bootClasspathString: String, + classpathString: String, + initialCommands: String, + cleanupCommands: String, + loader: ClassLoader, + bindNames: Array[String], + bindValues: Array[Any], + log: Logger + ): Unit = { + val completeArgs = + args :+ + "-bootclasspath" :+ bootClasspathString :+ + "-classpath" :+ classpathString + + println("Starting dotty interpreter...") + val repl = ConsoleInterface.customRepl( + initialCommands :: Nil, + cleanupCommands :: Nil, + bindNames zip bindValues + ) + repl.process(completeArgs) + } +} + +object ConsoleInterface { + def customConfig( + initCmds: List[String], + cleanupCmds: List[String], + boundVals: Array[(String, Any)] + ) = new Config { + override val initialCommands: List[String] = initCmds + override val cleanupCommands: List[String] = cleanupCmds + override val boundValues: Array[(String, Any)] = boundVals + } + + def customRepl(cfg: Config): REPL = new REPL { + override lazy val config = cfg + } + + def customRepl( + initCmds: List[String], + cleanupCmds: List[String], + boundVals: Array[(String, Any)] + ): REPL = customRepl(customConfig(initCmds, cleanupCmds, boundVals)) +} From fbf44ebaf4ae80cbc10613b759beb1f0167b19c6 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 7 Jun 2016 20:02:57 +0200 Subject: [PATCH 3/9] Remove duplicate line --- project/Build.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/project/Build.scala b/project/Build.scala index 4a8bfd522c5d..c07fab230e51 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -331,7 +331,6 @@ object DottyInjectedPlugin extends AutoPlugin { ) lazy val publishing = Seq( - publishMavenStyle := true, publishMavenStyle := true, publishArtifact := true, publishTo := { From a00a972c7425232432364bf991e118d248578f0d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 8 Jun 2016 10:50:38 +0200 Subject: [PATCH 4/9] Add date and hash to publishing version --- project/Build.scala | 6 ++++-- project/VersionUtil.scala | 18 ++++++++++++++++++ scripts/build/get-scala-commit-date | 16 ++++++++++++++++ scripts/build/get-scala-commit-date.bat | 9 +++++++++ scripts/build/get-scala-commit-sha | 18 ++++++++++++++++++ scripts/build/get-scala-commit-sha.bat | 9 +++++++++ 6 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 project/VersionUtil.scala create mode 100755 scripts/build/get-scala-commit-date create mode 100644 scripts/build/get-scala-commit-date.bat create mode 100755 scripts/build/get-scala-commit-sha create mode 100644 scripts/build/get-scala-commit-sha.bat diff --git a/project/Build.scala b/project/Build.scala index c07fab230e51..85a7bb8616bb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -25,7 +25,8 @@ object DottyBuild extends Build { override def settings: Seq[Setting[_]] = { super.settings ++ Seq( scalaVersion in Global := "2.11.5", - version in Global := "0.1-SNAPSHOT", + version in Global := + "0.1-SNAPSHOT-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash, organization in Global := "ch.epfl.lamp", organizationName in Global := "LAMP/EPFL", organizationHomepage in Global := Some(url("http://lamp.epfl.ch")), @@ -208,7 +209,8 @@ object DottyBuild extends Build { "org.scala-sbt" % "api" % sbtVersion.value % "test", "org.specs2" %% "specs2" % "2.3.11" % "test" ), - version := "0.1.1-SNAPSHOT", + version := + "0.1.1-SNAPSHOT-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash, // The sources should be published with crossPaths := false, the binaries // are unused so it doesn't matter. crossPaths := false, diff --git a/project/VersionUtil.scala b/project/VersionUtil.scala new file mode 100644 index 000000000000..338cf2d95e2f --- /dev/null +++ b/project/VersionUtil.scala @@ -0,0 +1,18 @@ +import scala.sys.process.Process + +object VersionUtil { + def executeScript(scriptName: String) = { + val cmd = + if (System.getProperty("os.name").toLowerCase.contains("windows")) + s"cmd.exe /c scripts\\build\\$scriptName.bat -p" + else s"scripts/build/$scriptName" + Process(cmd).lines.head.trim + } + + /** Seven letters of the SHA hash is considered enough to uniquely identify a + * commit, albeit extremely large projects - such as the Linux kernel - need + * more letters to stay unique + */ + def gitHash = executeScript("get-scala-commit-sha").substring(0, 7) + def commitDate = executeScript("get-scala-commit-date") +} diff --git a/scripts/build/get-scala-commit-date b/scripts/build/get-scala-commit-date new file mode 100755 index 000000000000..ef5b0f540da7 --- /dev/null +++ b/scripts/build/get-scala-commit-date @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# +# Usage: get-scala-commit-date [dir] +# Figures out current commit date of a git clone. +# If no dir is given, current working dir is used. +# +# Example build version string: +# 20120312 +# + +[[ $# -eq 0 ]] || cd "$1" + +lastcommitdate=$(git log --format="%ci" HEAD | head -n 1 | cut -d ' ' -f 1) + +# 20120324 +echo "${lastcommitdate//-/}" diff --git a/scripts/build/get-scala-commit-date.bat b/scripts/build/get-scala-commit-date.bat new file mode 100644 index 000000000000..735a80b927f3 --- /dev/null +++ b/scripts/build/get-scala-commit-date.bat @@ -0,0 +1,9 @@ +@echo off +for %%X in (bash.exe) do (set FOUND=%%~$PATH:X) +if defined FOUND ( + bash "%~dp0\get-scala-commit-date" 2>NUL +) else ( + rem echo this script does not work with cmd.exe. please, install bash + echo unknown + exit 1 +) diff --git a/scripts/build/get-scala-commit-sha b/scripts/build/get-scala-commit-sha new file mode 100755 index 000000000000..eab90a4215fc --- /dev/null +++ b/scripts/build/get-scala-commit-sha @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# +# Usage: get-scala-commit-sha [dir] +# Figures out current commit sha of a git clone. +# If no dir is given, current working dir is used. +# +# Example build version string: +# 6f1c486d0ba +# + +[[ $# -eq 0 ]] || cd "$1" + +# printf %016s is not portable for 0-padding, has to be a digit. +# so we're stuck disassembling it. +hash=$(git log -1 --format="%H" HEAD) +hash=${hash#g} +hash=${hash:0:10} +echo "$hash" diff --git a/scripts/build/get-scala-commit-sha.bat b/scripts/build/get-scala-commit-sha.bat new file mode 100644 index 000000000000..6559a191201c --- /dev/null +++ b/scripts/build/get-scala-commit-sha.bat @@ -0,0 +1,9 @@ +@echo off +for %%X in (bash.exe) do (set FOUND=%%~$PATH:X) +if defined FOUND ( + bash "%~dp0\get-scala-commit-sha" 2>NUL +) else ( + rem echo this script does not work with cmd.exe. please, install bash + echo unknown + exit 1 +) From df8490167708d009157710e5ad73fa6f8ed3f6fc Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 8 Jun 2016 17:56:41 +0200 Subject: [PATCH 5/9] Add loader support for dotty bridge --- bridge/src/main/scala/xsbt/ConsoleInterface.scala | 13 +++++++++---- .../tools/dotc/repl/CompilingInterpreter.scala | 14 +++++++++----- src/dotty/tools/dotc/repl/REPL.scala | 10 ++++++++-- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/bridge/src/main/scala/xsbt/ConsoleInterface.scala b/bridge/src/main/scala/xsbt/ConsoleInterface.scala index 1aec2a24193c..f56918113f79 100644 --- a/bridge/src/main/scala/xsbt/ConsoleInterface.scala +++ b/bridge/src/main/scala/xsbt/ConsoleInterface.scala @@ -9,6 +9,7 @@ import scala.tools.nsc.interpreter.InteractiveReader import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.util.ClassPath +import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.repl.REPL import dotty.tools.dotc.repl.REPL.Config @@ -39,7 +40,8 @@ class ConsoleInterface { val repl = ConsoleInterface.customRepl( initialCommands :: Nil, cleanupCommands :: Nil, - bindNames zip bindValues + bindNames zip bindValues, + loader ) repl.process(completeArgs) } @@ -49,11 +51,13 @@ object ConsoleInterface { def customConfig( initCmds: List[String], cleanupCmds: List[String], - boundVals: Array[(String, Any)] + boundVals: Array[(String, Any)], + loader: ClassLoader ) = new Config { override val initialCommands: List[String] = initCmds override val cleanupCommands: List[String] = cleanupCmds override val boundValues: Array[(String, Any)] = boundVals + override val classLoader: Option[ClassLoader] = Option(loader) } def customRepl(cfg: Config): REPL = new REPL { @@ -63,6 +67,7 @@ object ConsoleInterface { def customRepl( initCmds: List[String], cleanupCmds: List[String], - boundVals: Array[(String, Any)] - ): REPL = customRepl(customConfig(initCmds, cleanupCmds, boundVals)) + boundVals: Array[(String, Any)], + loader: ClassLoader + ): REPL = customRepl(customConfig(initCmds, cleanupCmds, boundVals, loader)) } diff --git a/src/dotty/tools/dotc/repl/CompilingInterpreter.scala b/src/dotty/tools/dotc/repl/CompilingInterpreter.scala index b6a3e388e55f..897011be2a6b 100644 --- a/src/dotty/tools/dotc/repl/CompilingInterpreter.scala +++ b/src/dotty/tools/dotc/repl/CompilingInterpreter.scala @@ -60,7 +60,11 @@ import printing.SyntaxHighlighting * @param ictx The context to use for initialization of the interpreter, * needed to access the current classpath. */ -class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler with Interpreter { +class CompilingInterpreter( + out: PrintWriter, + ictx: Context, + parentClassLoader: Option[ClassLoader] +) extends Compiler with Interpreter { import ast.untpd._ import CompilingInterpreter._ @@ -136,8 +140,6 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit /** the compiler's classpath, as URL's */ val compilerClasspath: List[URL] = ictx.platform.classPath(ictx).asURLs - protected def parentClassLoader: ClassLoader = classOf[Interpreter].getClassLoader - /* A single class loader is used for all commands interpreted by this Interpreter. It would also be possible to create a new class loader for each command to interpret. The advantages of the current approach are: @@ -153,8 +155,10 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit */ /** class loader used to load compiled code */ val classLoader: ClassLoader = { - val parent = new URLClassLoader(compilerClasspath.toArray, parentClassLoader) - new AbstractFileClassLoader(virtualDirectory, parent) + lazy val parent = new URLClassLoader(compilerClasspath.toArray, + classOf[Interpreter].getClassLoader) + + new AbstractFileClassLoader(virtualDirectory, parentClassLoader.getOrElse(parent)) } // Set the current Java "context" class loader to this interpreter's class loader diff --git a/src/dotty/tools/dotc/repl/REPL.scala b/src/dotty/tools/dotc/repl/REPL.scala index 1fcb055d6563..cca5e8d6bef9 100644 --- a/src/dotty/tools/dotc/repl/REPL.scala +++ b/src/dotty/tools/dotc/repl/REPL.scala @@ -4,7 +4,10 @@ package repl import core.Contexts.Context import reporting.Reporter -import java.io.{BufferedReader, File, FileReader, PrintWriter} +import io.{AbstractFile, PlainFile, VirtualDirectory} +import scala.reflect.io.{PlainDirectory, Directory} +import java.io.{BufferedReader, File => JFile, FileReader, PrintWriter} +import java.net.{URL, URLClassLoader} /** A compiler which stays resident between runs. * Usage: @@ -31,7 +34,7 @@ class REPL extends Driver { } override def newCompiler(implicit ctx: Context): Compiler = - new repl.CompilingInterpreter(config.output, ctx) + new repl.CompilingInterpreter(config.output, ctx, config.classLoader) override def sourcesRequired = false @@ -80,6 +83,9 @@ object REPL { */ val boundValues: Array[(String, Any)] = Array.empty[(String, Any)] + /** To pass a custom ClassLoader to the Dotty REPL, overwride this value */ + val classLoader: Option[ClassLoader] = None + /** The default input reader */ def input(in: Interpreter)(implicit ctx: Context): InteractiveReader = { val emacsShell = System.getProperty("env.emacs", "") != "" From 22b40bf0ff3ee685116a432225b77d395c958c14 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 9 Jun 2016 11:24:56 +0200 Subject: [PATCH 6/9] Disable binary publishing in bridge --- project/Build.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 85a7bb8616bb..712590d1fc4c 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -211,10 +211,13 @@ object DottyBuild extends Build { ), version := "0.1.1-SNAPSHOT-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash, - // The sources should be published with crossPaths := false, the binaries - // are unused so it doesn't matter. + // The sources should be published with crossPaths := false since they + // need to be compiled by the project using the bridge. crossPaths := false, + // Don't publish any binaries for the bridge because of the above + publishArtifact in (Compile, packageBin) := false, + fork in Test := true, parallelExecution in Test := false ). From 8fe3e3720d820a376782b9db2592534c985f2e41 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 9 Jun 2016 12:55:59 +0200 Subject: [PATCH 7/9] Add developers and license to POM --- project/Build.scala | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/project/Build.scala b/project/Build.scala index 712590d1fc4c..59b8739863fd 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -347,11 +347,47 @@ object DottyInjectedPlugin extends AutoPlugin { }, publishArtifact in Test := false, homepage := Some(url("https://github.com/lampepfl/dotty")), + licenses += ("BSD New", + url("https://github.com/lampepfl/dotty/blob/master/LICENSE.md")), scmInfo := Some( ScmInfo( url("https://github.com/lampepfl/dotty"), "scm:git:git@github.com:lampepfl/dotty.git" ) + ), + pomExtra := ( + + + odersky + Martin Odersky + martin.odersky@epfl.ch + https://github.com/odersky + + + DarkDimius + Dmitry Petrashko + me@d-d.me + https://d-d.me + + + smarter + Guillaume Martres + smarter@ubuntu.com + http://guillaume.martres.me + + + felixmulder + Felix Mulder + felix.mulder@gmail.com + http://felixmulder.com + + + liufengyun + Liu Fengyun + liufengyun@chaos-lab.com + http://chaos-lab.com + + ) ) From 9b15ac10f129a3579f02b2c1b776ba6fa7654edc Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 10 Jun 2016 10:24:40 +0200 Subject: [PATCH 8/9] remove `dotty-core` project and publish individually instead Since you still need to depend on multiple artifacts from within the dotty project, a unified project is not feasible. A plugin would work better of course. --- project/Build.scala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 59b8739863fd..2104d9b37d19 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -338,6 +338,7 @@ object DottyInjectedPlugin extends AutoPlugin { lazy val publishing = Seq( publishMavenStyle := true, publishArtifact := true, + isSnapshot := version.value.contains("SNAPSHOT"), publishTo := { val nexus = "https://oss.sonatype.org/" if (isSnapshot.value) @@ -391,13 +392,6 @@ object DottyInjectedPlugin extends AutoPlugin { ) ) - lazy val `dotty-core` = project - .dependsOn(`dotty-interfaces`) - .dependsOn(dotty) - .dependsOn(`dotty-bridge`) - .settings(publishing) - .aggregate(dotty, `dotty-interfaces`, `dotty-bridge`) - // Partest tasks lazy val lockPartestFile = TaskKey[Unit]("lockPartestFile", "Creates the lock file at ./tests/locks/partest-.lock") lazy val partestLockFile = new File("." + File.separator + "tests" + File.separator + "locks" + File.separator + s"partest-$pid.lock") From 42030aad5ad62296286f2d1ec785377ba550cb89 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 10 Jun 2016 10:49:10 +0200 Subject: [PATCH 9/9] Change versioning to a sonatype approved scheme --- project/Build.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 2104d9b37d19..fc452f7f66ac 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -26,7 +26,7 @@ object DottyBuild extends Build { super.settings ++ Seq( scalaVersion in Global := "2.11.5", version in Global := - "0.1-SNAPSHOT-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash, + "0.1-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash + "-SNAPSHOT", organization in Global := "ch.epfl.lamp", organizationName in Global := "LAMP/EPFL", organizationHomepage in Global := Some(url("http://lamp.epfl.ch")), @@ -210,7 +210,7 @@ object DottyBuild extends Build { "org.specs2" %% "specs2" % "2.3.11" % "test" ), version := - "0.1.1-SNAPSHOT-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash, + "0.1.1-" + VersionUtil.commitDate + "-" + VersionUtil.gitHash + "-SNAPSHOT", // The sources should be published with crossPaths := false since they // need to be compiled by the project using the bridge. crossPaths := false,