插件如何以编程方式配置maven-publish发布并允许build.gradle对其进行修改

dit*_*kin 16 gradle

我在一个名为parent的插件中有项目范围的设置,它试图应用maven-publish插件,然后以编程方式配置发布扩展.这似乎有效,但是当我在build.gradle脚本中应用此插件时,我无法配置发布扩展以设置项目特定的发布.

我收到错误:

  Cannot configure the 'publishing' extension after it has been accessed.
Run Code Online (Sandbox Code Playgroud)

我的目的是在父插件中设置发布存储库,然后让每个build.gradle脚本添加适当的发布.

有没有办法做到这一点?

目前ParentPlugin.groovy看起来像:

def void apply(Project project) {
    project.getProject().apply plugin: 'maven-publish'

     def publishingExtension = project.extensions.findByName('publishing')

    publishingExtension.with {
        repositories {
            maven {
                mavenLocal()

                credentials {
                    username getPropertyWithDefault(project.getProject(), 'publishUserName', 'dummy')
                    password getPropertyWithDefault(project.getProject(), 'publishPassword', 'dummy')
                }

            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的客户端build.gradle在尝试配置发布扩展时失败.

apply plugin: 'parent'

publishing {
        publications {
            mavenJava(MavenPublication) {
                groupId 'agroup'
                artifactId 'anartifactid'
                version '1.0.0-SNAPSHOT'

                from components.java
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?还有另一种方法我应该接近这个吗?

小智 16

关于插件maven-publish的存储库{}和发布{}的注意事项:

主题:如何解决这个令人困惑的gradle致命错误消息:无法在访问后配置"发布"扩展

首先要尝试(魔渊)(注:前缀是可选的"项目".) -配置的出版物和资料库喜欢这样的:

project.publishing {publications {...}}
project.publishing {repositories {...}}
Run Code Online (Sandbox Code Playgroud)

但是喜欢这个推荐的风格:

project.publishing.publications {...}
project.publishing.repositories {...}
Run Code Online (Sandbox Code Playgroud)

对于一个傻瓜大师解释为什么这个技巧有效是有益的.

另一个已知的解决方法是确保插件maven-publish的每个应用与project.publishing.repositories和project.publishing.publications位于相同的项目代码块中.但这比首先要尝试的更复杂,更难做,因为默认情况下CBF应用maven-publish,第二次应用它本身可能会导致相同的错误.maven-publish通常应用于pub/scripts/publish-maven.gradle,除非将PUB_PUBLISH_MAVEN设置为覆盖该文件位置,在这种情况下,调用者应该应用插件maven-publish.请参阅https://orareview.us.oracle.com/29516818,了解如何在仍使用CBF的情况下完成此优选解决方法(对于项目emcapms).

PS有一天我会用最少的代码示例来编写它.但是我现在把这个来之不易的知识放在那里,以免其他人在这个普通的maven-publish问题上浪费时间.


小智 7

为了解决这个问题,我编写了另一个插件,它可以延迟对发布的修改,同时还可以避免"读取"扩展,这会使其处于"已配置"状态.该插件名为nebula-publishing-plugin,"lazy"块的代码可以在github repo中找到.它看起来像这样:

/**
 * All Maven Publications
 */
def withMavenPublication(Closure withPubClosure) {
    // New publish plugin way to specify artifacts in resulting publication
    def addArtifactClosure = {

        // Wait for our plugin to be applied.
        project.plugins.withType(PublishingPlugin) { PublishingPlugin publishingPlugin ->
            DefaultPublishingExtension publishingExtension = project.getExtensions().getByType(DefaultPublishingExtension)
            publishingExtension.publications.withType(MavenPublication, withPubClosure)
        }
    }

    // It's possible that we're running in someone else's afterEvaluate, which means we need to run this immediately
    if (project.getState().executed) {
        addArtifactClosure.call()
    } else {
        project.afterEvaluate addArtifactClosure
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你会这样称呼它:

withMavenPublication { MavenPublication t ->
        def webComponent = project.components.getByName('web')
        // TODO Include deps somehow
        t.from(webComponent)
    }
Run Code Online (Sandbox Code Playgroud)

该插件在jcenter()中以'com.netflix.nebula:nebula-publishing-plugin:1.9.1'的形式提供.


Ron*_*Ron 6

有点晚了,但我找到了一个不需要额外插件的解决方案:(这是从我的一个内部插件中获取的,可以用于新旧发布,因此... withType ...东西.

代替:

    project.plugins.withType(MavenPublishPlugin) {
        project.publishsing {
            publications {
                myPub(MavenPublication) {
                    artifact myJar
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

做这个:

    project.plugins.withType(MavenPublishPlugin) {
        project.extensions.configure PublishingExtension, new ClosureBackedAction( {
            publications {
                myPub(MavenPublication) {
                    artifact myJar
                }
            }
        })
    }
Run Code Online (Sandbox Code Playgroud)

这不会立即解析扩展,但会在某人首次解析时应用配置.当然,在项目范围的插件中使用这种配置样式来配置存储库并像往常一样在构建脚本中使用发布扩展是完全有意义的.这样可以避免构建作者的混淆.