2015-03-11 19 views
6

olarak tanımlayın Yuvalanmış uzantı nesnelerini tanımlamam gereken ilk Gradle eklentisini uygulamaya koyma noktasındayım. Kullanıcı Kılavuzu henüz bunu kapsamamaktadır. Geçen sene bu konuyla ilgili birkaç soru oldu, fakat okuduğumdan bir çözüm oluşturamıyorum. Yuvalanmış uzatma kutularını Gradle

Bu

ben yapabilmek için kullanıcı istiyorum buna inanıyoruz:

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" 
     } 
    } 
} 

şuna İlk rastgele bıçak şöyle ve bu henüz yakın bile değil eminim : Burada

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 
     } 

Uzantımın sınıfları şunlardır: şu anda bunu çalıştırdığınızda

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 
} 

, aşağıdaki başarısız:

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) 

Ve eğer önemliyse, yapı betiğinde satır 25'i işaretledim.

Güncelleme:

çözümü entegre ettikten sonra bu gerekli kurulum bir özetidir. Bir "build.gradle" dosyasında

Numune yapısı:

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" 
    } 
} 

Eklenti yöntemi "uygulamak":

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) 
    } 
} 

Uzatma sınıfı:

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 
    } 
} 

Ve nihayet, CodeGenerator POGO:

class CodeGenerator { 
    String generatorClassName 
    String outputDir 
    Map  additionalConfiguration 
} 
+0

Java'ya nasıl dönüştürüleceğine dair herhangi bir referansınız var mı? Proje nesnesini uzantıya aktarmakta zorluk yaşıyorum. – zwebie

cevap

15

Hata, Project.container()'un NamedDomainObjectContainer oluşturmaya çalışmasından kaynaklanır. Bu özel koleksiyon türü, name özelliğinin belirtilmesi için koleksiyon türüne gereksinim duyar. Yaygın bir örnek, her öğenin benzersiz bir adı (ana, test vb.) Olduğu sourceSets'dur. DSL sonra gibi görünecektir: o anlamda her bir isim jeneratör vermek yapmaz ise

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" 
    } 
} 

sonra en iyi bahis sizin Generator nesnenin yeni bir örneğini yapılandırır uzantınıza bir yöntem tanımlamak için basitçe . Buradaki yakalama, 'dan beri,, Gradle'ın yapacağı tüm süslü süslemelere sahip olmayacaksanız (setter yöntemleri gibi) jeneratörü başlatıyor. Eğer yetenek istiyorsanız, bu yöntemleri Generator sınıfında manuel olarak tanımlamanız gerekir.

Güncelleme: Project.container() kaldıraç ve bir NamedDomainObjectContainer oluşturmak için

, bir özelliği olmalıdır konteyner tipi name denilen ve adı için bir String argüman alır kamu yapıcı. Bu özelliğin değeri, nesneyi başlangıçta yapılandırdığımda kullandığım adın adı.Örneğin:

sourceSets { 
    integTest { 
     srcDir 'src/integTest' 
    } 
} 

Yukarıdaki kod oluşturur ve adı "integTest" ile yeni bir SourceSet yapılandırır ve konteyner ekler. Bu özelliği ekleyerek bunu "jeneratörleriniz" ile kaldırabilirsiniz. Ayrıca, uzantı sınıfınızı değiştirmek için NamedDomainObjectContainer<CodeGenerator> türünde generators özelliğini oluşturmak ve ek CodeGeneratorsContainer sınıfına gerek yoktur.

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 
    } 
} 

Güncelleme 2: o anlamda sizin DSL adı geçen nesne olması yapmaz durumunda

, sadece yeni CodeGenerator yapılandırır ve ekler uzantınıza bir yöntem sağlayabilir bir koleksiyon.

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 
    } 
} 

Yeni DSL'niz generators bloğuna sahip olmayacaktı. Sadece şöyle görünür:

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" 
    } 
} 
+0

Woosh. Sıkıntı yok. Her jeneratör, "generatorClassName" değerini "name" olarak kullanabilirdi, demek istediğin buysa. Bu uzatma nesnelerini nasıl tanımlayacağımı bilmiyorum. Tabanın tanımlanması basittir, eğer yuvalanmış nesneler yoksa, ancak çizginin üzerinden bir adım attığınız zaman, bunun nasıl yapılacağı konusunda hiçbir bilgi yoktur. –

+0

Çok db geçişlerini desteklemek için kapsayıcı kullanan erken [flyway] (https://github.com/ben-manes/gradle-flyway-plugin) eklentisine bir göz atın. Proje sahibinin Gradle'ı veya kullanım durumunu anlamadığı için resmi eklenti olarak katkıda bulunduğunda bu durum kaldırıldı. –

+0

Tamam, o zaman belki de "NamedDomainObjectContainer" ihtiyacım olan şey değil. Birden fazla jeneratörü belirtmem gerekecek, ancak "generatorClassName" özelliğindeki fark dışında bunlar birbirlerinden kavramsal olarak farklı değiller. Ana görev jeneratörler boyunca yinelenecek ve her biri aynı girdi grubundan kod üretecektir. Başvurulan "flyway" kodunda gördüğüm şey yapmaya çalıştığım şeylerle benzerlik gösteriyor. Bu yaklaşıma bir yer bulabileceğimi göreceğim. –