依存関係解析グレードプラグイン:ABIは何ですか?


…のおかげでJack Douglass カバー画像のunsplashについて)
との依存関係解析の私のシリーズへようこそDependency Analysis Gradle Plugin . このポストは、このシリーズの直接のフォローアップとして意図されています.

Abiとは


図書館のABIapplication binary interface , 消費者が何をコード化しているのか.私はそれをライブラリのバイナリAPIと考えるのが好きです.ABIの知識は、増分コンパイルやコンパイル回避のようなGradle機能を有効にするものです.パブリックインターフェイスのコレクションとしてライブラリのABIを考えることができます.依存関係解析に関連する方法を理解するには、次の点を考慮します.
fun newOkHttpClient(gson: Gson): OkHttpClient {  }
これはGson パラメータとしてインスタンスを返し、OkHttpClient . これは、GSONとOKHTTPの両方があなたのABIの一部であることを意味します!Gradleの用語では、ビルドスクリプトで以下を必要とします.
dependencies {
  api "com.google.code.gson:gson:2.8.6"
  api "com.squareup.okhttp3:okhttp:4.8.0"
}
の代わりにapi あなたはimplementation , あなたのプロジェクトはまだコンパイルされるでしょう、しかし、あなたは下流の消費者に問題を起こしています.コンパイルされたクラスパスでこれらのライブラリがなければ、コンパイルできません.図書館作者がこの権利を得ることは非常に重要です.Gradleをご覧くださいdocumentation この分離の詳細な議論のために.
図書館のABIはAbiAnalysisTask . に委ねるabiDependencies and PublicApiDump , 後者はジェットブレーンから直接引き出されたrepository . それは2つの出力を生成します:1つはJSONで、依存分析にかかわる他のタスクによる使用のために意味されます、そして、2番目はより人間的に読みやすい平文出力です.各フォローの抜粋<variant> であろうdebug ( Android )プロジェクトとmain JVMプロジェクトの場合:
JSON :ビルド/レポート/依存解析/変形/中間体/ABI.JSON
[
  {
    "identifier": ":db",
    "configurationName": "implementation"
  },
  {
    "identifier": "androidx.appcompat:appcompat",
    "resolvedVersion": "1.1.0-rc01",
    "configurationName": "implementation"
  }
]
(上記では、プロジェクトが:db と外部依存androidx.appcompat:appcompat このプロジェクトのABIの一部であり、現在は不適切な"実装"と宣言されています.
プレーンテキスト:ビルド/レポート/依存解析/< variant >/中間体/ABIダンプ.txt
public abstract class com/seattleshelter/core/base/BaseActivity : androidx/appcompat/app/AppCompatActivity {
  public fun <init> ()V
  protected fun onCreate (Landroid/os/Bundle;)V
}
(上記のことは、BaseActivity 分析の下のプロジェクトのクラスは、広がりますAppCompatActivity 関数があります.onCreate , それはBundle パラメータとして).
プラグインは、この情報を使用して、プロジェクトの依存関係を宣言する方法についてユーザーに助言します.

事例研究


私は最近、私のチームが内部の消費のために出版する若干の図書館を更新していました.走ったbuildHealth 彼らの上で、アドバイスに続いてください.特に私はこうしました.

(注意:バージョン番号は使用しませんJava Platform plugin .)
私はPRを提出しました.レビューアーは完全に、なぜ私は短剣とRXJavaimplementation to api . 彼らはどこにさらされていたのですか.ここでは、いくつかのパスやクラス名が変更されたので、
あなたが走るならば./gradlew buildHealth このプロジェクトについてhello/build/reports/dependency-analysis/debug/intermediates/abi-dump.txt , あなたは24のUSEDを見つけるでしょうio/reactivex ( RXjava 2から)以下に例を示します:
public final class com/hello/MyService {
    public final fun disableService (Landroid/content/Context;)Lio/reactivex/Completable;
ここではパブリッククラスを持っていますCompletable . したがって、RXJava 2はこのプロジェクトのABIの一部です.
私は、短剣の74の結果を見ます.これが一つです.
public final class com/hello/dao/DbOp {
    public fun <init> (Landroid/content/Context;Ldagger/Lazy;)V
そして、公共の建設者が取る公共のクラスは、ここにありますDagger.Lazy パラメータとして.だから、短剣もABIの一部です.
私は十分にこれをしなければなりませんでした-それは、私自身のプラグインの結果に驚いているようになります.これはプラグインが常に正しいと言うことではありませんcorner cases 私はまだ解決していない-しかし、それは右の99 %以上です.[検証が必要]、私はそれが手動で結果を確認することが可能であることを嬉しく思います.
私は、退屈な部分がすぐに、私が呼ばれて働いているエキサイティングな新機能で消えてほしいですprovenance 別のプロジェクトでこのドラフト機能を使用してからのサンプル出力です
$ ./gradlew db:reasonDebug --id io.reactivex.rxjava2:rxjava
You asked about the dependency io.reactivex.rxjava2:rxjava. You have been advised to add this dependency.

Shortest path to io.reactivex.rxjava2:rxjava from the current project:
:db
\--- androidx.room:room-rxjava2
     \--- io.reactivex.rxjava2:rxjava

Dependency io.reactivex.rxjava2:rxjava provides the following:
- 1651 classes
- 141 public constants

And this project exposes the following classes provided by this dependency:
- io.reactivex.Flowable

Please see abi-dump.txt for more information.
🎉

結論


この記事では、ABIが何であるか、依存関係の解析にどのように関連しているか、どのようにしてDependency Analysis Gradle Plugin は、件名に正確なアドバイスを発している.次回の私にご参加ください.使用の基礎についてお話したいと思いますANTLR ソースコードの解析.