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

org.danilopianini.gradle.latex.LatexTask.kt Maven / Gradle / Ivy

There is a newer version: 0.2.7
Show newest version
package org.danilopianini.gradle.latex

import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.FileCollection
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputFile
import org.gradle.kotlin.dsl.get
import java.io.File
import java.io.PrintWriter
import java.util.concurrent.TimeUnit
import kotlin.system.exitProcess

abstract class LatexTask : DefaultTask() {
    /**
     * Latex artifact used to run current task.
     */
    lateinit var artifact: LatexArtifact
    val extension: LatexExtension = project.extensions.get(Latex.EXTENSION_NAME) as LatexExtension

    init {
        group = Latex.TASK_GROUP
        logging.captureStandardError(LogLevel.ERROR)
        logging.captureStandardOutput(LogLevel.ERROR)
    }
    /**
     * Collection of all files whose change should trigger this task.
     * Collected for Gradle's continuous build feature.
     * Contains the following (based on the Latex artifact):
     * - main TeX file
     * - bib file, if there is one
     * - outputs (PDF) of dependent TeX files
     * - auxiliary files/folders
     */
    @InputFiles
    open fun inputFiles(): FileCollection = project.files(*artifact.flattenDependencies().toTypedArray())

    /**
     * Output of current task. Not used by task itself.
     * Set for Gradle's continuous build feature.
     */
    @OutputFile
    open fun pdf() = artifact.pdf

    fun String.runScript(
        terminalEmulator: String = extension.terminalEmulator.get(),
        from: File = project.projectDir,
        waitTime: Long = extension.waitTime.get(),
        waitUnit: TimeUnit = extension.waitUnit.get(),
        whenFails: (Int, String, String) -> Unit = { exit, stdout, stderr ->
            throw GradleException("Process $this terminated with non-zero value $exit.\nStandard error: \n$stderr\n\nStandard output:\n$stdout")
        }
    ) {
        val stderr = createTempFile()
        val stdout = createTempFile()
        val shell = ProcessBuilder(terminalEmulator)
            .directory(from)
            .redirectError(stderr)
            .redirectOutput(stdout)
            .start()
        shell.inputStream.copyTo(System.out)
        PrintWriter(shell.outputStream).use {
            Latex.LOG.debug("Launching {} in {} from directory {}, waiting up to {} {} for termination.", this, terminalEmulator, from, waitTime, waitUnit);
            it.println("$this \n exit")
        }
        val terminatedNaturally = shell.waitFor(waitTime, waitUnit)
        if (!terminatedNaturally) {
            throw GradleException("Process $this stalled and was forcibly terminated due to timeout. If the process was not interactive, consider using longer timeouts.")
        }
        shell.exitValue().takeIf { it != 0 }?.let { whenFails (it, stderr.readText(), stdout.readText()) }
        Latex.LOG.debug("{} completed successfully", this)
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy