Empfohlener Weg, um einen Gradle-Build zu stoppen

162

Wie kann ich einen Gradle-Build stoppen, nachdem ich ein Problem festgestellt habe? Ich kann eine Zusicherung verwenden, eine Ausnahme auslösen, eine System.exit ausführen (schlechte Idee) oder eine dedizierte Funktion in Gradle verwenden (aber ich konnte keine finden). Was ist der beste Weg für Gradle (und warum?).

Kartoch
quelle

Antworten:

117

Normalerweise werfe ich die entsprechende Ausnahme aus dem org.gradle.apiPaket , zum Beispiel, InvalidUserDataExceptionwenn jemand etwas Ungültiges eingegeben hat, oderGradleScriptException für allgemeinere Fehler.

Wenn Sie die aktuelle Aufgabe oder Aktion stoppen und mit der nächsten fortfahren möchten, können Sie auch eine werfen StopActionException

tim_yates
quelle
5
Sie können TaskExecutionException auch verwenden, wenn eine Aufgabe nicht erfolgreich ausgeführt wird. (Dies ist wahr, gemäß den Gradle 1.11-Dokumenten, ich bin nicht sicher, wann es eingeführt wurde.)
Josh Gagnon
Gibt es hier nette Syntaxoptionen? Betrachten Sie Kotlins Voraussetzungssyntax: require(something != whatever) { "No good!" }im Gegensatz zu der ausführlicheren und if(something != whatever){ throw new GradleException("No good!") }
typischeren
Das Schreckliche daran GradleScriptExceptionist, dass es einen zweiten Parameter für eine Ursache benötigt.
Trejkaz
... Natürlich vermeiden wir es zu sagen, dass dies " Programmieren nach Ausnahmen " ist ?! Ich habe das Vermächtnis so codiert und es ist ein Horror, es aufrechtzuerhalten ... In den alten Tagen ist die Philosophie, makedass rules(Aufgaben) erfolgreich waren oder fehlgeschlagen sind. Ich habe es einmal versucht return false- Gradle ignorierte es einfach und rannte weiter.
wird
87

Wenn Sie den Build stoppen möchten, werfen Sie:

throw new GradleException('error occurred')

oder werfen Sie die Unterklassen für die obige Ausnahme. Einige der Unterklassenausnahmen schlagen tatsächlich nur die aktuelle Aufgabe fehl, fahren jedoch mit dem Build fort.

übersprungen
quelle
28

Derzeit gibt es keine dedizierte Methode, obwohl diskutiert wurde, eine hinzuzufügen.

Die empfohlene Methode zum Stoppen eines Gradle-Builds besteht darin, eine Ausnahme auszulösen. Da Groovy keine Ausnahmen aktiviert hat und Gradle standardmäßig den Ausnahmetyp nicht druckt, ist es nicht so kritisch, welche Ausnahme ausgelöst wird. In Build-Skripten wird häufig GradleException verwendet, aber eine Groovy-Behauptung erscheint auch vernünftig (abhängig von den Umständen und der Zielgruppe). Wichtig ist eine klare Botschaft. Das Hinzufügen einer Ursache (falls verfügbar) hilft beim Debuggen ( --stacktrace).

Gradle bietet dedizierte Ausnahmetypen StopExecutionException/ StopActionExceptionzum Stoppen der aktuellen Aufgabe / Aufgabenaktion, aber zum Fortfahren des Builds.

Peter Niederwieser
quelle
19

Eine andere Option, wenn Sie nicht möchten, die Ausnahme später abfangen zu können, ist das Aufrufen der Ant-Fail-Task. Meiner Meinung nach ist es etwas einfacher zu lesen und Sie können dem Benutzer eine nette Nachricht geben, ohne --stacktrace zu verwenden.

task (tarball, dependsOn: warAdmin) << {
    ant.fail('The sky is falling!!')
}

Gibt Ihnen eine Nachricht wie:

* What went wrong:
Execution failed for task ':tarball'.
> The sky is falling!!

Wahrscheinlich können Sie dies abfangen (vielleicht löst es die BuildException von ant aus?), Aber wenn dies ein Ziel ist, würde ich ant.fail nicht verwenden. Ich würde es einfach machen, zu sehen, welche Ausnahme zu fangen ist, indem ich eine Standard-Gradle-Ausnahme auslöse, wie von tim_yates vorgeschlagen.

Gus
quelle
Wie richte ich es ein? Nennen?
Pulver366
1
Rufen Sie einfach ant.fail an ('Nachricht Ihrer Wahl'), kein Setup erforderlich
Gus
2
Es sieht so aus, als wäre die Ausgabe identisch mit der Verwendung von throw new GradleException("The sky is falling!!")(Gradle 3.4.1)
mgaert
@mgaert Ich erinnere mich anscheinend, dass vor 4 Jahren, als ich dies schrieb, die gedruckte Nachricht anders war (aber das ist eine lange Zeit und ich habe keine Lust herauszufinden, welche Version zu diesem Zeitpunkt aktuell war und zu überprüfen). Darüber hinaus kommuniziert IMHO ant.fail klarer die Absicht, den Build vollständig zu stoppen, während die ausgelöste Ausnahme als etwas gelesen wird, das möglicherweise abgefangen und behandelt wird.
Gus
12

Durch das Auslösen einer einfachen GradleException wird das Build-Skript gestoppt. Dies eignet sich hervorragend zum Überprüfen der erforderlichen Umgebungseinstellungen.

GradleException('your message, why the script is stopped.')

Beispiel:

if(null == System.getenv()['GRADLE_USER_HOME']) {
    throw new GradleException('Required GRADLE_USER_HOME environment variable not set.')
}
edvox1138
quelle
5

Hier ist ein Codefragment, das versucht zu emulieren, wie die Gradle-Javac-Task Fehler auslöst:

task myCommand(type:Exec) {

    ... normal task setup ....

    ignoreExitValue true
    standardOutput = new ByteArrayOutputStream()
    ext.output = { standardOutput.toString() }
    doLast {
        if (execResult.exitValue) {
            logger.error(output())
            throw new TaskExecutionException( it,
                new Exception( "Command '${commandLine.join(' ')}' failed; "
                              + "see task output for details." )
            )
        }
    }
}

Wenn der Befehl zurückkehrt 0 wird, erfolgt keine Ausgabe. Jeder andere Wert gibt den Standardausgang aus und stoppt den Build.

HINWEIS: Wenn Ihr Befehl auch in errorOutput schreibt, müssen Sie dies möglicherweise in das Fehlerprotokoll aufnehmen.

cmcginty
quelle