Определить задачу Gradle с входными данными из зависимостей проекта?

Предыстория: у меня есть многопроектная сборка Gradle, и я определил задачу Gradle, которая запускает модульные тесты JavaScript в задаче Exec. Входными данными для этой задачи являются файлы JavaScript в проекте, поэтому он запускается только в случае изменения одного из исходных файлов. Задача добавляется во все проекты JavaScript из мастер-проекта.

Вопрос: Я хочу расширить это, чтобы тесты были перезапущены, если файлы JavaScript в проекте или в какой-либо из его зависимостей проекта были изменены. Как это лучше всего сделать?

Приведенный ниже код работает, если он помещен в каждый файл сборки подпроекта (после объявления зависимости), но у нас более 20 подпроектов JavaScript, и я бы хотел остаться СУХИМЫМ.

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
}

Есть ли лучшее решение? Может быть, где мне не нужно разрешать все файловые зависимости самостоятельно?

3 ответа

Решение

Как написано в ответе ранее, добавление задачи 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  ...
    }    
}

Будет ли возможно сделать что-то подобное?

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
}

Таким образом, задание выполняется для всех проектов и будет вызываться рекурсивно. Не совсем уверен, что это работает, но я думаю, что это путь

Я нашел решение, которое работает, но не отлично, используя ту же спецификацию зависимостей, что и в вопросе. Это загрузка файлов 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
}
Другие вопросы по тегам