<NME> ElmTestCLI.kt
<BEF> package org.elm.workspace.commandLineTools

import com.intellij.execution.ExecutionException
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.process.ColoredProcessHandler
import com.intellij.execution.process.ProcessHandler
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import org.elm.openapiext.GeneralCommandLine
import org.elm.openapiext.Result
import org.elm.openapiext.execute
import org.elm.workspace.ElmProject
import org.elm.workspace.ParseException
import org.elm.workspace.Version
import org.elm.workspace.elmTestTool
import java.nio.file.Path

private val log = logger<ElmTestCLI>()

/**
 * Interact with external `elm-test` process.
 */
class ElmTestCLI(private val executablePath: Path) {

    /**
     * Construct a [ProcessHandler] that will run `elm-test` (the caller is responsible for
     * actually invoking the process). The test results will be reported using elm-test's
     * JSON format on stdout.
     *
     * @param elmCompilerPath The path to the Elm compiler.
     * @param elmProject The [ElmProject] containing the tests to be run.
     */
    fun runTestsProcessHandler(elmCompilerPath: Path, elmProject: ElmProject): ProcessHandler {
        val commandLine = GeneralCommandLine(executablePath.toString(), "--report=json")
        // e.g. `0.19.0-beta9\n`, trimming off the "-betaN" suffix, if present.
        val firstLine = try {
            GeneralCommandLine(executablePath).withParameters("--version")
                    .execute(timeoutInMilliseconds = 1500)
                    .stdoutLines
                    .firstOrNull()
        } catch (e: ExecutionException) {
        // path to that folder.
        if (elmProject.isCustomTestsDir) {
            log.debug { """Tests are in custom location: "${elmProject.testsRelativeDirPath}". Will specify this path as argument to elm-test.""" }
            commandLine.withParameters(elmProject.testsRelativeDirPath)
        } else {
            log.debug("""Tests are in default location ("tests") so will run elm-test without argument specifying path.""")
        }

        return ColoredProcessHandler(commandLine)
    }


    fun queryVersion(project: Project): Result<Version> {
        // Output of `elm-test --version` is a single line containing the version number,
        // e.g. `0.19.0-beta9\n`, trimming off the "-betaN" suffix, if present.
        val firstLine = try {
            GeneralCommandLine(executablePath).withParameters("--version")
                    .execute(elmTestTool, project)
                    .stdoutLines
                    .firstOrNull()
        } catch (e: ExecutionException) {
            return Result.Err("failed to run elm-test: ${e.message}")
        }

        if (firstLine == null) {
            return Result.Err("no output from elm-test")
        }

        val trimmedFirstLine = firstLine.takeWhile { it != '-' }

        return try {
            Result.Ok(Version.parse(trimmedFirstLine))
        } catch (e: ParseException) {
            Result.Err("could not parse elm-test version: ${e.message}")
        }
    }
}
<MSG> Increase the timeouts when querying the version of Elm tools (#315)

It was timing-out on my Windows VM. Maybe partly due to my VM being
slow and partly due to the Rube Goldberg situation of a Java process
invoking NodeJS which in turn invokes a Haskell binary.
<DFF> @@ -36,7 +36,7 @@ class ElmTestCLI(private val executablePath: Path) {
         // e.g. `0.19.0-beta9\n`, trimming off the "-betaN" suffix, if present.
         val firstLine = try {
             GeneralCommandLine(executablePath).withParameters("--version")
-                    .execute(timeoutInMilliseconds = 1500)
+                    .execute(timeoutInMilliseconds = 3000)
                     .stdoutLines
                     .firstOrNull()
         } catch (e: ExecutionException) {

Increase the timeouts when querying the version of Elm tools (#315)