2015-04-29 2 views
3

Я хотел бы задать несколько вещей для нескольких тестовых задач. В частности, я хотел бы добавить несколько переменных среды и несколько свойств системы, возможно, несколько других вещей, таких как «зависимости» или «рабочий». С регулярной Test задачей я могу это сделать,Как расширить поведение задачи Gradle для нового типа задачи?

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, чтобы установить эти свойства. Должен ли я добавить все дополнительные значения в конструктор? Есть ли другой крючок, который я могу использовать? Благодарю.

ответ

3

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

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

спасибо. Мне нравится второй. Похоже, что первый подход нарушает часто цитируемый принцип, который «не вызывает переопределяемый метод в конструкторе», хотя он, вероятно, не имеет большого значения, так как метод 'systemProperty' вполне безопасен. Кроме того, весь контекст больше не доступен, и я должен постоянно называть 'getProject()', если мне нужно какое-либо свойство из проекта. – zggame

0

Также можно укажите поведение определенного параметра суперкласса. Скажем, например, вы хотите, чтобы централизовать 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)) 
    }) 
    } 
} 

Здесь мы используем оператор closure composition>>, чтобы объединить пройденное закрытие с нашим переопределенным поведением. Указанный пользователем configureClosure будет запущен первым, возможно, установив свойство libPath, а затем мы запустим блок environment.find. Это также может быть в сочетании с мягким по умолчанию в конструкторе, как и в Rene Groeschke's answer

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

Смежные вопросы