(С благодарностью Джек Дуглас на откреплении для изображения обложки)
Добро пожаловать в мою серию по анализу зависимостей с помощью плагина Dependency Analysis Gradle |/. Этот пост задуман как прямое продолжение предыдущего поста в этой серии, в котором обсуждалось обнаружение неиспользуемых зависимостей.
ABI библиотеки или двоичный интерфейс приложения , это то, что потребители компилируют против (а не то, против чего вы кодируете!). Мне нравится думать об этом как о библиотечном двоичном 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
вы использовали реализация
, ваш проект все равно будет компилироваться, но вы создадите проблемы для нижестоящих потребителей. Без этих библиотек в их пути к классу компиляции они не смогут компилироваться. Критически важно чтобы авторы библиотек поняли это правильно. Пожалуйста, ознакомьтесь с Gradle documentation для подробного обсуждения этого разделения.
ABI библиотеки определяется с помощью Задачи анализа Abi . Он делегирует зависимостям abi и Общедоступный дамп Api , последний из которых был извлечен непосредственно из репозитория JetBrains | . Он выдает два выходных данных: один представляет собой JSON и предназначен для использования другими задачами, участвующими в анализе зависимостей, а второй представляет собой более понятный для человека текстовый вывод. Выдержки из каждого следуют (где <вариант> будет |/debug
(и т.д.) для проекта Android и main
для проекта JVM):
json: сборка/отчеты/анализ зависимостей/<вариант>/промежуточные звенья/api.json
[ { "identifier": ":db", "configurationName": "implementation" }, { "identifier": "androidx.appcompat:appcompat", "resolvedVersion": "1.1.0-rc01", "configurationName": "implementation" } ]
((Вышеизложенное указывает на то, что проект :db
и внешняя зависимость androidx.appcompat:appcompat
оба являются частью этого ABI проекта и в настоящее время объявлены — неправильно — в “реализации”.)
открытый текст: сборка/отчеты/анализ зависимостей/<вариант>/intermediates/abi-dump.txt
public abstract class com/seattleshelter/core/base/BaseActivity : androidx/appcompat/app/AppCompatActivity { public fun()V protected fun onCreate (Landroid/os/Bundle;)V }
(Вышеизложенное указывает на то, что общедоступный BaseActivity
класс анализируемого проекта расширяет AppCompatActivity
и имеет функцию,/| onCreate , для этого требуется
Bundle в качестве параметра.)
Плагин использует эту информацию, чтобы консультировать пользователей о том, как лучше всего объявить зависимости своего проекта.
Недавно я обновлял некоторые библиотеки, которые моя команда публикует для внутреннего потребления. Я пробежал build Health
по ним и последовал совету. В частности, я сделал это:
(Примечание: номера версий отсутствуют, потому что я использую плагин Java Platform .)
Я подал заявку на пиар. Рецензент вполне резонно спросил, почему я меняю Dagger и RxJava с implementation
на api
. Где они были разоблачены? Вот что я ему сказал (с некоторыми путями и именами классов, измененными по причинам):
Если вы запустите ./gradlew build Health
в этом проекте, а затем откройте hello/build/reports/dependency-analysis/debug/intermediates/abi-dump.txt
, вы найдете 24 использование ввода-вывода|reactivex/| (из RxJava2). Вот один пример:
public final class com/hello/MyService { public final fun disableService (Landroid/content/Context;)Lio/reactivex/Completable;
Здесь у нас есть открытый класс с открытой функцией, которая возвращает Завершаемый
. Таким образом, RxJava 2 является частью ABI этого проекта.
Я вижу 74 результаты для dagger. Вот один из них:
public final class com/hello/dao/DbOp { public fun(Landroid/content/Context;Ldagger/Lazy;)V
А вот открытый класс, открытый конструктор которого принимает Dagger. Lazy
в качестве параметра. Итак, Кинжал тоже является частью ABI.
Мне приходилось делать это достаточно часто — то есть удивляться результатам моего собственного плагина, утомительно проверять их вручную, наконец, следовать советам, — что теперь я просто пропускаю первые два шага и следую совету. Это не значит, что плагин всегда прав — есть раздражающие угловые случаи , которые я еще не разрешил, но это правильно более чем в 99% случаев. [требуется проверка] Тем не менее, я рад, что можно проверить результаты вручную, хотя и утомительно.
Я надеюсь, что утомительная часть скоро исчезнет, благодаря новой захватывающей функции, над которой я работаю, под названием ” происхождение “, которая автоматизирует этот процесс объяснения. Вот пример вывода при использовании этой черновой функции в другом проекте
$ ./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 точные рекомендации по этому вопросу. Пожалуйста, присоединяйтесь ко мне в следующий раз, когда я надеюсь рассказать об основах использования ANTLR для анализа исходного кода.
Оригинал: “https://dev.to/autonomousapps/dependency-analysis-gradle-plugin-what-s-an-abi-3l2h”