2012-10-01 43 views
4

背景:我有一个多项目Gradle构建,并且我定义了一个Gradle任务,它在Exec任务中运行JavaScript单元测试。此任务的输入是项目中的JavaScript文件,因此只有修改了其中一个源文件时才会重新运行。该任务将添加到来自主项目的所有JavaScript项目中。使用来自项目依赖关系的输入定义Gradle任务?

问:我要扩展这个,这样的测试重新运行项目中的JavaScript文件,或任何其项目依赖的改变。这最好的做法是什么?

下面的代码如果放置在每个子项目构建文件中(在依赖声明之后),但是我们有20多个JavaScript子项目,我想保持DRY。

project.ext.jsSourceFiles = fileTree("src/").include("**/*.js*") 

task testJavaScript(type: Exec, dependsOn: configurations.js) { 
    inputs.files resolveJavascriptDependenciesFor(project) 
    outputs.file "report.xml" 

    // Run tests in JSTestDriver using command line call...  
} 

def resolveJavascriptDependenciesFor(project) { 
    def files = project.jsSourceFiles 
    project.configurations.js.allDependencies.each { 
     files = files + resolveJavascriptDependenciesFor(it.dependencyProject) 
    } 
    return files 
} 

有没有更好的解决方案?也许我不必自己解决所有文件依赖关系?

+0

测试文件夹已经被排除为简单起见,示例源。 –

回答

2

正如前面的答案中所写,在子项目闭包中添加jsTest任务可以很容易地为每个子项目添加jstesting支持。我想你可以通过声明的源文件作为依赖缓解你的输入设置:

dependencies { 
    js filetree("src/main").include("**/*.js") 
} 

subprojects { subproj -> 
    task testJavaScript(type: Exec, dependsOn: configurations.js) { 
     inputs.files subproj.configurations.js 
     outputs.file "report.xml" 

     commandLine ... 
    }  
} 
+0

对不起,为简单起见,我仅省略了示例中的输出。问题似乎是在定义输入时未指定依赖关系。 –

+0

顺便说一句,指定subproj.configurations.js作为输入会有什么不同?是否可以通过某种方式指定源,以便包含来自子项目依赖关系的文件?我尝试过,但没有看到任何区别,因为我没有定义任何将JavaScript源文件绑定到js配置的东西。 –

+0

任务的输入在执行任务之前的执行阶段被评估。因此我认为所有的依赖关系都是在评估时间定义的。 你可以做这样的事情,当地的js文件添加到您的JS配置: 依赖{ \t JS文件树( “SRC /主”)匹配{it.endsWith( “JS”)} 。} –

0

是否有可能做到这样的事情?

allprojects {project -> 
    task testJavaScript(type: Exec, dependsOn: configurations.js) { 
     inputs.files resolveJavascriptDependenciesFor(project) 
    // Run tests in JSTestDriver using command line call...  
    } 
} 

def resolveJavascriptDependenciesFor(project) { 
    def files = project.jsSourceFiles 
    project.configurations.js.allDependencies.each { 
     files = files + resolveJavascriptDependenciesFor(it.dependencyProject) 
    } 
    return files 
} 

该方法的任务是在所有的项目,将被称为递归。 不完全确定这是行得通的,但我认为它的路要走

+0

如果从主项目运行目标,这可能会重新运行所有测试,但如果依赖项中的文件发生更改,则它不会对重新运行进行任何更改。 –

+0

inputs属性应该包含可以改变任务输出的东西。如果依赖可以触发重新运行,那么它们也应该处于输入状态。输入和输出属性正好用于增量构建 – mathiasbn

0

我发现工作,但不是很大,使用相同的依赖性规范作为一种解决方案在问题中。它是在主项目中以稍微不同的顺序加载gradle文件。

万事达build.gradle

subprojects { 
    configurations { 
     js 
    } 

    // Apply the subproject's build.gradle, but with another name (that isn't automatically loaded) 
    if (project.file('depends.gradle').exists()) { 
     apply from: project.file('depends.gradle') 
    } 

    apply from: project.parent.file('javaScriptProjectTasks.gradle') 
} 

比较到以前,非工作主build.gradle

subprojects { 
    configurations { 
     js 
    } 

    apply from: project.parent.file('javaScriptProjectTasks.gradle') 
    // The subproject's build.gradle is automatically loaded 
}