diff options
-rwxr-xr-x | build.sc | 62 | ||||
-rwxr-xr-x | ci/test-mill-built.sh | 8 | ||||
-rwxr-xr-x | ci/test-mill-release.sh | 7 | ||||
-rwxr-xr-x | ci/test-sbt-built.sh | 7 | ||||
-rw-r--r-- | clientserver/src/mill/clientserver/Client.scala | 7 | ||||
-rw-r--r-- | clientserver/src/mill/clientserver/Server.scala | 9 | ||||
-rw-r--r-- | main/src/mill/Main.scala | 18 | ||||
-rw-r--r-- | main/src/mill/modules/Jvm.scala | 6 |
8 files changed, 79 insertions, 45 deletions
@@ -201,23 +201,56 @@ object integration extends MillModule{ def forkArgs = testArgs() } +def launcherScript(jvmArgs: Seq[String], + classPath: Agg[String]) = { + val jvmArgsStr = jvmArgs.mkString(" ") + val classPathStr = classPath.mkString(":") + s"""#!/usr/bin/env sh + | + |case "$$1" in + | -i | --interactive ) + | exec java $jvmArgsStr $$JAVA_OPTS -cp "$classPathStr" mill.Main "$${@:2}" + | ;; + | *) + | exec java $jvmArgsStr $$JAVA_OPTS -cp "$classPathStr" mill.ClientMain "$$@" + | ;; + |esac + """.stripMargin +} object dev extends MillModule{ def moduleDeps = Seq(scalalib, scalajslib) def forkArgs = T{ scalalib.testArgs() ++ scalajslib.testArgs() ++ scalaworker.testArgs() } - def mainClass = Some("mill.ClientMain") - - def run(wd: Path, args: String*) = T.command{ - mill.modules.Jvm.interactiveSubprocess( - finalMainClass(), - runClasspath().map(_.path), - forkArgs(), - forkEnv(), - args, - workingDir = ammonite.ops.pwd - ) + def launcher = T{ + val outputPath = T.ctx().dest / "run" + + write(outputPath, prependShellScript()) + + val perms = java.nio.file.Files.getPosixFilePermissions(outputPath.toNIO) + perms.add(PosixFilePermission.GROUP_EXECUTE) + perms.add(PosixFilePermission.OWNER_EXECUTE) + perms.add(PosixFilePermission.OTHERS_EXECUTE) + java.nio.file.Files.setPosixFilePermissions(outputPath.toNIO, perms) + PathRef(outputPath) + } + def prependShellScript = launcherScript(forkArgs(), runClasspath().map(_.path.toString)) + + def run(args: String*) = T.command{ + args match{ + case Nil => mill.eval.Result.Failure("Need to pass in cwd as first argument to dev.run") + case wd0 +: rest => + val wd = Path(wd0, pwd) + mkdir(wd) + mill.modules.Jvm.baseInteractiveSubprocess( + Seq(launcher().path.toString) ++ rest, + forkEnv(), + workingDir = wd + ) + mill.eval.Result.Success(()) + } + } } @@ -225,10 +258,9 @@ object dev extends MillModule{ def release = T{ createAssembly( dev.runClasspath().map(_.path), - prependShellScript = mill.modules.Jvm.launcherShellScript( - dev.mainClass().get, - Agg("$0"), - Seq("-DMILL_VERSION=" + publishVersion()._2) + prependShellScript = launcherScript( + Seq("-DMILL_VERSION=" + publishVersion()._2), + Agg("$0") ) ) diff --git a/ci/test-mill-built.sh b/ci/test-mill-built.sh index c12beefe..e2015237 100755 --- a/ci/test-mill-built.sh +++ b/ci/test-mill-built.sh @@ -12,7 +12,7 @@ target/bin/mill dev.assembly # Second build & run tests using Mill -out/dev/assembly/dest/out.jar all clientserver.test -#out/dev/assembly/dest/out.jar all {clientserver,main,scalalib,scalajslib}.test -#out/dev/assembly/dest/out.jar integration.test "mill.integration.forked.{AmmoniteTests,BetterFilesTests}" -#out/dev/assembly/dest/out.jar dev.assembly + +out/dev/assembly/dest/out.jar all {clientserver,main,scalalib,scalajslib}.test +out/dev/assembly/dest/out.jar integration.test "mill.integration.forked.{AmmoniteTests,BetterFilesTests}" +out/dev/assembly/dest/out.jar dev.assembly diff --git a/ci/test-mill-release.sh b/ci/test-mill-release.sh index b9986df0..838d1960 100755 --- a/ci/test-mill-release.sh +++ b/ci/test-mill-release.sh @@ -11,7 +11,6 @@ git clean -xdf # Second build & run tests using Mill -~/mill-release all clientserver.test -#~/mill-release all {clientserver,main,scalalib,scalajslib}.test -#~/mill-release integration.test "mill.integration.forked.{AcyclicTests,JawnTests,UpickleTests}" -#~/mill-release dev.assembly +~/mill-release all {clientserver,main,scalalib,scalajslib}.test +~/mill-release integration.test "mill.integration.forked.{AcyclicTests,JawnTests,UpickleTests}" +~/mill-release dev.assembly diff --git a/ci/test-sbt-built.sh b/ci/test-sbt-built.sh index 6895088d..3a85d345 100755 --- a/ci/test-sbt-built.sh +++ b/ci/test-sbt-built.sh @@ -8,7 +8,6 @@ git clean -xdf sbt bin/test:assembly # Run tests using Mill built using SBT -target/bin/mill clientserver.test -#target/bin/mill all {clientserver,main,scalalib,scalajslib}.test -#target/bin/mill integration.test "mill.integration.local.{AcyclicTests,JawnTests,UpickleTests}" -#target/bin/mill dev.assembly +target/bin/mill all {clientserver,main,scalalib,scalajslib}.test +target/bin/mill integration.test "mill.integration.local.{AcyclicTests,JawnTests,UpickleTests}" +target/bin/mill dev.assembly diff --git a/clientserver/src/mill/clientserver/Client.scala b/clientserver/src/mill/clientserver/Client.scala index b7a39cb2..1a4b1539 100644 --- a/clientserver/src/mill/clientserver/Client.scala +++ b/clientserver/src/mill/clientserver/Client.scala @@ -34,17 +34,14 @@ class Client(lockBase: String, stdout: OutputStream, stderr: OutputStream) extends ClientServer(lockBase){ def run(args: Array[String]) = { - println("Client Run") val f = new FileOutputStream(runFile) ClientServer.writeArgs(System.console() != null, args, f) f.close() if (locks.processLock.probe()) initServer() while(locks.processLock.probe()) Thread.sleep(3) - println("Client Connect Socket") - val ioSocket = ClientServer.retry(1000, new UnixDomainSocket(ioPath)) - println("Client Connected Socket") + val outErr = ioSocket.getInputStream val in = ioSocket.getOutputStream val outPump = new ClientOutputPumper(outErr, stdout, stderr) @@ -55,10 +52,8 @@ class Client(lockBase: String, inThread.setDaemon(true) outThread.start() inThread.start() - println("Client Await Server Lock") locks.serverLock.await() - println("Client End") } } diff --git a/clientserver/src/mill/clientserver/Server.scala b/clientserver/src/mill/clientserver/Server.scala index 1271933d..a40c7cbe 100644 --- a/clientserver/src/mill/clientserver/Server.scala +++ b/clientserver/src/mill/clientserver/Server.scala @@ -35,17 +35,13 @@ class Server[T](lockBase: String, val originalStdout = System.out def run() = { locks.processLock.tryLockBlock{ - println("Server Process Lock") var running = true while (running) locks.serverLock.lockBlock{ - println("Server Lock") new File(ioPath).delete() - println("Server Accept Socket") val ioSocket = new UnixDomainServerSocket(ioPath) val sockOpt = ClientServer.interruptWith( acceptTimeout, { - println("Server Socket Timing Out Close") try new UnixDomainSocket(ioPath).close() catch{case e: Throwable => } } @@ -55,13 +51,10 @@ class Server[T](lockBase: String, sockOpt match{ case None => running = false case Some(sock) => - println("Server Handle Run") try handleRun(sock) catch{case e: Throwable => e.printStackTrace(originalStdout) } } - println("Server Unlock") } - println("Server Process Unlock") }.getOrElse(throw new Exception("PID already present")) } @@ -97,7 +90,6 @@ class Server[T](lockBase: String, ) t.start() - println("Server Poll Client/Done") // We cannot simply use Lock#await here, because the filesystem doesn't // realize the clientLock/serverLock are held by different threads in the // two processes and gives a spurious deadlock error @@ -107,7 +99,6 @@ class Server[T](lockBase: String, t.interrupt() t.stop() - println("Server Socket Close") clientSocket.close() } } diff --git a/main/src/mill/Main.scala b/main/src/mill/Main.scala index ee055d64..4adb8d9c 100644 --- a/main/src/mill/Main.scala +++ b/main/src/mill/Main.scala @@ -2,7 +2,7 @@ package mill import java.io.{InputStream, OutputStream, PrintStream} -import ammonite.main.Cli.{formatBlock, genericSignature, replSignature} +import ammonite.main.Cli._ import ammonite.ops._ import ammonite.util.Util import mill.clientserver.{Client, FileLocks} @@ -102,12 +102,26 @@ object Main { import ammonite.main.Cli val removed = Set("predef-code", "home", "no-home-predef") - val millArgSignature = Cli.genericSignature.filter(a => !removed(a.name)) + var interactive = false + val interactiveSignature = Arg[Config, Unit]( + "interactive", Some('i'), + "Run Mill in interactive mode, suitable for opening REPLs and taking user input", + (c, v) =>{ + interactive = true + c + } + ) + val millArgSignature = + Cli.genericSignature.filter(a => !removed(a.name)) :+ interactiveSignature + Cli.groupArgs( args.toList, millArgSignature, Cli.Config(remoteLogging = false) ) match{ + case _ if interactive => + stderr.println("-i/--interactive must be passed in as the first argument") + (false, None) case Left(msg) => System.err.println(msg) (false, None) diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 2d351c18..fb2661e1 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -35,7 +35,11 @@ object Jvm { jvmArgs ++ Vector("-cp", classPath.mkString(":"), mainClass) ++ mainArgs - + baseInteractiveSubprocess(commandArgs, envArgs, workingDir) + } + def baseInteractiveSubprocess(commandArgs: Seq[String], + envArgs: Map[String, String], + workingDir: Path) = { val builder = new java.lang.ProcessBuilder() import collection.JavaConverters._ for ((k, v) <- envArgs){ |