openlang

Каталог версий виден везде, кроме convention-плагинов

Переношу версии в gradle/libs.versions.toml, а общие настройки держу в convention-плагинах в buildSrc. Задумка была в том, чтобы у версий было одно место. Три случая по порядку.

В скрипте сборки подпроекта работают и alias(libs.plugins.kotlin.jvm), и libs. Претензий нет.

Скрипт сборки самого buildSrc каталог основного проекта не наследует. Его надо подключить руками в buildSrc/settings.gradle.kts.

dependencyResolutionManagement {
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

Пока всё по документации. Немного странно объяснять buildSrc, где в его же репозитории лежит файл, но работает, и аксессоры появляются.

С третьего случая начинается невесёлое. В прекомпилированном скриптовом плагине внутри buildSrc типобезопасного libs нет. Документация предлагает доставать каталог по имени через extensions.getByType(VersionCatalogsExtension::class.java).named("libs") и потом спрашивать каждую запись по псевдониму. А блок plugins такого плагина до каталога вообще не дотягивается, так что convention-плагин, который применяет другой плагин, называет его по id, а версия приходит оттуда, где buildSrc объявил артефакт плагина.

Картина неровная. Самые неважные скрипты сборки получают самые удобные аксессоры. Convention-плагины, где теперь живёт большая часть общих настроек, получают поиск по строкам.

Так что одно место, где записи достаются по имени, остаётся всегда. Тут начинаешь думать, не честнее ли держать координаты внутри convention-плагинов просто строками.

Разговор продолжается 3

Следуя доводам
  1. Ссылка на ответ

    Против строк. Тогда версия живёт в двух местах. Раз в каталоге, раз в convention-плагине. Рано или поздно обновят только одно.

    Поиск по имени уродлив, тут ko_jae прав. Но это одна уродливая строка, а у версии по-прежнему один дом. Держите вызовы findLibrary вместе, в одном плагине, тогда неверный псевдоним хотя бы упадёт в одном файле, и понятно, куда смотреть.

  2. Ссылка на ответ

    Способ otto для библиотек подходит. Один convention-плагин берёт каталог через named("libs") и получает координаты библиотек через findLibrary("guava").get().

    Смущает другое. Опечатка падает двумя очень разными способами. Опечатка в libs.guava в подпроекте останавливает компиляцию скрипта сразу, на неразрешённом имени. А если опечататься в псевдониме внутри convention-плагина, findLibrary возвращает пустой Optional, затем get() бросает NoSuchElementException, и в сообщении о псевдониме ни слова. Можно как-то вытащить псевдоним в это сообщение, или все просто грепают findLibrary, когда такое случается?

  3. Ссылка на ответ

    Голое исключение, на которое наткнулся ko_jae, идёт из get(). Замените на orElseThrow с сообщением. fun VersionCatalog.lib(alias: String) = findLibrary(alias).orElseThrow { IllegalStateException("catalog has no library '$alias'") }. Все обращения только через эту функцию.

    Неверный псевдоним тогда падает на этапе конфигурации со своим именем в сообщении.

Другие стороны того же вопроса

  1. tryEval пропустил нарочно сломанный пакет

    Есть у меня небольшой обход оверлея, который оборачивает каждый пакет в builtins.tryEval и перечисляет упавшие. Он сообщил, ч…

    Ответы 4nix
  2. Ключи for_each - это адреса, а не ярлыки

    Ключ for_each - не ярлык. Это половина адреса ресурса, terraform_data.queue["prod-orders"], и состояние хранит объект именно…

    Ответы 6hcl
  3. Остановленное задание оболочки ещё не завершено

    Пришёл вопрос про правило супервизора, которое считает остановленный процесс завершённым, и маленький пример сразу показывает…

    Ответы 17bashpython