Skip to content

Commit

Permalink
!sbt Use multiJvmPlugin from pekko.
Browse files Browse the repository at this point in the history
  • Loading branch information
He-Pin committed Aug 7, 2023
1 parent 9c5323c commit 1f5b25d
Show file tree
Hide file tree
Showing 5 changed files with 753 additions and 5 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ValidatePullRequest._
import net.bzzt.reproduciblebuilds.ReproducibleBuildsPlugin.reproducibleBuildsCheckResolver
import PekkoDependency._
import Dependencies.{ h2specExe, h2specName }
import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys.MultiJvm
import MultiJvmPlugin.MultiJvmKeys.MultiJvm
import java.nio.file.Files
import java.nio.file.attribute.{ PosixFileAttributeView, PosixFilePermission }

Expand Down
125 changes: 125 additions & 0 deletions project/Jvm.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* license agreements; and to You under the Apache License, version 2.0:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* This file is part of the Apache Pekko project, which was derived from Akka.
*/

/*
* Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
*/

import java.io.File
import java.lang.{ ProcessBuilder => JProcessBuilder }

import sbt._
import scala.sys.process.Process

object Jvm {
def startJvm(
javaBin: File,
jvmOptions: Seq[String],
runOptions: Seq[String],
logger: Logger,
connectInput: Boolean) = {
forkJava(javaBin, jvmOptions ++ runOptions, logger, connectInput)
}

def forkJava(javaBin: File, options: Seq[String], logger: Logger, connectInput: Boolean) = {
val java = javaBin.toString
val command = (java :: options.toList).toArray
val builder = new JProcessBuilder(command: _*)
Process(builder).run(logger, connectInput)
}

/**
* check if the current operating system is some OS
*/
def isOS(os: String) =
try {
System.getProperty("os.name").toUpperCase.startsWith(os.toUpperCase)
} catch {
case _: Throwable => false
}

/**
* convert to proper path for the operating system
*/
def osPath(path: String) = if (isOS("WINDOWS")) Process(Seq("cygpath", path)).lineStream.mkString else path

def getPodName(hostAndUser: String, sbtLogger: Logger): String = {
val command: Array[String] =
Array("kubectl", "get", "pods", "-l", s"host=$hostAndUser", "--no-headers", "-o", "name")
val builder = new JProcessBuilder(command: _*)
sbtLogger.debug("Jvm.getPodName about to run " + command.mkString(" "))
val podName = Process(builder).!!
sbtLogger.debug("Jvm.getPodName podName is " + podName)
podName.stripPrefix("pod/").stripSuffix("\n")
}

def syncJar(jarName: String, hostAndUser: String, remoteDir: String, sbtLogger: Logger): Process = {
val podName = getPodName(hostAndUser, sbtLogger)
val command: Array[String] =
Array("kubectl", "exec", podName, "--", "/bin/bash", "-c", s"rm -rf $remoteDir && mkdir -p $remoteDir")
val builder = new JProcessBuilder(command: _*)
sbtLogger.debug("Jvm.syncJar about to run " + command.mkString(" "))
val process = Process(builder).run(sbtLogger, false)
if (process.exitValue() == 0) {
val command: Array[String] = Array("kubectl", "cp", osPath(jarName), podName + ":" + remoteDir + "/")
val builder = new JProcessBuilder(command: _*)
sbtLogger.debug("Jvm.syncJar about to run " + command.mkString(" "))
Process(builder).run(sbtLogger, false)
} else {
process
}
}

def forkRemoteJava(
java: String,
jvmOptions: Seq[String],
appOptions: Seq[String],
jarName: String,
hostAndUser: String,
remoteDir: String,
logger: Logger,
connectInput: Boolean,
sbtLogger: Logger): Process = {
val podName = getPodName(hostAndUser, sbtLogger)
sbtLogger.debug("About to use java " + java)
val shortJarName = new File(jarName).getName
val javaCommand = List(List(java), jvmOptions, List("-cp", shortJarName), appOptions).flatten
val command = Array(
"kubectl",
"exec",
podName,
"--",
"/bin/bash",
"-c",
("cd " :: (remoteDir :: (" ; " :: javaCommand))).mkString(" "))
sbtLogger.debug("Jvm.forkRemoteJava about to run " + command.mkString(" "))
val builder = new JProcessBuilder(command: _*)
Process(builder).run(logger, connectInput)
}
}

class JvmBasicLogger(name: String) extends BasicLogger {
def jvm(message: String) = "[%s] %s".format(name, message)

def log(level: Level.Value, message: => String) = System.out.synchronized {
System.out.println(jvm(message))
}

def trace(t: => Throwable) = System.out.synchronized {
val traceLevel = getTrace
if (traceLevel >= 0) System.out.print(StackTrace.trimmed(t, traceLevel))
}

def success(message: => String) = log(Level.Info, message)
def control(event: ControlEvent.Value, message: => String) = log(Level.Info, message)

def logAll(events: Seq[LogEvent]) = System.out.synchronized { events.foreach(log) }
}

final class JvmLogger(name: String) extends JvmBasicLogger(name)
6 changes: 3 additions & 3 deletions project/MultiNode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* Copyright (C) 2009-2020 Lightbend Inc. <https://www.lightbend.com>
*/

import com.typesafe.sbt.SbtMultiJvm
import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys._
import MultiJvmPlugin.MultiJvmKeys.multiJvmCreateLogger
import MultiJvmPlugin.MultiJvmKeys._
import sbt._
import sbt.Keys._

Expand Down Expand Up @@ -57,7 +57,7 @@ object MultiNode extends AutoPlugin {
}

private val multiJvmSettings =
SbtMultiJvm.multiJvmSettings ++
MultiJvmPlugin.multiJvmSettings ++
inConfig(MultiJvm)(org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings) ++
inConfig(MultiJvm)(Seq(
MultiJvm / jvmOptions := defaultMultiJvmOptions,
Expand Down
Loading

0 comments on commit 1f5b25d

Please sign in to comment.