在buildsrc中多次调用我的插件

时间:2017-11-28 21:15:28

标签: gradle gradle-plugin

我有一个monolythic build.gradle来构建一个应用程序。它由几个任务组成(缩小,组合文件,gzip,上传到CDN,调用外部脚本等)

我设法将build.gradle中的所有内容移到buildsrc/中的自定义插件中,遵循文档中的GreetingPlugin官方Gradle教程。经过一番努力,我现在可以从build.gradle成功调用它,并且它按预期工作:

group 'CDN'
version '1.0-SNAPSHOT'

buildscript {
    .
    .
}

println "building user app"
apply plugin: BuildAppModule
appmodulebuilder.modulename = 'user'

到目前为止一切顺利。但我将所有内容移到buildsrc /中的插件的目的是能够多次调用此插件来构建不同的模块。

天真地,我试过这个:

.
.
println "building user app"
apply plugin: BuildAppModule
appmodulebuilder.modulename = 'user'

println "building admin app"
apply plugin: BuildAppModule
appmodulebuilder.modulename = 'admin'

和这个

task buildUser {
    println "building user app"
    apply plugin: BuildAppModule
    appmodulebuilder.modulename = 'user'
}
task buildAdmin {
    println "building admin app"
    apply plugin: BuildAppModule
    appmodulebuilder.modulename = 'admin'
}

和这个

task buildUser {
    doLast {
        println "building user app"
        apply plugin: BuildAppModule
        appmodulebuilder.modulename = 'user'
    }
}
task buildAdmin {
    doLast {
        println "building admin app"
        apply plugin: BuildAppModule
        appmodulebuilder.modulename = 'admin'
    }
}

和这个

  apply plugin: BuildAppModule
  task buildUser (Type: BuildAppModule) {
        doLast {
            println "building user app"
            appmodulebuilder.modulename = 'user'
        }
    }
    task buildAdmin (Type: BuildAppModule) {
        doLast {
            println "building admin app"
            appmodulebuilder.modulename = 'admin'
        }
    }

然而,该插件永远不会被执行2次。我最接近的是,插件使用最后提供的值执行一次。

任何人都可以在没有&#34的情况下帮助我;阅读gradle文档的插件部分" - 有点回答? (我有,但发现对于新手来说非常难以接近!)

编辑:整个插件,我的需要是在一组目录上执行它。

buildSrc /主/常规/ BuildAppModule.groovy

import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.tasks.Exec;

class BuildAppModuleExtension {
    String modulename
}

class  BuildAppModule implements Plugin<Project> {


    void apply(Project project) {

        def extension = project.extensions.create('appmodulebuilder', BuildAppModuleExtension)

        project.afterEvaluate {
            println "-----------------------------"
            println extension.modulename
            println "-----------------------------"
        }

        def APP = extension.modulename
        def buildDir = project.getBuildDir()

        project.configure(project) {

            apply plugin: 'js'
            javascript.source {
                /** common libraries */
                lib {
                    js {
                        srcDir 'src/lib'
                        include "*.js"
                    }
                }

                /** specific app files */
                appfiles {
                    js {
                        srcDir "src/app/${APP}"
                        include "*.js"
                    }
                }

                closurein {
                    js {
                        srcDir 'src/lib/closure'
                        include "in.jst"
                    }
                }
                closureout {
                    js {
                        srcDir 'src/lib/closure'
                        include "out.jst"
                    }
                }
            }

            // Configure the built-in task
            combineJs {
                source = [ javascript.source.closurein.js.files, javascript.source.lib.js.files, javascript.source.appfiles.js.files, javascript.source.closureout.js.files ]
                dest = file("${buildDir}/${APP}/js/code.debug.js")
            }


            minifyJs {
                source = combineJs
                dest = file("${buildDir}/${APP}/js/code.min.js")
                sourceMap = file("${buildDir}/${APP}/js/code.sourcemap.json")
                closure {
                    warningLevel = 'QUIET'
                }
                dependsOn 'undebug'
            }

            gzipJs {
                source=file("${buildDir}/${APP}/js/code.min.js")
                dest = file("${buildDir}/out/app/lib-${APP}/code.js")
            }

            apply plugin: 'css'
            css.source {
                lib {
                    css {
                        srcDir 'src/res'
                        include "*.css"
                    }
                }
                appfiles {
                    css {
                        srcDir "src/app/${APP}/res"
                        include "*.css"
                    }
                }
            }

            // Specify a collection of files to be combined, then minified and finally GZip compressed.

            combineCss {
                source =  [css.source.lib.css.files, css.source.appfiles.css.files]
                dest = "${buildDir}/${APP}/res/style.all.css"
            }

            minifyCss {
                source = combineCss
                dest = "${buildDir}/${APP}/res/style.min.css"
                yuicompressor { // Optional
                    lineBreakPos = -1
                }
            }

            gzipCss {
                dependsOn 'minifyCss'
                source = minifyCss
                dest = "${buildDir}/out/app/lib-${APP}/style.css"
            }

        }
        project.task('gzipHtml') {

           doLast {

               def uploadOut = new ByteArrayOutputStream()

               getProject().exec {

                   println "$buildDir"
                   commandLine "scripts/dohtml.sh","src/app","$buildDir/out/app", "$APP"
                   standardOutput = uploadOut

               }

               println uploadOut
           }
        }

        /** upload module to the CDN, the final step */
        project.task('upload') {


            dependsOn 'gzipJs'
            dependsOn 'gzipHtml'

            doLast {

                println "UPLOAD $APP"
                def uploadOut = new ByteArrayOutputStream()

                getProject().exec {

                    println "$buildDir"
                    commandLine "scripts/upload.sh","$buildDir/out/app/","s3://xxxxxxx/public/app/"
                    standardOutput = uploadOut

                }

                println uploadOut

            }

            /** remove window.console.log from the combined JS file */
            project.task('undebug') {

                dependsOn 'combineJs'

                doLast {

                    def uploadOut = new ByteArrayOutputStream()

                    getProject().exec {

                        println "UNDEBUG $APP"
                        commandLine "scripts/undebug.sh","${buildDir}/${APP}/js/code.debug.js"
                        standardOutput = uploadOut

                    }

                    println uploadOut
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

插件只能应用于项目一次。任何尝试在第二次或以后的时间应用相同的插件都将无效。

我觉得你的插件应该添加一个extension object,可以在应用插件后进行配置。

例如:

apply plugin: BuildAppModule
appModuleBuilder {
    moduleNames = ['user', 'admin']        
}

或者

apply plugin: BuildAppModule
appModuleBuilder {
    module {
        name = 'user'
        type = 'xxx'
    }
    module {
        name = 'admin'
        type = 'yyy'
    }
}