Как да създадете gradle задача, която винаги се изпълнява?

Вероятно пренебрегвам нещо доста основно/очевидно, но как мога да създам задача, която винаги ще се изпълнява за всяка задача/цел?

Мога да направя нещо като:

task someTask << {
    println "I sometimes run"
}
println "I always run"

Но би било много по-желателно да имате винаги изпълняваната част от задачата.

Най-близкото до което съм стигнал е:

task someTask << {
    println "I sometimes run"
}

println "I always run"

void helloThing() {
    println "I always run too. Hello?"
}

helloThing()

Така че използването на метод е „добре“ решение, но се надявах, че ще има начин конкретно да се посочи/използва повторно задача.

Надяваме се, че някой има начин да направи това. :)


person CasualT    schedule 09.01.2014    source източник
comment
Ако има N задачи, тази функция трябва да бъде извикана N пъти, нали? Ами ако някои задачи НИКОГА не се изпълняват в дадената компилация?   -  person akhikhl    schedule 09.01.2014
comment
Или искате да се извиква функция за всеки проект?   -  person akhikhl    schedule 09.01.2014
comment
Веднъж на компилация. Без значение кои задачи се извикват.   -  person CasualT    schedule 09.01.2014
comment
Това е необичайно изискване и няма първокласна функция за това. Какъв е случаят на употреба?   -  person Peter Niederwieser    schedule 09.01.2014
comment
Предполагам, че мисълта е била по-организационен подход към общи „задачи“ за изграждане... но може просто да прибягна до използване на методи за някои от тези случаи.   -  person CasualT    schedule 09.01.2014
comment
Един конкретен случай беше за информация за диагностика/статус на системата. Което, в някои случаи просто бих искал да извикам задачата 'systemStatus', но също така бих искал тази информация да се изплюе и за всяка компилация. (разбира се, че бих могъл да постигна нещо подобно с методи под капака... но просто си помислих, че те може да са често срещан начин да го направя със задачи).   -  person CasualT    schedule 09.01.2014


Отговори (3)


Ако приемем, че целта е да отпечатате системна информация, можете или винаги да отпечатвате информацията във фазата на конфигуриране (извън декларация на задача) и да имате фиктивна задача systemStatus, която не прави нищо (защото информацията така или иначе се отпечатва). Или можете да го приложите като обикновена задача и да се уверите, че задачата винаги се изпълнява, като добавите ":systemStatus" като първи елемент от gradle.startParameter.taskNames (списък от низове), което симулира, че някой винаги въвежда gradle :systemStatus .... Или можете да използвате кука като gradle.projectsLoaded { ... }, за да отпечатате информацията там.

person Peter Niederwieser    schedule 09.01.2014
comment
Това е страхотен трик за динамичното манипулиране на списъка taskNames. (за справка, това работи: gradle.startParameter.taskNames = [:someTask] + gradle.startParameter.taskNames) - person CasualT; 10.01.2014
comment
Някаква идея как да „закачите“ задача към друга задача, различна от „изпълни“, което не се препоръчва? - person Ivan Balashov; 22.01.2015

Това прикрепя затваряне към всяка задача във всеки проект в дадената компилация:

def someClosure = { task ->
  println "task executed: $task"
}

allprojects {
  afterEvaluate {
    for(def task in it.tasks)
      task << someClosure
  }
}

Ако имате нужда функцията/затварянето да се извиква само веднъж на компилация, преди всички задачи на всички проекти, използвайте това:

task('MyTask') << {
  println 'Pre-build hook!'
}

allprojects {
  afterEvaluate {
    for(def task in it.tasks)
      if(task != rootProject.tasks.MyTask)
        task.dependsOn rootProject.tasks.MyTask
  }
}

Ако имате нужда функцията/затварянето да се извиква само веднъж на компилация, след всички задачи на всички проекти, използвайте това:

task('MyTask') << {
  println 'Post-build hook!'
}

allprojects {
  afterEvaluate {
    for(def task in it.tasks)
      if(task != rootProject.tasks.MyTask)
        task.finalizedBy rootProject.tasks.MyTask
  }
}
person akhikhl    schedule 09.01.2014
comment
Хммм...това е доста удобно...малко по-подробно, отколкото се надявах, но все пак доста лесно. - person CasualT; 09.01.2014
comment
Актуализирах отговора си, като се грижа за това, което казахте - Веднъж на компилация. - person akhikhl; 10.01.2014
comment
По-добре е да използвате кука за компилация, отколкото кука за проект. Вторият фрагмент ще изпълни задачата в края на компилацията, а не в началото. - person Peter Niederwieser; 10.01.2014
comment
Избрах отговора на Питър, защото е малко по-сбит. Въпреки това може да използвам и този друг подход. (но мога да избера само един отговор ;)). Благодаря за помощта. :) - person CasualT; 10.01.2014
comment
Добро мнение, Питър, благодаря ти. Разширих отговора с два варианта: кука преди изграждане и след изграждане. - person akhikhl; 10.01.2014
comment
Удоволствие е да участваш в такива дискусии, човек научава много :) - person akhikhl; 10.01.2014
comment
Току-що ми стана ясно, че има една (потенциално важна) разлика между решението от @PeterNiederwieser и от мен: вариантът на Peter ще бъде ВИНАГИ извикан, независимо от изпълнението на други задачи. Моят вариант (post-hook и pre-hook) ще бъде извикан САМО ТОГАВА, когато е изпълнена поне още една задача (директно или като зависимост). Например, ако всички задачи са актуални, куките не се изпълняват. - person akhikhl; 10.01.2014

Какво лошо има в извикването му направо от корена build.gradle?

task init << {
    println "I always run"
}

tasks.init.execute()
person Nick Grealy    schedule 14.10.2015
comment
execute() вече е отхвърлена функция и ще бъде премахната в Gradle 5.0 - person DPancs; 18.05.2018