Skip to content

Commit

Permalink
Universal script generation for assembly, launcher, and release (com-…
Browse files Browse the repository at this point in the history
  • Loading branch information
LolHens authored and leakyabstraction committed Apr 2, 2018
1 parent e322320 commit 7759887
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 84 deletions.
126 changes: 63 additions & 63 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -205,35 +205,57 @@ object integration extends MillModule{
def forkArgs = testArgs()
}

def launcherScript(isWin: Boolean,
jvmArgs: Seq[String],
classPath: Agg[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(
"",
":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(" ")
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 "${shellClassPath.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 "${cmdClassPath.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
}
)
}

object dev extends MillModule{
Expand All @@ -243,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())

Expand All @@ -258,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{
Expand All @@ -282,51 +307,29 @@ 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 = {
Expand Down Expand Up @@ -377,8 +380,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-<version>.bat (?)
else label, authKey)
upload.apply(release().path, releaseTag, label, authKey)
}
52 changes: 34 additions & 18 deletions main/src/mill/modules/Jvm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -319,30 +319,46 @@ object Jvm {

}

def launcherShellScript(isWin: Boolean,
mainClass: String,
classPath: 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
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(
"",
":BOF",
"@echo off",
cmdCommands.replaceAll("\r\n|\n", "\r\n"),
"exit /B %errorlevel%",
""
).mkString("\r\n")
).filterNot(_.isEmpty).mkString("\n")
}

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 %*""",
)
}
def createLauncher(mainClass: String,
classPath: Agg[Path],
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, classPath.map(_.toString), jvmArgs))
write(outputPath, launcherUniversalScript(mainClass, classPathStrs, classPathStrs, jvmArgs))

if (!isWin) {
val perms = Files.getPosixFilePermissions(outputPath.toNIO)
Expand Down
5 changes: 2 additions & 3 deletions scalalib/src/mill/scalalib/ScalaModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,9 @@ 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(if (isWin) "%~dp0%~nx0" else "$0"),
Agg("$0"), Agg("%~dpnx0"),
forkArgs()
)
}
Expand Down

0 comments on commit 7759887

Please sign in to comment.