2017-02-04 116 views
7

我想有以下工作gradle這個腳本語言任意foo如何在gradle插件中添加新的語言源目錄?

sourceSets { 
    main { 
     java { 
      srcDir "${project.buildDir}/generated-sources/gen-java" 
     } 
     foo { 
      srcDir "${project.buildDir}/generated-sources/gen-foo" 
     } 
    } 
    test { 
     java { 
      srcDir "${project.buildDir}/generated-sources/gen-test-java" 
     } 
     foo { 
      srcDir "${project.buildDir}/generated-sources/gen-test-foo" 
     } 
    } 
} 

我也想有標準foo源目錄在src/main/foosrc/test/foo

如何編寫gradle插件來實現此功能?有沒有可能做到這一點?

我有一個類似於解決方案的解決方法,可以滿足我在下面發佈的需求,但仍想了解添加新語言源目錄的正確方法。

回答

2

爲了實現這樣的功能,應該擴展現有源集(或至少maintest源集)。它看起來像maintest來源集are defined in JavaPlugin。通過Convention對象可以擴展。

public class FooPlugin implements Plugin<ProjectInternal> { 
    @Override 
    public void apply(ProjectInternal project) { 
     project.getPluginManager().apply(JavaPlugin.class); 
     FooExtension ext = project.getExtensions().create(
      "foo", 
      FooExtension.class, 
      project, 
      project.getFileResolver() 
     ); 
     SourceSetContainer cont = (SourceSetContainer) project.getProperties().get("sourceSets"); 
     cont.all((SourceSet ss) -> { 
      String name = ss.getName(); 
      File sources = project.file("src/" + name + "/foo"); 
      FooSourceSet fss = ext.getSourceSetsContainer().maybeCreate(name); 
      SourceDirectorySet sds = fss.getFoo(); 
      sds.srcDir(sources); 
      Convention sourceSetConvention = (Convention) InvokerHelper.getProperty(ss, "convention"); 
      sourceSetConvention.getPlugins().put("foo", fss); 
     }); 
     project.task("compileFoo"); 
    } 
} 

public class FooExtension { 

    private final NamedDomainObjectContainer<FooSourceSet> sourceSetsContainer; 

    public FooExtension(Project project, FileResolver fileResolver) { 
     sourceSetsContainer = project.container(
      FooSourceSet.class, 
      new FooSourceSetFactory(fileResolver) 
     ); 
    } 

    public NamedDomainObjectContainer<FooSourceSet> getSourceSetsContainer() { 
     return sourceSetsContainer; 
    } 

    public void srcDir(String file) { 
     sourceSetsContainer.getByName("main").getFoo().srcDir(file); 
    } 
} 

public class FooSourceSetFactory implements NamedDomainObjectFactory<FooSourceSet> { 

    private final FileResolver fileResolver; 

    public FooSourceSetFactory(FileResolver fileResolver) { 
     this.fileResolver = fileResolver; 
    } 

    @Override 
    public FooSourceSet create(String name) { 
     return new DefaultFooSourceSet(name, fileResolver); 
    } 
} 

public interface FooSourceSet { 
    public String getName(); 
    public SourceDirectorySet getFoo(); 
    public FooSourceSet foo(Closure clsr); 
} 

public class DefaultFooSourceSet implements FooSourceSet { 

    final String name; 
    final SourceDirectorySet foo; 

    public DefaultFooSourceSet(String displayName, FileResolver fileResolver) { 
     this.name = displayName; 
     DefaultDirectoryFileTreeFactory ddftf = new DefaultDirectoryFileTreeFactory(); 
     foo = new DefaultSourceDirectorySet(name, fileResolver, ddftf); 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 

    @Override 
    public SourceDirectorySet getFoo() { 
     return foo; 
    } 

    @Override 
    public FooSourceSet foo(Closure clsr) { 
     ConfigureUtil.configure(clsr, foo); 
     return this; 
    } 
} 

public class CompileFooTask extends DefaultTask { 

    @TaskAction 
    public void compileFoo() { 
     SourceSetContainer cont = (SourceSetContainer) getProject().getProperties().get("sourceSets"); 
     cont.all((SourceSet ss) -> { 
      FooSourceSet fss = getProject() 
       .getExtensions() 
       .getByType(FooExtension.class) 
       .getSourceSetsContainer() 
       .maybeCreate(ss.getName()); 
      System.out.println("directories under " + ss.getName() 
       + ": " + fss.getFoo().getSrcDirs()); 
     }); 
    } 
} 

任務compileFoo表明該插件實際工作。鑑於構建腳本片段從問題它打印這樣的線:

directories under main: [<root>/src/main/foo, <root>/build/generated-sources/gen-foo] 
directories under test: [<root>/src/test/foo, <root>/build/generated-sources/gen-test-foo] 
+0

使用@ sm4更新代碼[answer](http://stackoverflow.com/a/42335494/2933541) –

3

爲您的使用情況下,源代碼將是相當長的,但這裏有幾個三分球,希望能得到你要的。

看看Scala Plugin。它完全符合你的需求(因爲它看起來像遵循Java約定的源代碼),還有更多。如果您正在嘗試編寫任何插件,我建議查看整個gradle源代碼。

你想看到確切的地方是:

  1. ScalaBasePlugin#configureSourceSetDefaults - 這是最高級別的配置情況
  2. DefaultScalaSourceSet - 實際的源集合類

在你的情況,你的可能只是想將所有scala字符串重命名爲foo並刪除所有不需要的配置(例如實際編譯)。

插件示出如何添加默認源目錄和方法:

public ScalaSourceSet scala(Closure configureClosure) { 
    configure(configureClosure, getScala()); 
    return this; 
} 

需要添加的生成源的護理。基本上它只需要默認的源目錄工廠並使用它。您可以使用注入來添加所有默認的Gradle工廠(請參閱Scala插件,僅使用javax.inject.Inject作品)。

您還可以檢查groovy插件。請注意,例如DefaultGroovySourceSet看起來像scala插件中的一個。

相關問題