我正在尝试使用"基于规则的模型配置中描述的概念" docs,我找不到做我需要的路径。
我正在使用ruleSourcePluginEach示例代码开始,但我需要能够为每个FileItem和/或DirectoryItem创建一个命名任务并将其依赖于某个地方。
基本上我需要做这样的事情:
@Managed interface Item extends Named {}
@Managed interface FileItem extends Item {}
@Managed interface DirectoryItem extends Item {
ModelMap<Item> getChildren()
}
class PluginRules extends RuleSource {
@Rules void ApplyRulesForDirectory(DirectoryRules rules, @Each DirectoryItem directory) {}
}
apply plugin: PluginRules
abstract class DirectoryRules extends RuleSource {
@Mutate
void CreateTaskForFiles(ModelMap<Task> tasks, ModelMap<FileItem> children) {
children.each {
tasks.create(it.name, Task) {
// ...
}
}
}
}
model {
root(DirectoryItem) {
children {
dir(DirectoryItem) {
children {
file1(FileItem)
file2(FileItem)
}
}
file3(FileItem)
}
}
}
但是,在gradle 3.3中运行它会失败:
The following model rules could not be applied due to unbound inputs and/or subjects:
DirectoryRules#CreateTaskForFiles(ModelMap<Task>, ModelMap<FileItem>)
subject:
- <no path> ModelMap<Task> (parameter 1) [*]
scope: root
inputs:
- <no path> ModelMap<FileItem> (parameter 2) [*]
[*] - indicates that a model item could not be found for the path or type.
任何想法如何实现这一目标?
干杯,谢谢你的时间!
答案 0 :(得分:0)
就我对Gradle基于规则的模型的有限知识所知,您的配置存在两个问题:
由于DirectoryRules
规则适用于范围(即未作为插件应用于模型的根目录),您需要为其提供所需的所有模型元素进入。你没有给它ModelMap<Task> tasks
,所以这是第一个问题。一个潜在的解决方案是:
class PluginRules extends RuleSource {
@Rules
void ApplyRulesForDirectory(DirectoryRules rules,
ModelMap<Task> tasks, @Each DirectoryItem directory) {}
}
然而,这揭示了第二个问题......
看起来Gradle的@Each
注释只能用于规则的目标(即被修改的东西),而你试图在它上面使用它规则的输入之一(目标是ModelMap<Task> tasks
)。我不知道为什么这个限制适用于@Each
;大概是与检测到匹配模型对象的时间/方式有关。
如果不确切知道自己要实现的目标,很难提出理想或惯用的解决方案。然而,天真地,这似乎有效:
@Managed interface Item extends Named {}
@Managed interface FileItem extends Item {}
@Managed interface DirectoryItem extends Item {
ModelMap<Item> getChildren()
}
class PluginRules extends RuleSource {
@Mutate
void CreateTasksForFiles(ModelMap<Task> tasks, @Path("root") DirectoryItem directory) {
directory.children.withType(FileItem).each {
tasks.create(it.name, Task) {
// ...
}
}
directory.children.withType(DirectoryItem).each {
ApplyRulesForDirectory(tasks, it)
}
}
}
apply plugin: PluginRules
model {
root(DirectoryItem) {
children {
dir(DirectoryItem) {
children {
file1(FileItem)
file2(FileItem)
}
}
file3(FileItem)
}
}
}