All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.gradle.internal.exec.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC3
Show newest version
/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.gradle.internal

import jetbrains.buildServer.messages.serviceMessages.ServiceMessageParserCallback
import org.gradle.api.Project
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.internal.logging.progress.ProgressLogger
import org.gradle.internal.service.ServiceRegistry
import org.gradle.process.ExecResult
import org.gradle.process.internal.ExecAction
import org.gradle.process.internal.ExecActionFactory
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessageOutputStreamHandler
import java.io.ByteArrayOutputStream
import java.io.PipedInputStream
import java.io.PipedOutputStream
import kotlin.concurrent.thread

internal fun ServiceRegistry.execWithProgress(description: String, readStdErr: Boolean = false, body: (ExecAction) -> Unit): ExecResult {
    val stderr = ByteArrayOutputStream()
    val stdout = StringBuilder()
    val stdInPipe = PipedInputStream()
    val exec = get(ExecActionFactory::class.java).newExecAction()
    body(exec)
    return operation(description) {
        progress(description)
        exec.standardOutput = PipedOutputStream(stdInPipe)
        val outputReaderThread = thread(name = "output reader for [$description]") {
            stdInPipe.reader().use { reader ->
                val buffer = StringBuilder()
                while (true) {
                    val read = reader.read()
                    if (read == -1) break
                    val ch = read.toChar()
                    if (ch == '\b' || ch == '\n' || ch == '\r') {
                        if (buffer.isNotEmpty()) {
                            val str = buffer.toString()
                            stdout.append(str)
                            progress(str.trim())
                            buffer.setLength(0)
                        }
                        stdout.append(ch)
                    } else buffer.append(ch)
                }
            }
        }
        if (readStdErr) {
            exec.errorOutput = exec.standardOutput
        } else {
            exec.errorOutput = System.err
        }
        exec.isIgnoreExitValue = true
        val result = exec.execute()
        outputReaderThread.join()
        if (result.exitValue != 0) {
            error(
                """
                Process '$description' returns ${result.exitValue}
                $stderr
                $stdout
                """.trimIndent()
            )
        }
        result
    }
}

internal fun ServiceRegistry.execWithErrorLogger(
    description: String,
    body: (ExecAction, ProgressLogger) -> Pair
): ExecResult {
    val exec = get(ExecActionFactory::class.java).newExecAction()
    return operation(description) {
        progress(description)
        val (standardClient, errorClient) = body(exec, this)
        exec.isIgnoreExitValue = true
        val result = exec.execute()
        if (result.exitValue != 0) {
            error(
                errorClient.testFailedMessage()
                    ?: standardClient.testFailedMessage()
                    ?: "Error occurred. See log for details."
            )
        }
        result
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy