从自定义任务内部运行 gradle 任务



我有一个自定义任务,它读取在项目的build.gradle中定义的变量,然后将这些值传递给maven-publish任务,以便它可以在适当的位置发布工件。

问题:

当我运行自定义任务时,它会抛出一个错误

org.gradle.api.InvalidUserDataException: Cannot configure the 'publishing' extension after it has been accessed.

当我从 getProject().gradle.taskGraph.whenReady 调用 publishTask() 时。

目的:

在我的自定义任务从 build.gradle 文件中获取值后运行 maven-publish 任务。(gradle 在生成图表之前不会填充这些值,我可能是错的,因为我不太熟悉 gradle 开发)

BuildAndUpload.groovy:

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.execution.TaskExecutionGraph
import org.gradle.api.internal.tasks.options.Option
import org.gradle.api.tasks.Input
import org.gradle.api.DefaultTask
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.TaskAction
/**
 * Created by Umer on 12/01/2019.
 */
class BuildAndUpload extends BaseTask {
    @Input
    def remoteArtifactRepoURL = ""
    @Input
    def localDiskArtifactRepoURL = ""
    @Input
    def _artifactID = "mdm"
    @Input
    def _groupID = "com.picavi"
    @Input
    def pushToRemoteArtifactRepo = false
    boolean isBuildAndUploadExecutedExplicitly = false;
    public BuildAndUpload() {
        getProject().gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
            publishTask()
        }
    }
    def publishTask() {
        if(getProject().getPlugins().hasPlugin("com.android.library")) {
            getProject().android.libraryVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "${_groupID}-${_artifactID}-${getProject().android.defaultConfig.versionName}.aar"
                }
            }
                getProject().publishing {
                    println "url is: " + getRepoUrl()
                    //publish to filesystem repo
                    repositories {
                        maven {
                            url getRepoUrl()
                        }
                    }
                    populateVariablesValue();//reads values from build.gradle of the project
                    publications {
                        println "inside publications"
                        maven(MavenPublication) {
                            println "inside publications->maven"
                            groupId _groupID //You can either define these here or get them from project conf elsewhere
                            artifactId _artifactID
                            version getProject().android.defaultConfig.versionName
                            artifact(getProject().getBuildDir().path + "/outputs/aar/" + _groupID + "-" + _artifactID + "-" + getProject().android.defaultConfig.versionName + ".aar") {
                                //aar artifact you want to publish
                                println "inside publications->maven->artifact"
                                builtBy getProject().getTasks().getByName("assembleDebug")
                            }
                            //generate pom nodes for dependencies
                            pom.withXml {
                                def dependenciesNode = asNode().appendNode('dependencies')
                                println "about to create pom file bsaed on CONFIGURATIONS"
                                getProject().getConfigurations().compile.allDependencies.each { dependency ->
                                    def dependencyNode = dependenciesNode.appendNode('dependency')
                                    dependencyNode.appendNode('groupId', dependency.group)
                                    dependencyNode.appendNode('artifactId', dependency.name)
                                    dependencyNode.appendNode('version', dependency.version)
                                }
                            }
                        }
                    }
                }
        }
        else
            println getProject().name + " PROJECT is not a library project"
    }
    def populateVariablesValue() {
        this._artifactID = getProject()._artifactID.size() > 0 ? getProject()._artifactID : "PLEASE PROVIDE ARTIFACT ID!";
        this._groupID = getProject()._groupID.size() > 0 ? getProject()._groupID : "PLEASE PROVIDE GROUP ID!";
        this.remoteArtifactRepoURL = getProject()._remoteArtifactRepoURL.size() > 0 ? getProject()._remoteArtifactRepoURL : "PLEASE PROVIDE REMOTE REPO URL";
        this.localDiskArtifactRepoURL = getProject()._localDiskArtifactRepoURL.size() > 0 ? getProject()._localDiskArtifactRepoURL : "PLEASE PROVIDE LOCAL DISK REPO URL";
        this.pushToRemoteArtifactRepo = getProject()._pushToRemoteArtifactRepo;
        println "_groupID "+ _groupID + " _artifactId: "+ _artifactID
    }
    def getRepoUrl() {
        println "inside getRepoURL"
        println "inside pushToRemoteArtifactRepo: "+ pushToRemoteArtifactRepo
        println "inside remoteArtifactRepoURL: "+ remoteArtifactRepoURL
        println "inside localDiskArtifactRepoURL: "+ localDiskArtifactRepoURL
        return (pushToRemoteArtifactRepo ? remoteArtifactRepoURL : localDiskArtifactRepoURL);
    }
    @TaskAction
    public void readCommandLineArguments() {
        println "Starting to run BuildAndUpload Task"
    }
}

UmerPlugins.groovy:

/**
 * Created by Umer on 25/12/2018.
 */
class PicaviPlugins implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.getPluginManager().apply("maven-publish")
        BuildAndUpload buildAndUpload = project.getTasks().create("buildAndUploadTest", BuildAndUpload.class);
        project.getTasks().getByName("buildAndUploadTest").dependsOn("publish");
    }
}

错误堆栈跟踪:

inside publishTask() isBuildAndUploadExecutedExplicitly: false
INSIDE PUBLISH TASK method
FAILURE: Build failed with an exception.
* What went wrong:
Cannot configure the 'publishing' extension after it has been accessed.
* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Exception is:
org.gradle.api.InvalidUserDataException: Cannot configure the 'publishing' extension after it has been accessed.
        at org.gradle.api.internal.plugins.ExtensionsStorage$DeferredConfigurableExtensionHolder.configureLater(ExtensionsStorage.java:216)
        at org.gradle.api.internal.plugins.ExtensionsStorage$DeferredConfigurableExtensionHolder.configure(ExtensionsStorage.java:210)
        at org.gradle.api.internal.plugins.ExtensionsStorage.configureExtension(ExtensionsStorage.java:67)
        at org.gradle.api.internal.plugins.DefaultConvention.configureExtension(DefaultConvention.java:399)
        at org.gradle.api.internal.plugins.DefaultConvention.access$500(DefaultConvention.java:45)
        at org.gradle.api.internal.plugins.DefaultConvention$ExtensionsDynamicObject.tryInvokeMethod(DefaultConvention.java:336)
        at org.gradle.internal.metaobject.CompositeDynamicObject.tryInvokeMethod(CompositeDynamicObject.java:98)
        at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.tryInvokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
        at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:160)
        at org.gradle.api.internal.project.DefaultProject_Decorated.invokeMethod(Unknown Source)
        at com.picavi.gradlePlugins.plugins.BuildAndUpload.publishTask(BuildAndUpload.groovy:56)
        at com.picavi.gradlePlugins.plugins.BuildAndUpload$_closure1.doCall(BuildAndUpload.groovy:37)
        at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)
        at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
        at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
        at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
        at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
        at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy102.graphPopulated(Unknown Source)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:128)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:46)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
        at org.gradle.initialization.DefaultGradleLauncher$ExecuteTasks.run(DefaultGradleLauncher.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.initialization.DefaultGradleLauncher.runTasks(DefaultGradleLauncher.java:210)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:140)
        at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:115)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
        at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
        at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
        at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:49)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:32)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
        at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:57)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
        at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:45)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)

* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_warnings
BUILD FAILED in 5s

解决方案是使用惰性 GString。这解决了 maven-publish 任务在 gradle 配置阶段获得空/空值的问题,因为 gradle 图尚未完全生成。使用惰性gStrings可以解决这个问题。所以时髦的代码看起来像这样:

def populateVariablesValue() {
        def remoteURL = "${->project._remoteArtifactRepoURL}";
        def localURL = "${->project._localDiskArtifactRepoURL}";
        def arID = "${->project._artifactID}";
        def gID = "${->project._groupID}";
        def pushToRemote = "${->project._pushToRemoteArtifactRepo}";
        this._artifactID = arID.size() > 0 ? arID: "PLEASE PROVIDE ARTIFACT ID!";
        this._groupID = gID > 0 ? gID : "PLEASE PROVIDE GROUP ID!";
        this.remoteArtifactRepoURL = remoteURL.size() > 0 ? remoteURL : "PLEASE PROVIDE REMOTE REPO URL";
        this.localDiskArtifactRepoURL = localURL.size() > 0 ? localURL : "PLEASE PROVIDE LOCAL DISK REPO URL";
        this.pushToRemoteArtifactRepo = pushToRemote;
        println "INSIDE POPULATE VARIABLES VALUES:: _groupID "+ _groupID + " _artifactId: "+ _artifactID + " pushToRemote: "+ "${->project._pushToRemoteArtifactRepo}"
    }
    def getRepoUrl() {
        println "inside getRepoURL"
        println "inside pushToRemoteArtifactRepo: "+ pushToRemoteArtifactRepo
        println "inside remoteArtifactRepoURL: "+ remoteArtifactRepoURL
        println "inside localDiskArtifactRepoURL: "+ localDiskArtifactRepoURL
        return (pushToRemoteArtifactRepo ? remoteArtifactRepoURL : localDiskArtifactRepoURL);
    }

最新更新