gradle - 在 buildsrc/中多次调用我的插件

标签 gradle gradle-plugin

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

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

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 次。我最接近的一次,插件使用最后提供的值执行一次。

任何人都可以在没有“阅读 gradle 文档的插件部分”的情况下帮助我吗? (我有,但发现它对于 gradle 新手来说非常难以接近!)

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

buildSrc/main/groovy/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
                }
            }
        }
    }
}

最佳答案

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

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

例如:

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

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

关于gradle - 在 buildsrc/中多次调用我的插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47541058/

相关文章:

spring-boot - 如何在gradle中从一个位置复制到另一个位置时动态修改文件

node.js - Node和Google App Engine的CORS问题(等级)

android - 在项目中使用android swipelistview

android - 无法解析 : multidex-instrumentation

android - 我无法在Android Studio中通过Gradle导入库

android - Intellij IDEA 2019中的离线Android Gradle插件3.5.0

更新后 Android gradle 'installDebug' 任务停止工作

maven-plugin - 如何在 Quarkus 中为 Gradle 的外部模块中的类创建 Jandex 索引

android - _apply插件 'com.google.gms.google-services' _做什么?

java - Eclipse Gradle 添加类路径条目