summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sc62
-rwxr-xr-xci/test-mill-built.sh8
-rwxr-xr-xci/test-mill-release.sh7
-rwxr-xr-xci/test-sbt-built.sh7
-rw-r--r--clientserver/src/mill/clientserver/Client.scala7
-rw-r--r--clientserver/src/mill/clientserver/Server.scala9
-rw-r--r--main/src/mill/Main.scala18
-rw-r--r--main/src/mill/modules/Jvm.scala6
8 files changed, 79 insertions, 45 deletions
diff --git a/build.sc b/build.sc
index bd06c7db..32c77310 100755
--- a/build.sc
+++ b/build.sc
@@ -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){