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

co.tomlee.gradle.plugins.protoc.tasks.ProtobufCompile.groovy Maven / Gradle / Ivy

Go to download

Gradle plugin for protoc, the code generator typically associated with Google's Protocol Buffers

There is a newer version: 0.0.3
Show newest version
package co.tomlee.gradle.plugins.protoc.tasks

import org.gradle.api.DefaultTask
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileTree;
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectories
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction

import co.tomlee.gradle.plugins.protoc.domain.ProtocPlugin

import org.gradle.api.GradleException

class ProtobufCompile extends DefaultTask {
    String protoc
    NamedDomainObjectContainer plugins = project.container(ProtocPlugin)
    List path = []

    @TaskAction
    def invokeProtoc() {
        def command = buildCommand()
        project.logger.info(command.join(" "))
        ensureOutputDirectoriesExist()
        def p = command.execute()
        if (project.logger.quietEnabled) {
            p.waitFor()
        }
        else {
            p.waitForProcessOutput(System.out, System.err)
        }
        if (p.exitValue() != 0) {
            throw new GradleException("${protocExecutable()} command failed")
        }
    }

    @OutputDirectories
    def outputDirectories() {
        def result = []
        plugins.each { ProtocPlugin plugin ->
            result << (plugin.out != null ? plugin.out : project.file("src/main/${plugin.name}"))
        }
        return result
    }
    
    private void ensureOutputDirectoriesExist() {
        outputDirectories().each { File dir ->
            if (!dir.exists()) {
                if (!dir.mkdirs()) {
                    throw new GradleException("Failed to create output directory: ${dir.absolutePath}")
                }
            }
            if (!dir.isDirectory()) {
                throw new GradleException("Specified output path is not a directory: ${dir.absolutePath}")
            }
        }
    }
    
    String protocExecutable() {
        return (this.protoc != null ? this.protoc : project.protoc.executable)
    }
    
    List buildCommand() {
        def protoc = protocExecutable()
        def command = [protoc]
        project.protoc.path.each { File includePath ->
            command << "-I${includePath.absolutePath}"
        }
        path.each { File includePath ->
            command << "-I${includePath.absolutePath}"
        }
        def builtins = ["java", "cpp", "python"]
        plugins.each { ProtocPlugin plugin ->
            if (!builtins.contains(plugin.name)) {
                if (plugin.executable != null) {
                    command << "--plugin=${plugin.name}=${plugin.executable}".toString()
                }
                else {
                    command << "--plugin=${plugin.name}".toString()
                }
            }
            def optionsPrefix = ""
            if (plugin.options.size() > 0) {
                def options = plugin.options.collect { option -> "${option.key}=${option.value}" }.join(",")
                optionsPrefix = options + ":"
            }
            // FIXME code duplication: see pluginOutDir
            def outDir = plugin.out != null ? plugin.out : project.file("src/main/${plugin.name}")
            command << "--${plugin.name}_out=${optionsPrefix}${outDir.absolutePath}"
        }
        def sources = this.inputs.files
        if (!sources.any()) {
            throw new GradleException("No protobuf sources found in ")
        }
        sources.each { command << it.absolutePath }
        return command
    }

    def protoc(String protoc) {
        this.protoc = protoc
    }
    
    def plugins(Closure c) {
        plugins.configure(c)
    }
    
    def srcDir(File srcDir) {
        this.srcDir = srcDir
    }
    
    def path(String pathItem) {
        final File file = new File(pathItem);
        if (file.isAbsolute()) {
            this.path << file
        }
        else {
            this.path = project.file(pathItem)
        }
    }
    
    def path(File pathItem) {
        this.path << pathItem
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy