Как расширить поведение задачи Gradle для нового типа задачи?

Я хотел бы установить несколько вещей для нескольких тестовых заданий. Более конкретно, я хотел бы добавить несколько переменных среды и несколько системных свойств, возможно, несколько других вещей, таких как "зависимости" или "рабочий диск". С регулярным Test задача, которую я могу сделать это,

task test1(type:Test, dependsOn:[testPrep,testPrep1]){
     workingDir testWorkingPath
     systemProperty 'property','abs'
     environment.find { it.key ==~ /(?i)PATH/ }.value += (System.properties['path.separator'] + myLibPath)
     environment.LD_LIBRARY_PATH = "/usr/lib64:/lib64:${myLibPath}:" + environment.LD_LIBRARY_PATH
 }

task test2(type:Test, dependsOn:[testPrep]){
     workingDir testWorkingPath
     systemProperty 'property','abs'
     environment.find { it.key ==~ /(?i)PATH/ }.value += (System.properties['path.separator'] + myLibPath)
     environment.LD_LIBRARY_PATH = "/usr/lib64:/lib64:${myLibPath}:" + environment.LD_LIBRARY_PATH
     systemPropety 'newProperty','fdsjfkd'
 }

Было бы неплохо иметь новый тип задачи MyTestType расширение обычного типа тестовой задачи, где определено общее определение.

task test1(type:MyTestType){
     dependsOn testPrep1
 }

task test2(type:MyTestType){
     systemPropety 'newProperty','fdsjfkd'
 } 

Что было бы лучшим способом сделать это? Кажется, что execute() Метод является окончательным и не может быть расширен. Мне нужно будет сделать что-то вроде doFirst установить эти свойства. Должен ли я добавить все дополнительные значения в конструкторе? Есть ли другой крючок, который я могу использовать? Благодарю.

2 ответа

В общем, вы можете расширить задачу "Тест" и реализовать свои настройки

task test1(type:MyTestType){
}

task test2(type:MyTestType){
     systemProperty 'newProperty','fdsjfkd'
}

class MyTestType extends Test {
    public MyTestType(){
        systemProperty 'property','abs'
    }
}

В качестве альтернативы вы можете настроить все задачи типа Test с меньшим количеством шаблонов:

// will apply to all tasks of type test. 
// regardless the task was created before this snippet or after
tasks.withType(Test) {
   systemProperty 'newProperty','fdsjfkd'   
}

Вы можете сделать это следующими способами

task TestExt{ Test { systemPropety 'newProperty','fdsjfkd' } }

примечание: это просто добавляет к методу настройки источника теста: https://docs.gradle.org/current/dsl/org.gradle.api.Task.html

Также возможно указать поведение определенного параметра суперкласса. Скажем, например, вы хотите централизовать environment.find заблокировать, но разрешить настройку myLibPath за задачу вроде этого:

task test1(type: MyTestType) {
}
task test2(type: MyTestType) {
  libPath = '/foo/bar'
}

Вы можете сделать это, переопределив configure метод:

class MyTestType {
  @Input def String libPath

  @Override
  public Task configure(Closure configureClosure) {
    return super.configure(configureClosure >> {
      environment.find { it.key ==~ /(?i)PATH/ }.value += (System.properties['path.separator'] + (libPath ?: myLibPath))
    })
  }
}

Здесь мы используем оператор композиции замыкания >> объединить переданное закрытие с нашим переопределенным поведением. Указанный пользователем configureClosure будет запущен первым, возможно, установив libPath собственности, а затем мы запускаем environment.find блок после этого. Это также можно сочетать с мягкими значениями по умолчанию в конструкторе, как в ответе Рене Грошке

Обратите внимание, что этот конкретный вариант использования может прерваться, если вы сконфигурируете задачу более чем на одну, так как environment.find оператор трансформирует существующее состояние вместо его замены.

Другие вопросы по тегам