【问题标题】:Nested extensions in Gradle pluginGradle 插件中的嵌套扩展
【发布时间】:2021-02-19 08:22:34
【问题描述】:

我正在尝试在我的 gradle 插件中实现以下配置

music {
    artist {
        artistName = "artist1"
        album {
            albumName = "album1"
        }
    }
    artist {
        artistName = "artist2"
        album {
            albumName = "album1"
        }
        album {
            albumName = "album1"
        }
    }
}

这就是我目前所拥有的

open class MusicPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.extensions.create("music", MusicPluginExtension::class.java)
    }
}

open class MusicPluginExtension @Inject constructor(val objectFactory: ObjectFactory) {
    val artists = objectFactory.domainObjectSet(Artist::class.java)

    fun artist(action: Action<in Artist>) {
        val artist = Artist(objectFactory)
        action.execute(artist)
        artists.add(artist)
    }
}

open class Artist @Inject constructor(objectFactory: ObjectFactory) {
    var artistName: String? = null
    val albums = objectFactory.domainObjectSet(Album::class.java)

    fun album(action: Action<in Album>) {
        val album = Album()
        action.execute(album)
        albums.add(album)
    }
}

open class Album() {
    var albumName: String? = null
}

当我将插件应用到项目时,我能够创建闭包,但是当我尝试为 Album 设置属性时失败(例如设置专辑名称)。这是我得到的错误:

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/user/git/pluginTest/build.gradle' line: 19

* What went wrong:
A problem occurred evaluating root project 'pluginTest'.
> Could not set unknown property 'albumName' for object of type com.plugin.Artist.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

CONFIGURE FAILED in 84ms

我们将不胜感激。

【问题讨论】:

  • 什么时候出现这个错误?在项目配置阶段?
  • 是的,我在项目配置阶段得到了这个。
  • 无法复制...对我来说很好用(实际上我删除了@Inject 注释)。在您的情况下,如果没有它们,它会工作吗?
  • 我尝试删除 @Inject 注释但仍然得到相同的结果 FAILURE: Build failed with an exception. * Where: Build file '/Users/user/git/pluginTest/build.gradle' line: 19 * What went wrong: A problem occurred evaluating root project 'pluginTest'. &gt; Could not set unknown property 'albumName' for object of type com.plugin.Artist. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org CONFIGURE FAILED in 84ms
  • 为什么要使用domainObjectSet() 而不是newInstance 将所有属性包装在Property&lt;&gt; 中??

标签: java kotlin gradle gradle-plugin


【解决方案1】:

或许你可以使用 Gradle 的NamedDomainObjectContainer

interface MusicPluginExtension {
    // https://docs.gradle.org/current/userguide/custom_gradle_types.html#nameddomainobjectcontainer
    NamedDomainObjectContainer<Artist> getArtists()

    interface Artist {
        String getName()
        NamedDomainObjectContainer<Album> getAlbums()
        interface Album {
            String getName()
        }
    }
}
music {
    artists {
        register("artist1") {
            albums {
                register("album1"){}
                register("album2"){}
            }
        }
        register("artist2") {
            // ...
        }
    }
}

它适用于 1 级嵌套列表,也许它也适用于 2 级列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    相关资源
    最近更新 更多