IntelliJ IDEAには今日、最も高度な静的Javaコードアナライザーがあり、その機能はCheckstyleやSpotbugsのような「ベテラン」に大きく後れを取っていました 。 その多くの「検査」は、コーディングスタイルから特徴的なバグまで、さまざまな面でコードをチェックします。
ただし、分析結果は開発者IDEのローカルインターフェイスにのみ表示されますが、開発プロセスにはほとんど役立ちません。 静的解析は 、アセンブリパイプラインの最初のステップとして実行する必要があり 、その結果は品質ゲートを決定する必要があり、品質ゲートが合格しない場合、アセンブリは失敗します。 TeamCity CIはIDEAと統合されることが知られています。 ただし、TeamCityを使用していない場合でも、他のCIサーバーでIDEA検査を実行しようとする場合があります。 IDEA Community Edition、Jenkins and Warnings NGプラグインを使用してこれを行う方法を確認することを提案します。
ステップ1.コンテナーで分析を実行し、レポートを取得する
最初は、グラフィカルインターフェイスを持たないCIシステム内でIDE(デスクトップアプリケーション!)を起動するという考えは、疑わしく、非常に面倒に思えます。 幸いなことに、IDEA開発者は、コマンドラインからコードの書式設定と検査を実行する機能を提供しました。 さらに、このモードでIDEAを実行するには、グラフィックスサブシステムは不要であり、これらのタスクはテキストシェルを備えたサーバーで実行できます。
検査は、IDEAインストールディレクトリのbin/inspect.sh
を使用して起動されます。 パラメーターが必要なため:
- プロジェクトへのフルパス(相対サポートなし)
- 検査設定を含む.xmlファイルへのパス(通常、プロジェクト内の.idea / inspectionProfiles / Project_Default.xmlにあります)、
- 分析結果に関するレポートを含む.xmlファイルが追加されるフォルダーへのフルパス。
さらに、それは期待されます
- IDEはJava SDKへのパスを設定します。そうしないと、分析が機能しません。 これらの設定は、IDEAグローバル構成フォルダーの
jdk.table.xml
構成ファイルに含まれています。 グローバルIDEA構成自体はデフォルトでユーザーのホームディレクトリにありますが、この場所はidea.properties
ファイルで明示的に指定できます。 - 分析されたプロジェクトは有効なIDEAプロジェクトである必要があります。バージョン管理では、通常無視されるいくつかのファイルをコミットする必要があります。
.idea/inspectionProfiles/Project_Default.xml
アナライザーの設定。コンテナーで検査を開始するときに明らかに使用されます。.idea/modules.xml
それ以外の場合、「このプロジェクトにはモジュールが含まれていません」というエラーが表示されます。.idea/misc.xml
それ以外の場合は、「このプロジェクトに対してJDKが正しく構成されていません」というエラーが表示されます。*.iml-
-そうしないと、モジュール内の未構成のJDKに関するエラーが発生します。
これらのファイルは通常.gitignore
に含まれていますが、特定の開発者の環境に固有の情報は含まれていません。たとえば、そのような情報が含まれるworkspace.xml
ファイルとは異なり、コミットする必要はありません。
それ自体は、分析されたプロジェクトを「設定」できる状態で、JDKをIDEA Community Editionと一緒にコンテナにパックする方法を求めています。 適切なベースコンテナを選択します。取得するDockerfileは次のとおりです。
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
idea.config.path
オプションを使用して、 idea.config.path
のユーザーのホームフォルダーは未定義であり、多くの場合完全に存在しないため、IDEAは/etc/idea
フォルダーでグローバル構成を探すように強制しました。
これは、コンテナにコピーされたjdk.table.xml
ファイルがどのように見えるかで、コンテナ内にインストールされたOpenJDKへのパスが書き込まれます(IDEA設定を持つ独自のディレクトリから同様のファイルを取得できます)。
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>
完成したイメージはDocker Hubで入手できます 。
次に進む前に、コンテナ内のIDEAアナライザの開始を確認します。
docker run --rm -v <///>:/var/project inponomarev/intellij-idea-analyzer
分析が正常に機能し、アナライザーレポートを含む多数の.xmlファイルがサブフォルダーtarget / idea_inspectionsに表示されるはずです。
これで、IDEAをどのCI環境でもオフラインで実行できることに疑いはなくなり、次のステップに進みます。
ステップ2.レポートを表示および分析する
.xmlファイルの形式でレポートを取得することは、戦いの半分であり、人間が読めるようにする必要があります。 また、その結果は品質ゲートで使用する必要があります。これは、受け入れられた変更が品質基準に従って合格するかどうかを決定するロジックです。
これは、2019年1月にリリースされたJenkins Warnings NG Pluginに役立ちます。 その外観により、Jenkinsの静的解析の結果を処理するための多くの個々のプラグイン(CheckStyle、FindBugs、PMDなど)が廃止されたとマークされています。
プラグインは2つの部分で構成されています。
- 多数のアナライザーメッセージコレクター( 完全なリストには、AcuCobolからZPT Lintまでのすべての既知のアナライザーが含まれます)
- それらすべてのための単一のビューア。
警告NGが分析できるリストには、Javaコンパイラからの警告とMavenランタイムログからの警告が含まれます。これらは常に見えていますが、意図的に分析されることはほとんどありません。 IntelliJ IDEAレポートも、認識されている形式のリストに含まれています。
プラグインは新しいので、最初はJenkins Pipelineとうまくやり取りします。 彼が参加するアセンブリ手順は次のようになります(プラグインに、どのレポート形式を認識し、どのファイルをスキャンする必要があるかを指示します)。
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')] ) }
レポートインターフェースは次のようになります。
便利なことに、このインターフェースは、すべての認識されているアナライザーに共通です。 カテゴリごとの発見の分布のインタラクティブな図と発見の数の変化のダイナミクスのグラフが含まれています。 ページの下部にあるグリッドで、クイック検索を実行できます。 IDEAが検査のために機能しなかった唯一のことは、Jenkinsでコードを直接参照する機能でした(たとえば、Checkstyleなどの他のレポートの場合、このプラグインはそれを美しく実行できます)。 これは、修正するIDEAレポートパーサーのバグのようです。
Warnings NGの機能の中には、さまざまなソースからの検出結果を1つのレポートに集約し、リファレンスアセンブリのラチェットを含むQuality Gatesをプログラムする機能があります。 一部のQuality Gatesプログラミングドキュメントはここから入手できますが、完全ではないため、ソースを確認する必要があります。 一方、何が起こっているかを完全に制御するために、「ラチェット」を個別に実装できます(このトピックに関する以前の投稿を参照してください)。
おわりに
この資料の準備を始める前に、私は検索することにしました:すでに誰かがこのトピックについてHabréで書いたのですか? ラニーとの2017年のインタビューを見つけたところ、彼は次のように語っています。
私の知る限り、Jenkinsやmavenプラグインとの統合はありません[...]原則として、愛好家なら誰でもIDEA Community EditionとJenkinsを友達にすることができます。
まあ:2年後、警告NGプラグインがあり、ついにこの友情が実現しました!