Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api/src/main/scala/org/scastie/api/Inputs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import io.circe.generic.semiauto._
import io.circe._
import org.scastie.buildinfo.BuildInfo

import java.security.MessageDigest

import System.{lineSeparator => nl}

sealed trait BaseInputs {
Expand Down Expand Up @@ -138,6 +140,9 @@ case class SbtInputs(
sbtInputs != other.sbtInputs
}

def toHash: String =
MessageDigest.getInstance("SHA-256").digest(SbtInputs.sbtInputsEncoder(this).noSpaces.getBytes).map("%02x".format(_)).mkString

override def toString: String = {
if (this == SbtInputs.default) {
"Inputs.default"
Expand Down
45 changes: 39 additions & 6 deletions sbt-runner/src/main/scala/org/scastie/sbt/SbtProcess.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,31 @@ object SbtProcess {

sealed trait Data
case class SbtData(currentInputs: SbtInputs) extends Data

case class CompilationInfoCache(
infos: List[Problem] = Nil,
inputsHash: Option[String] = None
) {
def refreshIfValid(
progress: SnippetProgress,
newInputsHash: String
): CompilationInfoCache = {
if (progress.compilationInfos.nonEmpty && !progress.isTimeout) {
this.copy(infos = progress.compilationInfos, inputsHash = Some(newInputsHash))
} else {
this
}
}
}
case class SbtRun(
snippetId: SnippetId,
inputs: SbtInputs,
isForcedProgramMode: Boolean,
progressActor: ActorRef,
snippetActor: ActorRef,
timeoutEvent: Option[Cancellable],
lineMapping: Int => Int = identity
lineMapping: Int => Int = identity,
inputsHash: String
) extends Data
case class SbtStateTimeout(duration: FiniteDuration, state: SbtState) {
def message: String = {
Expand Down Expand Up @@ -75,16 +92,31 @@ class SbtProcess(runTimeout: FiniteDuration,
import context.dispatcher

private var progressId = 0L
private var compilationInfoCache = CompilationInfoCache()

def sendProgress(run: SbtRun, _p: SnippetProgress): Unit = {
compilationInfoCache = compilationInfoCache.refreshIfValid(_p, run.inputsHash)

val shouldCopyWarnings =
_p.compilationInfos.isEmpty &&
compilationInfoCache.inputsHash.contains(run.inputsHash) &&
compilationInfoCache.infos.nonEmpty &&
_p.runtimeError.isEmpty &&
!_p.isTimeout

val p = if (shouldCopyWarnings)
_p.copy(compilationInfos = compilationInfoCache.infos)
else
_p

progressId += 1
val p = _p.copy(id = Some(progressId))
run.progressActor ! p
val pWithId = p.copy(id = Some(progressId))
run.progressActor ! pWithId
implicit val tm = Timeout(10.seconds)
(run.snippetActor ? p)
(run.snippetActor ? pWithId)
.recover {
case e =>
log.error(e, s"error while saving progress $p")
log.error(e, s"error while saving progress $pWithId")
}
}

Expand Down Expand Up @@ -187,7 +219,8 @@ class SbtProcess(runTimeout: FiniteDuration,
isForcedProgramMode = false,
progressActor = progressActor,
snippetActor = sender(),
timeoutEvent = None
timeoutEvent = None,
inputsHash = taskInputs.toHash
)
sendProgress(_sbtRun, SnippetProgress.default.copy(isDone = false, ts = Some(Instant.now.toEpochMilli), snippetId = Some(snippetId)))

Expand Down
8 changes: 8 additions & 0 deletions sbt-runner/src/test/scala/org/scastie/sbt/SbtActorTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,14 @@ class SbtActorTest() extends TestKit(ActorSystem("SbtActorTest")) with ImplicitS
})
}

(1 to 2).foreach { i =>
test(s"[$i] warnings persist (issue #1144)") {
runCode("Nil match { case Seq(xs*) => println(\"test\") }")( progress =>
progress.compilationInfos.nonEmpty
)
}
}

def assertCompilationInfo(
infoAssert: Problem => Any
)(progress: SnippetProgress): Boolean = {
Expand Down
Loading