Zalecany sposób na zatrzymanie kompilacji Gradle

162

Jak mogę zatrzymać kompilację Gradle po wykryciu problemu? Mogę użyć potwierdzenia, zgłosić wyjątek, wykonać System.exit (zły pomysł) lub użyć dedykowanej funkcji w Gradle (ale nie mogłem jej znaleźć). Jaki jest najlepszy sposób dla Gradle (i dlaczego?).

Kartoch
źródło

Odpowiedzi:

117

Zwykle wyrzucam odpowiedni wyjątek z org.gradle.apipakietu , na przykład InvalidUserDataExceptiongdy ktoś wprowadził coś nieprawidłowego lub GradleScriptExceptiondla bardziej ogólnych błędów.

Jeśli chcesz zatrzymać bieżące zadanie lub akcję i przejść do następnego, możesz również rzucić StopActionException

tim_yates
źródło
5
Możesz również użyć TaskExecutionException, jeśli zadanie nie zostanie wykonane pomyślnie. (Jest to prawdą zgodnie z dokumentacją gradle 1.11, nie jestem pewien, kiedy została wprowadzona.)
Josh Gagnon,
czy są tu jakieś fajne opcje składni? Rozważmy składnię warunków wstępnych Kotlina: require(something != whatever) { "No good!" }w przeciwieństwie do bardziej if(something != whatever){ throw new GradleException("No good!") }
rozwlekłej
Najgorsze GradleScriptExceptionjest to, że jako przyczyna wymaga drugiego parametru.
Trejkaz
... Oczywiście unikamy stwierdzenia, że ​​jest to „ programowanie przez wyjątki ” ?! Mam zakodowane w ten sposób dziedzictwo i jest to horror do utrzymania ... W dawnych czasach filozofia makebyła taka, że rules(zadania) się powiodły lub zawiodły. Kiedyś próbowałem return false- Gradle po prostu to zignorował i kontynuował bieg.
będzie
87

Jeśli chcesz zatrzymać budowanie, rzuć:

throw new GradleException('error occurred')

lub wyrzuć podklasy dla powyższego wyjątku. Niektóre wyjątki podklasy w rzeczywistości kończą się niepowodzeniem tylko dla bieżącego zadania, ale kontynuują kompilację.

skipy
źródło
28

Obecnie nie ma dedykowanej metody, chociaż trwały dyskusje, aby ją dodać.

Zalecanym sposobem zatrzymania kompilacji Gradle jest zgłoszenie wyjątku. Ponieważ Groovy nie ma sprawdzonych wyjątków, a Gradle domyślnie nie drukuje typu wyjątku, nie jest tak krytyczne, który wyjątek jest zgłaszany. W skryptach kompilacji często używany jest GradleException, ale asercja Groovy również wydaje się rozsądna (w zależności od okoliczności i odbiorców). Ważne jest, aby przekazać jasny komunikat. Dodanie przyczyny (jeśli jest dostępna) pomaga w debugowaniu ( --stacktrace).

Gradle zapewnia dedykowane typy wyjątków StopExecutionException/ StopActionExceptiondo zatrzymywania bieżącego zadania / akcji zadania, ale kontynuuje kompilację.

Peter Niederwieser
źródło
19

Inną opcją, jeśli nie chcesz później wychwycić wyjątku, jest wywołanie zadania niepowodzenia mrówki. Moim zdaniem jest nieco łatwiejszy do odczytania i można przekazać użytkownikowi przyjemną wiadomość bez użycia opcji --stacktrace.

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

Przekazuje Ci wiadomość taką jak:

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

Prawdopodobnie możesz to złapać (być może rzuca on wyjątek BuildException ant?), Ale jeśli to jest cel, nie użyłbym ant.fail. Ułatwiłbym tylko wyłapanie wyjątku, rzucając standardowy wyjątek gradle, zgodnie z sugestią tim_yates.

Gus
źródło
Jak to ustawić? Nazwać?
proszek 366
1
po prostu zadzwoń do ant.fail („wiadomość do wyboru”) konfiguracja nie jest wymagana
Gus
2
Wygląda na to, że wynik tego jest identyczny z użyciem throw new GradleException("The sky is falling!!")(Gradle 3.4.1)
mgaert
@mgaert Wydaje mi się, że 4 lata temu, kiedy to pisałem, wydrukowany komunikat różnił się (ale to długo i nie mam ochoty zastanawiać się, która wersja była wtedy aktualna i sprawdzać). Poza tym IMHO ant.fail wyraźniej komunikuje zamiar całkowitego zatrzymania kompilacji, podczas gdy zgłoszony wyjątek jest odczytywany jako coś, co można złapać i obsłużyć.
Gus
12

Zgłoszenie prostego GradleException działa w przypadku zatrzymania skryptu kompilacji. Działa to świetnie do sprawdzania wymaganej konfiguracji środowiska.

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

Przykład:

if(null == System.getenv()['GRADLE_USER_HOME']) {
    throw new GradleException('Required GRADLE_USER_HOME environment variable not set.')
}
edvox1138
źródło
5

Oto fragment kodu, który próbuje naśladować sposób, w jaki zadanie Gradle javac zgłasza błędy:

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." )
            )
        }
    }
}

Gdy polecenie powróci, 0nie ma wyjścia. Każda inna wartość spowoduje wydrukowanie standardOutput i zatrzymanie kompilacji.

UWAGA: Jeśli polecenie zapisuje również w errorOutput, może być konieczne uwzględnienie tego w dzienniku błędów.

cmcginty
źródło