IntelliJ IDEA verfügt heute über den fortschrittlichsten statischen Java-Code-Analysator, der in seinen Funktionen solche "Veteranen" wie Checkstyle und Spotbugs weit hinter sich gelassen hat . Seine vielen "Inspektionen" überprüfen den Code in verschiedenen Aspekten, vom Codierungsstil bis zu den charakteristischen Fehlern.
Während die Analyseergebnisse nur in der lokalen Oberfläche der Entwickler-IDE angezeigt werden, sind sie für den Entwicklungsprozess von geringem Nutzen. Die statische Analyse sollte als erster Schritt der Baugruppenpipeline durchgeführt werden. Die Ergebnisse sollten die Qualitätstore bestimmen, und die Baugruppe sollte fehlschlagen, wenn die Qualitätstore nicht bestanden werden. Es ist bekannt, dass TeamCity CI in IDEA integriert ist. Aber selbst wenn Sie TeamCity nicht verwenden, können Sie versuchen, IDEA-Inspektionen auf einem anderen CI-Server durchzuführen. Ich schlage vor zu sehen, wie dies mit dem IDEA Community Edition-, Jenkins- und Warnings NG-Plugin erreicht werden kann.
Schritt 1. Führen Sie die Analyse im Container aus und erhalten Sie einen Bericht
Die Idee, eine IDE (Desktop-Anwendung!) In einem CI-System ohne grafische Oberfläche zu starten, kann zunächst zweifelhaft und sehr problematisch erscheinen. Glücklicherweise haben IDEA-Entwickler die Möglichkeit bereitgestellt, Code-Formatierungen und Inspektionen über die Befehlszeile auszuführen . Um IDEA in diesem Modus auszuführen, ist kein grafisches Subsystem erforderlich, und diese Aufgaben können auf Servern mit einer Text-Shell ausgeführt werden.
Inspektionen werden mit dem bin/inspect.sh
aus dem IDEA-Installationsverzeichnis gestartet. Als Parameter sind erforderlich:
- vollständiger Pfad zum Projekt (relativ nicht unterstützt)
- Pfad zur XML-Datei mit Inspektionseinstellungen (normalerweise innerhalb des Projekts in .idea / inspectionProfiles / Project_Default.xml),
- vollständiger Pfad zu dem Ordner, in den XML-Dateien mit Berichten zu den Analyseergebnissen hinzugefügt werden.
Darüber hinaus wird erwartet, dass
- Die IDE konfiguriert den Pfad zum Java SDK, andernfalls funktioniert die Analyse nicht. Diese Einstellungen sind in der Konfigurationsdatei
jdk.table.xml
im globalen IDEA-Konfigurationsordner enthalten. Die globale IDEA-Konfiguration selbst befindet sich standardmäßig im idea.properties
des Benutzers. Dieser Speicherort kann jedoch explizit in der Datei idea.properties
werden. - Das analysierte Projekt sollte ein gültiges IDEA-Projekt sein, für das die Versionskontrolle einige Dateien festschreiben muss, die normalerweise ignoriert werden, nämlich:
.idea/inspectionProfiles/Project_Default.xml
- Analysatoreinstellungen, die offensichtlich beim Starten von Inspektionen im Container verwendet werden..idea/modules.xml
- andernfalls erhalten wir den Fehler 'Dieses Projekt enthält keine Module',.idea/misc.xml
- andernfalls wird der Fehler "Das JDK ist für dieses Projekt nicht richtig konfiguriert" .idea/misc.xml
*.iml-
- Andernfalls wird eine Fehlermeldung zu einem nicht konfigurierten JDK im Modul *.iml-
.
Obwohl diese Dateien normalerweise in .gitignore
, enthalten sie keine Informationen, die für die Umgebung eines bestimmten Entwicklers spezifisch sind - im Gegensatz beispielsweise zur Datei .gitignore
, in der solche Informationen enthalten sind, und daher ist es nicht erforderlich, sie festzuschreiben.
Selbst bittet darum, das JDK zusammen mit der IDEA Community Edition in einem Container in einer Form zu verpacken, in der die analysierten Projekte "festgelegt" werden können. Wir wählen den geeigneten Basiscontainer aus und hier ist die Docker-Datei, die wir erhalten:
Dockerfile FROM openkbs/ubuntu-bionic-jdk-mvn-py3 ARG INTELLIJ_VERSION="ideaIC-2019.1.1" ARG INTELLIJ_IDE_TAR=${INTELLIJ_VERSION}.tar.gz ENV IDEA_PROJECT_DIR="/var/project" WORKDIR /opt COPY jdk.table.xml /etc/idea/config/options/ RUN wget https://download-cf.jetbrains.com/idea/${INTELLIJ_IDE_TAR} && \ tar xzf ${INTELLIJ_IDE_TAR} && \ tar tzf ${INTELLIJ_IDE_TAR} | head -1 | sed -e 's/\/.*//' | xargs -I{} ln -s {} idea && \ rm ${INTELLIJ_IDE_TAR} && \ echo idea.config.path=/etc/idea/config >> idea/bin/idea.properties && \ chmod -R 777 /etc/idea CMD idea/bin/inspect.sh ${IDEA_PROJECT_DIR} ${IDEA_PROJECT_DIR}/.idea/inspectionProfiles/Project_Default.xml ${IDEA_PROJECT_DIR}/target/idea_inspections -v2
Mit der Option idea.config.path
wir IDEA gezwungen, im Ordner /etc/idea
nach seiner globalen Konfiguration zu suchen, da der idea.config.path
des Benutzers unter CI-Bedingungen eine undefinierte und häufig völlig fehlende Sache ist.
So sieht die in den Container kopierte Datei jdk.table.xml
aus, in die die Pfade zum im Container installierten OpenJDK geschrieben werden (eine ähnliche Datei aus Ihrem eigenen Verzeichnis mit IDEA-Einstellungen kann verwendet werden):
jdk.table.xml <application> <component name="ProjectJdkTable"> <jdk version="2"> <name value="1.8" /> <type value="JavaSDK" /> <version value="1.8" /> <homePath value="/usr/java" /> <roots> <annotationsPath> <root type="composite"> <root url="jar://$APPLICATION_HOME_DIR$/lib/jdkAnnotations.jar!/" type="simple" /> </root> </annotationsPath> <classPath> <root type="composite"> <root url="jar:///usr/java/jre/lib/charsets.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/deploy.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/access-bridge-64.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/cldrdata.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/dnsns.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/jaccess.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/jfxrt.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/localedata.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/nashorn.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunec.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunjce_provider.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunmscapi.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/sunpkcs11.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/ext/zipfs.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/javaws.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jce.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jfr.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jfxswt.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/jsse.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/management-agent.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/plugin.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/resources.jar!/" type="simple" /> <root url="jar:///usr/java/jre/lib/rt.jar!/" type="simple" /> </root> </classPath> </roots> <additional /> </jdk> </component> </application>
Das fertige Image ist auf dem Docker Hub verfügbar .
Überprüfen Sie vor dem Fortfahren den Start des IDEA-Analysators im Behälter:
docker run --rm -v <///>:/var/project inponomarev/intellij-idea-analyzer
Die Analyse sollte erfolgreich funktionieren und zahlreiche XML-Dateien mit Analyseberichten sollten im Unterordner target / idea_inspections angezeigt werden.
Jetzt besteht kein Zweifel mehr, dass die IDEA in jeder CI-Umgebung offline ausgeführt werden kann, und wir fahren mit dem zweiten Schritt fort.
Schritt 2. Zeigen Sie den Bericht an und analysieren Sie ihn
Das Abrufen eines Berichts in Form von XML-Dateien ist die halbe Miete. Jetzt müssen Sie ihn für den Menschen lesbar machen. Und auch seine Ergebnisse sollten in Qualitätsgattern verwendet werden - die Logik, um zu bestimmen, ob eine akzeptierte Änderung gemäß Qualitätskriterien bestanden wird oder nicht.
Dies wird uns helfen, Jenkins Warnings NG Plugin , das im Januar 2019 veröffentlicht wurde. Viele einzelne Plugins für die Arbeit mit den Ergebnissen der statischen Analyse in Jenkins (CheckStyle, FindBugs, PMD usw.) sind jetzt als veraltet markiert.
Das Plugin besteht aus zwei Teilen:
- zahlreiche Analysator-Nachrichtensammler (die vollständige Liste enthält alle bekannten Analysatoren von AcuCobol bis ZPT Lint),
- ein einziger Betrachter für alle.
Die Liste der Warnungen, die NG analysieren kann, enthält Warnungen des Java-Compilers und Warnungen der Maven-Laufzeitprotokolle: Obwohl sie ständig in Sicht sind, werden sie selten gezielt analysiert. IntelliJ IDEA-Berichte sind auch in der Liste der erkannten Formate enthalten.
Da das Plugin neu ist, interagiert es zunächst gut mit Jenkins Pipeline. Der Montageschritt mit seiner Teilnahme sieht folgendermaßen aus (wir teilen dem Plug-In lediglich mit, welches Berichtsformat wir erkennen und welche Dateien gescannt werden sollen):
stage ('Static analysis'){ sh 'rm -rf target/idea_inspections' docker.image('inponomarev/intellij-idea-analyzer').inside { sh '/opt/idea/bin/inspect.sh $WORKSPACE $WORKSPACE/.idea/inspectionProfiles/Project_Default.xml $WORKSPACE/target/idea_inspections -v2' } recordIssues( tools: [ideaInspection(pattern: 'target/idea_inspections/*.xml')] ) }
Die Berichtsoberfläche sieht folgendermaßen aus:

Praktischerweise ist diese Schnittstelle für alle anerkannten Analysegeräte universell. Es enthält ein interaktives Diagramm der Verteilung der Funde nach Kategorien und ein Diagramm der Dynamik der Änderungen der Anzahl der Funde. Im Raster unten auf der Seite können Sie eine Schnellsuche durchführen. Das einzige, was IDEA für die Überprüfung nicht funktionierte, war die Möglichkeit, den Code direkt in Jenkins zu durchsuchen (obwohl dieses Plugin für andere Berichte, zum Beispiel Checkstyle, dies wunderbar kann). Dies scheint ein zu behebender IDEA-Report-Parser-Fehler zu sein.
Zu den Funktionen von Warnungen NG gehört die Möglichkeit, Funde aus verschiedenen Quellen in einem Bericht zusammenzufassen und Quality Gates zu programmieren, einschließlich einer Ratsche für die Referenzbaugruppe. Einige Programmierdokumentationen von Quality Gates finden Sie hier - sie sind jedoch nicht vollständig und Sie müssen sich die Quelle ansehen. Andererseits kann die „Ratsche“ zur vollständigen Kontrolle über das Geschehen unabhängig implementiert werden (siehe meinen vorherigen Beitrag zu diesem Thema).
Fazit
Bevor ich mit der Vorbereitung dieses Materials begann, entschied ich mich zu suchen: Hat jemand bereits in Habré zu diesem Thema geschrieben? Ich habe nur ein Interview 2017 mit Lany gefunden, in dem er sagt:
Soweit ich weiß, gibt es keine Integration mit Jenkins oder dem Maven-Plugin [...] Grundsätzlich könnte jeder Enthusiast Freunde IDEA Community Edition und Jenkins finden, viele würden davon profitieren.
Nun: zwei Jahre später haben wir das Warnings NG Plugin und endlich ist diese Freundschaft wahr geworden!