From ea7d9b7b13b349644800a19e3c25ed4f3358e416 Mon Sep 17 00:00:00 2001 From: LolHens Date: Wed, 28 Mar 2018 10:30:17 +0200 Subject: [PATCH 1/8] universal scripts that run on linux and windows --- build.sc | 74 +++++++++++++------- main/src/mill/modules/Jvm.scala | 47 +++++++++---- scalalib/src/mill/scalalib/ScalaModule.scala | 2 +- 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/build.sc b/build.sc index 134e76e9142..22a58c6da56 100755 --- a/build.sc +++ b/build.sc @@ -208,32 +208,56 @@ object integration extends MillModule{ def launcherScript(isWin: Boolean, jvmArgs: Seq[String], classPath: Agg[String]) = { + def universalScript(shellCommands: String, + cmdCommands: String, + shebang: Boolean = true): String = { + Seq( + Some("#!/usr/bin/env sh") + .filter(_ => shebang), + Some( + s""":; shopt -s expand_aliases + |:; alias ::='' + |${shellCommands.split("\r\n|\n").map(":: " + _).mkString("\n")} + |:: exit""".stripMargin.replaceAll("\r\n|\n", "\n") + ), + Some( + s"""@echo off + |$cmdCommands + |exit /B %errorlevel% + |""".stripMargin.replaceAll("\r\n|\n", "\r\n") + ) + ).flatMap(_.toSeq).mkString("\n") + } + val jvmArgsStr = jvmArgs.mkString(" ") - val classPathStr = if (isWin) classPath.mkString(";") else classPath.mkString(":") - if (isWin) - s"""::#! - |@echo off - |if "%1" == "-i" set _I_=true - |if "%1" == "--interactive" set _I_=true - |if defined _I_ ( - | java $jvmArgsStr %JAVA_OPTS% -cp "$classPathStr" mill.Main %* - |) else ( - | java $jvmArgsStr %JAVA_OPTS% -cp "$classPathStr" mill.clientserver.Client %* - |) - |EXIT /B %errorlevel% - """.stripMargin.split('\n').mkString("\r\n") - else - s"""#!/usr/bin/env sh - | - |case "$$1" in - | -i | --interactive ) - | exec java $jvmArgsStr $$JAVA_OPTS -cp "$classPathStr" mill.Main "$$@" - | ;; - | *) - | exec java $jvmArgsStr $$JAVA_OPTS -cp "$classPathStr" mill.clientserver.Client "$$@" - | ;; - |esac - """.stripMargin + universalScript( + shellCommands = { + def java(mainClass: String) = + s"""exec java $jvmArgsStr $$JAVA_OPTS -cp "${classPath.mkString(":")}" mill.Main "$$@"""" + + s"""case "$$1" in + | -i | --interactive ) + | ${java("mill.Main")} + | ;; + | *) + | ${java("mill.clientserver.Client")} + | ;; + |esac""".stripMargin + }, + cmdCommands = { + def java(mainClass: String) = + s"""java $jvmArgsStr %JAVA_OPTS% -cp "${classPath.mkString(";")}" $mainClass %*""" + + s"""if "%1" == "-i" set _I_=true + |if "%1" == "--interactive" set _I_=true + |if defined _I_ ( + | ${java("mill.Main")} + |) else ( + | ${java("mill.clientserver.Client")} + |)""".stripMargin + }, + shebang = !isWin + ) } object dev extends MillModule{ diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 92469988a18..96bb102d89d 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -277,7 +277,7 @@ object Jvm { // Prepend shell script and make it executable if (prependShellScript.isEmpty) mv(tmp, output) else{ - val lineSep = if (isWin) "\r\n" else "\n" + val lineSep = if (!prependShellScript.endsWith("\n")) "\n\r\n" else "" val outputStream = newOutputStream(output.toNIO) IO.stream(new ByteArrayInputStream((prependShellScript + lineSep).getBytes()), outputStream) IO.stream(read.getInputStream(tmp), outputStream) @@ -319,21 +319,41 @@ object Jvm { } + def universalScript(shellCommands: String, + cmdCommands: String, + shebang: Boolean = true): String = { + Seq( + Some("#!/usr/bin/env sh") + .filter(_ => shebang), + Some( + s""":; shopt -s expand_aliases + |:; alias ::='' + |${shellCommands.split("\r\n|\n").map(":: " + _).mkString("\n")} + |:: exit""".stripMargin.replaceAll("\r\n|\n", "\n") + ), + Some( + s"""@echo off + |$cmdCommands + |exit /B %errorlevel% + |""".stripMargin.replaceAll("\r\n|\n", "\r\n") + ) + ).flatMap(_.toSeq).mkString("\n") + } + def launcherShellScript(isWin: Boolean, mainClass: String, - classPath: Agg[String], + shellClassPath: Agg[String], + cmdClassPath: Agg[String], jvmArgs: Seq[String]) = { val cp = classPath.mkString(File.pathSeparator) - if (isWin) - s"""@echo off - | - |java ${jvmArgs.mkString(" ")} %JAVA_OPTS% -cp "$cp" $mainClass %* - """.stripMargin.split('\n').mkString("\r\n") - else - s"""#!/usr/bin/env sh - | - |exec java ${jvmArgs.mkString(" ")} $$JAVA_OPTS -cp "$cp" $mainClass "$$@" - """.stripMargin + + universalScript( + shellCommands = + s"""exec java ${jvmArgs.mkString(" ")} $$JAVA_OPTS -cp "${classPath.mkString(":")}" $mainClass "$$@"""", + cmdCommands = + s"""java ${jvmArgs.mkString(" ")} %JAVA_OPTS% -cp "${classPath.mkString(";")}" $mainClass %*""", + shebang = !isWin + ) } def createLauncher(mainClass: String, classPath: Agg[Path], @@ -341,8 +361,9 @@ object Jvm { (implicit ctx: Ctx.Dest)= { val isWin = scala.util.Properties.isWin val outputPath = ctx.dest / (if (isWin) "run.bat" else "run") + val classPathStrs = classPath.map(_.toString) - write(outputPath, launcherShellScript(isWin, mainClass, classPath.map(_.toString), jvmArgs)) + write(outputPath, launcherShellScript(isWin, mainClass, classPathStrs, classPathStrs, jvmArgs)) if (!isWin) { val perms = Files.getPosixFilePermissions(outputPath.toNIO) diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala index fdc83cbf09c..8c22d5e1e5d 100644 --- a/scalalib/src/mill/scalalib/ScalaModule.scala +++ b/scalalib/src/mill/scalalib/ScalaModule.scala @@ -139,7 +139,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer => mill.modules.Jvm.launcherShellScript( isWin, cls, - Agg(if (isWin) "%~dp0%~nx0" else "$0"), + "$0", "%~dpnx0", forkArgs() ) } From fb516cf982f91481a6375551febc8b59bd515295 Mon Sep 17 00:00:00 2001 From: LolHens Date: Wed, 28 Mar 2018 11:11:59 +0200 Subject: [PATCH 2/8] fixed classPath compile error --- main/src/mill/modules/Jvm.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 96bb102d89d..5091956e13d 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -345,13 +345,11 @@ object Jvm { shellClassPath: Agg[String], cmdClassPath: Agg[String], jvmArgs: Seq[String]) = { - val cp = classPath.mkString(File.pathSeparator) - universalScript( shellCommands = - s"""exec java ${jvmArgs.mkString(" ")} $$JAVA_OPTS -cp "${classPath.mkString(":")}" $mainClass "$$@"""", + s"""exec java ${jvmArgs.mkString(" ")} $$JAVA_OPTS -cp "${shellClassPath.mkString(":")}" $mainClass "$$@"""", cmdCommands = - s"""java ${jvmArgs.mkString(" ")} %JAVA_OPTS% -cp "${classPath.mkString(";")}" $mainClass %*""", + s"""java ${jvmArgs.mkString(" ")} %JAVA_OPTS% -cp "${cmdClassPath.mkString(";")}" $mainClass %*""", shebang = !isWin ) } From af1eeada59a6d959f5493061f1ccd72e84d96fb4 Mon Sep 17 00:00:00 2001 From: LolHens Date: Wed, 28 Mar 2018 11:17:25 +0200 Subject: [PATCH 3/8] fixed compile error --- scalalib/src/mill/scalalib/ScalaModule.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala index 8c22d5e1e5d..1d5e829491d 100644 --- a/scalalib/src/mill/scalalib/ScalaModule.scala +++ b/scalalib/src/mill/scalalib/ScalaModule.scala @@ -139,7 +139,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer => mill.modules.Jvm.launcherShellScript( isWin, cls, - "$0", "%~dpnx0", + Agg("$0"), Agg("%~dpnx0"), forkArgs() ) } From 7f772ddb4af595e231b9994df2fd143c29f49b86 Mon Sep 17 00:00:00 2001 From: LolHens Date: Wed, 28 Mar 2018 12:32:59 +0200 Subject: [PATCH 4/8] use other method of universal scripts to prevent scrambling the shell scripts --- build.sc | 28 +++++++++++++--------------- main/src/mill/modules/Jvm.scala | 28 +++++++++++++--------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/build.sc b/build.sc index 22a58c6da56..2bc2c840574 100755 --- a/build.sc +++ b/build.sc @@ -212,21 +212,19 @@ def launcherScript(isWin: Boolean, cmdCommands: String, shebang: Boolean = true): String = { Seq( - Some("#!/usr/bin/env sh") - .filter(_ => shebang), - Some( - s""":; shopt -s expand_aliases - |:; alias ::='' - |${shellCommands.split("\r\n|\n").map(":: " + _).mkString("\n")} - |:: exit""".stripMargin.replaceAll("\r\n|\n", "\n") - ), - Some( - s"""@echo off - |$cmdCommands - |exit /B %errorlevel% - |""".stripMargin.replaceAll("\r\n|\n", "\r\n") - ) - ).flatMap(_.toSeq).mkString("\n") + if (shebang) "#!/usr/bin/env sh" else "", + "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", + shellCommands.replaceAll("\r\n|\n", "\n"), + "exit", + Seq( + "", + ":BOF", + "@echo off", + cmdCommands.replaceAll("\r\n|\n", "\r\n"), + "exit /B %errorlevel%", + "" + ).mkString("\r\n") + ).filterNot(_.isEmpty).mkString("\n") } val jvmArgsStr = jvmArgs.mkString(" ") diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 5091956e13d..996b96e606e 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -323,21 +323,19 @@ object Jvm { cmdCommands: String, shebang: Boolean = true): String = { Seq( - Some("#!/usr/bin/env sh") - .filter(_ => shebang), - Some( - s""":; shopt -s expand_aliases - |:; alias ::='' - |${shellCommands.split("\r\n|\n").map(":: " + _).mkString("\n")} - |:: exit""".stripMargin.replaceAll("\r\n|\n", "\n") - ), - Some( - s"""@echo off - |$cmdCommands - |exit /B %errorlevel% - |""".stripMargin.replaceAll("\r\n|\n", "\r\n") - ) - ).flatMap(_.toSeq).mkString("\n") + if (shebang) "#!/usr/bin/env sh" else "", + "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", + shellCommands.replaceAll("\r\n|\n", "\n"), + "exit", + Seq( + "", + ":BOF", + "@echo off", + cmdCommands.replaceAll("\r\n|\n", "\r\n"), + "exit /B %errorlevel%", + "" + ).mkString("\r\n") + ).filterNot(_.isEmpty).mkString("\n") } def launcherShellScript(isWin: Boolean, From 3bc4263458b445bceaa6d93b92ff6d3e8cb52b4b Mon Sep 17 00:00:00 2001 From: LolHens Date: Wed, 28 Mar 2018 13:00:59 +0200 Subject: [PATCH 5/8] reset exit status after cmd jump --- build.sc | 1 + main/src/mill/modules/Jvm.scala | 1 + 2 files changed, 2 insertions(+) diff --git a/build.sc b/build.sc index 2bc2c840574..7926c8ee636 100755 --- a/build.sc +++ b/build.sc @@ -214,6 +214,7 @@ def launcherScript(isWin: Boolean, Seq( if (shebang) "#!/usr/bin/env sh" else "", "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", + ":", shellCommands.replaceAll("\r\n|\n", "\n"), "exit", Seq( diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 996b96e606e..1062c369bf1 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -325,6 +325,7 @@ object Jvm { Seq( if (shebang) "#!/usr/bin/env sh" else "", "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", + ":", shellCommands.replaceAll("\r\n|\n", "\n"), "exit", Seq( From c137092506ff140dace9ba2c7b60f68f88313224 Mon Sep 17 00:00:00 2001 From: LolHens Date: Thu, 29 Mar 2018 13:14:14 +0200 Subject: [PATCH 6/8] set shebang to false by default and only generate one script --- build.sc | 96 +++++++++++++-------------------- main/src/mill/modules/Jvm.scala | 16 +++--- 2 files changed, 44 insertions(+), 68 deletions(-) diff --git a/build.sc b/build.sc index 7926c8ee636..8c052242d29 100755 --- a/build.sc +++ b/build.sc @@ -205,34 +205,34 @@ object integration extends MillModule{ def forkArgs = testArgs() } -def launcherScript(isWin: Boolean, - jvmArgs: Seq[String], - classPath: Agg[String]) = { - def universalScript(shellCommands: String, - cmdCommands: String, - shebang: Boolean = true): String = { +private def universalScript(shellCommands: String, + cmdCommands: String, + shebang: Boolean = false): String = { + Seq( + if (shebang) "#!/usr/bin/env sh" else "", + "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", + ":", + shellCommands.replaceAll("\r\n|\n", "\n"), + "exit", Seq( - if (shebang) "#!/usr/bin/env sh" else "", - "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", - ":", - shellCommands.replaceAll("\r\n|\n", "\n"), - "exit", - Seq( - "", - ":BOF", - "@echo off", - cmdCommands.replaceAll("\r\n|\n", "\r\n"), - "exit /B %errorlevel%", - "" - ).mkString("\r\n") - ).filterNot(_.isEmpty).mkString("\n") - } + "", + ":BOF", + "@echo off", + cmdCommands.replaceAll("\r\n|\n", "\r\n"), + "exit /B %errorlevel%", + "" + ).mkString("\r\n") + ).filterNot(_.isEmpty).mkString("\n") +} +def launcherScript(jvmArgs: Seq[String], + shellClassPath: Agg[String], + cmdClassPath: Agg[String]) = { val jvmArgsStr = jvmArgs.mkString(" ") universalScript( shellCommands = { def java(mainClass: String) = - s"""exec java $jvmArgsStr $$JAVA_OPTS -cp "${classPath.mkString(":")}" mill.Main "$$@"""" + s"""exec java $jvmArgsStr $$JAVA_OPTS -cp "${shellClassPath.mkString(":")}" mill.Main "$$@"""" s"""case "$$1" in | -i | --interactive ) @@ -245,7 +245,7 @@ def launcherScript(isWin: Boolean, }, cmdCommands = { def java(mainClass: String) = - s"""java $jvmArgsStr %JAVA_OPTS% -cp "${classPath.mkString(";")}" $mainClass %*""" + s"""java $jvmArgsStr %JAVA_OPTS% -cp "${cmdClassPath.mkString(";")}" $mainClass %*""" s"""if "%1" == "-i" set _I_=true |if "%1" == "--interactive" set _I_=true @@ -254,8 +254,7 @@ def launcherScript(isWin: Boolean, |) else ( | ${java("mill.clientserver.Client")} |)""".stripMargin - }, - shebang = !isWin + } ) } @@ -266,7 +265,7 @@ object dev extends MillModule{ } def launcher = T{ val isWin = scala.util.Properties.isWin - val outputPath = T.ctx().dest / (if (isWin) "run.bat" else "run") + val outputPath = T.ctx().dest / "run" write(outputPath, prependShellScript()) @@ -281,12 +280,15 @@ object dev extends MillModule{ } def assembly = T{ - val filename = if (scala.util.Properties.isWin) "mill.bat" else "mill" + val filename = "mill" mv(super.assembly().path, T.ctx().dest / filename) PathRef(T.ctx().dest / filename) } - def prependShellScript = launcherScript(scala.util.Properties.isWin, forkArgs(), runClasspath().map(_.path.toString)) + def prependShellScript = T{ + val classpath = runClasspath().map(_.path.toString) + launcherScript(forkArgs(), classpath, classpath) + } def run(args: String*) = T.command{ args match{ @@ -308,48 +310,27 @@ object dev extends MillModule{ private def releaseHelper(dest: Path, cp: Agg[Path], - ver: String, - isWin: Boolean) + ver: String) (implicit ctx: mill.util.Ctx.Dest): PathRef = { - val (filename, arg) = - if (isWin) ("mill.bat", "%~dp0%~nx0") - else ("mill", "$0") mv( createAssembly( cp, prependShellScript = launcherScript( - isWin, Seq("-DMILL_VERSION=" + ver), - Agg(arg) + Agg("$0"), + Agg("%~dpnx0") ) ).path, - dest / filename + dest / "mill" ) - PathRef(dest / filename) + PathRef(dest / "mill") } def release = T{ releaseHelper( T.ctx().dest, dev.runClasspath().map(_.path), - publishVersion()._2, - false) -} - -def releaseBatch = T{ - releaseHelper( - T.ctx().dest, - dev.runClasspath().map(_.path), - publishVersion()._2, - true) -} - -def releaseAll = T{ - val dest = T.ctx().dest - val cp = dev.runClasspath().map(_.path) - val ver = publishVersion()._2 - for (isWin <- Seq(false, true)) - yield (isWin, releaseHelper(dest, cp, ver, isWin)) + publishVersion()._2) } val isMasterCommit = { @@ -400,8 +381,5 @@ def uploadToGithub(authKey: String) = T.command{ .asString } - for ((isWin, pr) <- releaseAll()) - upload.apply(pr.path, releaseTag, - if (isWin) s"mill-$label.bat" // so browser downloads it as mill-.bat (?) - else label, authKey) + upload.apply(release().path, releaseTag, label, authKey) } diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 1062c369bf1..1c36fc4e8c1 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -321,7 +321,7 @@ object Jvm { def universalScript(shellCommands: String, cmdCommands: String, - shebang: Boolean = true): String = { + shebang: Boolean = false): String = { Seq( if (shebang) "#!/usr/bin/env sh" else "", "@ 2>/dev/null # 2>nul & echo off & goto BOF\r", @@ -339,17 +339,15 @@ object Jvm { ).filterNot(_.isEmpty).mkString("\n") } - def launcherShellScript(isWin: Boolean, - mainClass: String, - shellClassPath: Agg[String], - cmdClassPath: Agg[String], - jvmArgs: Seq[String]) = { + def launcherUniversalScript(mainClass: String, + shellClassPath: Agg[String], + cmdClassPath: Agg[String], + jvmArgs: Seq[String]) = { universalScript( shellCommands = s"""exec java ${jvmArgs.mkString(" ")} $$JAVA_OPTS -cp "${shellClassPath.mkString(":")}" $mainClass "$$@"""", cmdCommands = s"""java ${jvmArgs.mkString(" ")} %JAVA_OPTS% -cp "${cmdClassPath.mkString(";")}" $mainClass %*""", - shebang = !isWin ) } def createLauncher(mainClass: String, @@ -357,10 +355,10 @@ object Jvm { jvmArgs: Seq[String]) (implicit ctx: Ctx.Dest)= { val isWin = scala.util.Properties.isWin - val outputPath = ctx.dest / (if (isWin) "run.bat" else "run") + val outputPath = ctx.dest / "run" val classPathStrs = classPath.map(_.toString) - write(outputPath, launcherShellScript(isWin, mainClass, classPathStrs, classPathStrs, jvmArgs)) + write(outputPath, launcherUniversalScript(isWin, mainClass, classPathStrs, classPathStrs, jvmArgs)) if (!isWin) { val perms = Files.getPosixFilePermissions(outputPath.toNIO) From 7fbfea8d88a5b620fb0c9d69cba1b39dc18a28bd Mon Sep 17 00:00:00 2001 From: Pierre Kisters Date: Thu, 29 Mar 2018 14:02:07 +0200 Subject: [PATCH 7/8] removed unnecessary isWin parameters --- main/src/mill/modules/Jvm.scala | 2 +- scalalib/src/mill/scalalib/ScalaModule.scala | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala index 1c36fc4e8c1..8e9d443eff8 100644 --- a/main/src/mill/modules/Jvm.scala +++ b/main/src/mill/modules/Jvm.scala @@ -358,7 +358,7 @@ object Jvm { val outputPath = ctx.dest / "run" val classPathStrs = classPath.map(_.toString) - write(outputPath, launcherUniversalScript(isWin, mainClass, classPathStrs, classPathStrs, jvmArgs)) + write(outputPath, launcherUniversalScript(mainClass, classPathStrs, classPathStrs, jvmArgs)) if (!isWin) { val perms = Files.getPosixFilePermissions(outputPath.toNIO) diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala index 1d5e829491d..91944308e1f 100644 --- a/scalalib/src/mill/scalalib/ScalaModule.scala +++ b/scalalib/src/mill/scalalib/ScalaModule.scala @@ -136,8 +136,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer => case None => "" case Some(cls) => val isWin = scala.util.Properties.isWin - mill.modules.Jvm.launcherShellScript( - isWin, + mill.modules.Jvm.launcherUniversalScript( cls, Agg("$0"), Agg("%~dpnx0"), forkArgs() From 5b55e15d32d19f7750910a341ecccce1249e2544 Mon Sep 17 00:00:00 2001 From: Pierre Kisters Date: Thu, 29 Mar 2018 23:14:51 +0200 Subject: [PATCH 8/8] restart build --- build.sc | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sc b/build.sc index 8c052242d29..2d5db2c446e 100755 --- a/build.sc +++ b/build.sc @@ -307,7 +307,6 @@ object dev extends MillModule{ } } - private def releaseHelper(dest: Path, cp: Agg[Path], ver: String)