Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle: Execute an action only if a task fails

I would like to open the report file of several of the "check" and "test" plugins I use when a check fails. I know I can use "finalizedBy to execute another task no matter whether the original task was executed. Using that knowledge I tried the following to open the report only if the corresponding task (in this example checkstyle) fails:

task showCheckStyleResultsInBrowser(type: Exec) {
    ext.htmlFileName = "main.html"
    executable 'open'
    args 'file:///' + checkstyleMain.reports.xml.destination.parent + "/" + ext.htmlFileName
}

task showCheckStyleResultsIfFailed {
    ext.aCheckFailed = true
    doLast {
        if (ext.aCheckFailed) {
            showCheckStyleResultsInBrowser.execute()
        }
    }
}

checkstyleMain {
    finalizedBy 'showCheckStyleResultsIfFailed'
    doLast {
        // convert the xml output to html via https://stackoverflow.com/questions/20361942/generate-checkstyle-html-report-with-gradle
        ant.xslt(in: reports.xml.destination,
                 style: new File('config/checkstyle/checkstyle-noframes-sorted.xsl'),
                 out: new File(reports.xml.destination.parent, showCheckStyleResultsInBrowser.htmlFileName))

        showCheckStyleResultsIfFailed.aCheckFailed = false
    }
}

Explanation (as far as I understand it):

  • showCheckStyleResultsInBrowser ist the task that actually does the opening of the report. You can ignore what it actually does, but it's the one that should be executed if the check-task fails
  • The showCheckStyleResultsIfFailed task declares a property aCheckFailed and initializes it to true. When it is executed it checks whether it is still true (which means, the check did not complete successfully) and if so, opens the report using showCheckStyleResultsInBrowser.
  • checkstyleMain is the task that does the actual checking. I'm interested in its result. However I don't know how to get to it. So instead, in end of the checkStyleMain task, I set the aCheckFailed property to false relying on the fact that the last step will only be executed if none of the previous checks failed.
  • showCheckStyleResultsIfFailed is set to execute after checkstyleMain no matter what by finalizedBy. This way it will execute even if checkstyleMain fails. It uses the aCheckFailed property to determine whether checkstyleMain was completed successfully.

This works ok if I do a complete build. But if I just do a partial rebuild and the checkstyleMain task does not run, because all its result are already up-to-date, I end up with aCheckFailed being true, because checkstyleMain did not run, which makes it look as if something actually went wrong.

So how can I execute my showCheckStyleResultsInBrowser task if and only if the checkstyleMain task fails? Also, my solution feels rather cumbersome and hacky even for what it does achieve. Is there an easier way?

like image 737
Joachim Kurz Avatar asked Oct 15 '14 17:10

Joachim Kurz


1 Answers

You can interrogate the task state to determine if it failed or not.

task showCheckStyleResultsIfFailed {
    onlyIf {
        checkstyleMain.state.failure != null
    }
}
like image 98
Mark Vieira Avatar answered Nov 19 '22 07:11

Mark Vieira