我正在实现我的第一个Gradle插件,我需要定义嵌套的扩展对象.用户指南尚未涵盖此内容.在过去一年左右的时间里,有几个问题存在,但我无法从我读过的内容中找到解决方案.
这就是我认为我希望用户能够做到的事情:
yang {
yangFilesRootDir "src/main/resources/yang"
inspectDependencies true
generators {
generator { // line 25
generatorClassName "org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl"
outputDir "build/gen1"
}
generator {
generatorClassName "org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl"
outputDir "build/gen2"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我对此的第一次随机刺穿看起来像这样,我确信这还没有接近:
public void apply(Project project) {
project.plugins.apply(JavaPlugin)
YangExtension yang = project.extensions.create(YANG_EXT, YangExtension)
project.yang.extensions.generators =
project.container(CodeGeneratorsContainer) {
println it
}
Run Code Online (Sandbox Code Playgroud)
这是我的扩展类:
class YangExtension {
CodeGeneratorsContainer generators
String yangFilesRootDir
String[] excludeFiles
boolean inspectDependencies
String yangFilesConfiguration
String generatorsConfiguration
}
public class CodeGeneratorsContainer {
Collection<CodeGenerator> generators
}
class CodeGenerator {
String generatorClassName
File outputBaseDir
Map additionalConfiguration
}
Run Code Online (Sandbox Code Playgroud)
当我现在运行它时,它失败并带有以下内容:
Caused by: java.lang.NullPointerException: Cannot get property 'name' on null object
at org.gradle.api.internal.DynamicPropertyNamer.determineName(DynamicPropertyNamer.groovy:36)
at org.gradle.api.internal.DefaultNamedDomainObjectCollection.add(DefaultNamedDomainObjectCollection.java:70)
at org.gradle.api.internal.AbstractNamedDomainObjectContainer.create(AbstractNamedDomainObjectContainer.java:58)
at org.gradle.api.internal.AbstractNamedDomainObjectContainer.create(AbstractNamedDomainObjectContainer.java:52)
at org.gradle.api.internal.NamedDomainObjectContainerConfigureDelegate._configure(NamedDomainObjectContainerConfigureDelegate.java:39)
at org.gradle.api.internal.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:73)
at build_2a353qtggi869feteaqu2qgc3$_run_closure1_closure3.doCall(....\workspace2\YangUsingProject\build.gradle:25)
Run Code Online (Sandbox Code Playgroud)
如果重要的话,我在构建脚本中标记了第25行.
更新:
集成解决方案后,这是所需设置的摘要.
"build.gradle"文件中的示例结构:
yang {
yangFilesRootDir "src/main/resources/yang"
//excludeFiles "target.yang"
inspectDependencies true
generator {
generatorClassName = "org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl"
outputDir = "build/gen1"
}
generator {
generatorClassName = "org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl"
outputDir = "build/gen2"
}
}
Run Code Online (Sandbox Code Playgroud)
插件"apply"方法:
public void apply(Project project) {
project.plugins.apply(JavaPlugin)
YangExtension yang = project.extensions.create(YANG_EXT, YangExtension, project)
YangGenerateTask task = project.task(YANG_GENERATE_TASK, type: YangGenerateTask)
project.afterEvaluate {
task.init(project, yang)
}
}
Run Code Online (Sandbox Code Playgroud)
扩展类:
class YangExtension {
private Project project
Collection<CodeGenerator> generators
String yangFilesRootDir
String[] excludeFiles
boolean inspectDependencies
String yangFilesConfiguration
String generatorsConfiguration
YangExtension(Project project) {
this.project = project
}
CodeGenerator generator(Closure closure) {
def generator = project.configure(new CodeGenerator(), closure)
generators.add(generator)
return generator
}
}
Run Code Online (Sandbox Code Playgroud)
最后,CodeGenerator POGO:
class CodeGenerator {
String generatorClassName
String outputDir
Map additionalConfiguration
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ira 16
该错误是由Project.container()尝试创建一个错误引起的NamedDomainObjectContainer.此特殊类型的集合需要集合类型来指定name属性.一个常见的例子是sourceSets,每个项目都有一个唯一的名称(主要,测试等).然后DSL看起来像:
generators {
codeGenerator {
generatorClassName "org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl"
outputDir "build/gen1"
}
docGenerator {
generatorClassName "org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl"
outputDir "build/gen2"
}
}
Run Code Online (Sandbox Code Playgroud)
如果给每个生成器命名没有意义,那么最好的办法就是在扩展中定义一个配置Generator对象新实例的方法.这里的问题是,如果你没有Gradle会做的所有奇特的装饰(例如setter方法),那么你将实例化生成器.如果需要功能,则必须在Generator类上手动定义这些方法.
更新:
为了利用Project.container()和创建a NamedDomainObjectContainer,容器类型必须具有一个名为的属性name和一个公共构造函数,该构造函数接受String名称的参数.这个属性的值是我最初配置对象时使用的任何名称.例如:
sourceSets {
integTest {
srcDir 'src/integTest'
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码创建并配置SourceSet名为"integTest" 的new ,并将其添加到容器中.您只需添加该属性即可将此功能与"生成器"结合使用.您还需要修改扩展类以创建generators类型的属性,NamedDomainObjectContainer<CodeGenerator>并且不需要其他CodeGeneratorsContainer类.
class YangExtension {
NamedDomainObjectContainer<CodeGenerator> generators
String yangFilesRootDir
String[] excludeFiles
boolean inspectDependencies
String yangFilesConfiguration
String generatorsConfiguration
YangExtension(Project project) {
this.generators = project.container(CodeGenerator)
}
}
class CodeGenerator {
String generatorClassName
File outputBaseDir
Map additionalConfiguration
private String name
CodeGenerator(String name) {
this.name = name
}
String getName() {
return this.name
}
}
Run Code Online (Sandbox Code Playgroud)
更新2:
如果在DSL中使用命名对象没有意义,您可以在扩展上提供一种配置新方法CodeGenerator并将其添加到集合的方法.
class YangExtension {
Collection<CodeGenerator> generators = new ArrayList<>()
private Project project
YangExtension(Project project) {
this.project = project
}
CodeGenerator generator(Closure closure) {
def generator = project.configure(new CodeGenerator(), closure)
generators.add(generator)
return generator
}
}
Run Code Online (Sandbox Code Playgroud)
您的新DSL将没有generators阻止.它看起来像这样:
yang {
generator {
generatorClassName = "org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl"
outputDir = "build/gen1"
}
generator {
generatorClassName = "org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl"
outputDir = "build/gen2"
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2606 次 |
| 最近记录: |