Gradle

Usability improvements

Automatic shortening of long command-lines for Java applications on Windows

When Gradle detects that a Java process command-line will exceed Windows’s 32,768 character limit, Gradle will attempt to shorten the command-line by passing the classpath of the Java application via a «classpath jar».

The classpath jar contains a manifest with the full classpath of the application. Gradle will only pass the generated jar on the command-line to the application. If the command-line is still too long, the Java process will fail to start as before.

If the command-line does not require shortening, Gradle will not change the command-line arguments for the Java process.

More consistent & robust file deletion on Windows

Deleting complex file hierarchies on Windows can sometimes fail with errors like . In the past, Gradle has used workarounds in some but not all cases when deleting files.

Gradle now deletes files in a consistent way that should avoid failures when cleaning output files of a task.

Windows line endings: generates file

To ensure Windows batch scripts retain the appropriate line endings, now generates a file.

This was contributed by Tom Eyckmans.

Gradle now reports the progress of the distribution downloaded.

Initially contributed by Artur Dryomov.

Wrapper tries to recover from an invalid Gradle installation

If the wrapper determines a Gradle distribution installed by the wrapper is invalid, the wrapper will attempt to re-install the distribution. Previous versions of the wrapper would fail and require manual intervention.

Daemon logs contain the date and timestamp

When logging messages to the Gradle daemon log, our log format only contain the time and not the date.

Gradle now logs with ISO-8601 date timestamps.

How to upgrade

We’ve provided a document to help you upgrade from Gradle 5.x to Gradle 6.0. If you’re using something older than Gradle 5.0, you may want to see all the new things in Gradle 5.0 first.

Before upgrading, we recommend you:

  • Upgrade to Gradle 5.6.4 using the Gradle wrapper.

  • Run to list all uses of deprecated Gradle APIs with their locations.
  • Update your Gradle plugins, especially those listed in the deprecations report from the build scan.
  • See the or reach out on the community forums if you get stuck.

You can share feedback with the Gradle team via @gradle on Twitter. Go forth and Build Happiness!

Upgrade Gradle 5.x to 6.0
Compare Gradle vs. Maven

Трансформация кода в Android 2. Анализ AST

  • Первая часть
  • Пример на Github

В этой статье расскажу о том, как решал проблемы, с которыми столкнулся в предыдущей части при реализации проекта.

Во-первых, при анализе трансформируемого класса, нужно как-то понять, является ли этот класс наследником или , чтобы с уверенностью сказать, что класс подходит для нашей трансформации.

Во-вторых, в трансформируемом файле для всех полей с аннотацией нужно явно определить тип, чтобы вызвать соответствующий метод у бандла для сохранения/восстановления состояния, а точно определить тип можно лишь проанализировав всех родителей класса и реализуемые ими интерфейсы.

Таким образом, нужно просто иметь возможность анализировать абстрактно синтаксическое дерево трансформируемых файлов.

Update to newer Scala Zinc compiler

The Zinc compiler has been upgraded to version 1.3.0. Gradle no longer supports building for Scala 2.9.

This fixes some Scala incremental compilation bugs and improves performance.

The minimum Zinc compiler supported by Gradle is 1.2.0 and the maximum tested version is 1.3.0.

To make it easier to select the version of the Zinc compiler, you can now configure a property:

Please note that the coordinates for the supported version of Zinc has changed since Zinc 1.0. If you try to use the compiler, Gradle will switch to the new Zinc implementation with a default version (1.3.0).

This was originally contributed by Predrag Knežević.

Недостатки

Единственной разницей между использованием композитных сборок и является доступность классов без соответствующих плагинов. Она проявляется, когда мы применяем блок вместо или прямых вызовов функций. Главное достоинство использования блока в том, что в Groovy-скриптах работает автодополнение. У вас будет доступ к классам и расширениям, относящимся к конкретным плагинам. Но вы не можете быть уверены в том, что расширения полностью сконфигурированы на момент применения плагина.

Допустим, у вас такой набор плагинов:

Плагин при конфигурировании просто выводит в консоли текущий . В этой реализации будет выведено значение . Теперь попробуем использовать блок .

Теперь вы увидите в консоли , потому что применился до конфигурации . Исправить это можно несколькими способами:

  1. Продолжать использовать или статические функции. Если мигрировать трудно, то никто не запрещает делать по-старому.
  2. Использовать внутри плагина блок . Но будьте осторожны: если злоупотребить этим, то блоки начнут зависеть от других блоков и порядка их исполнения.
  3. Попробовать преобразовать логику в плагине с помощью ленивого API, задач и других механизмов. Для этого нужно хорошо разбираться в Gradle API, но зато вы сможете создавать переиспользуемые и независимые плагины.

CI TeamCity — Автоматизация build процессов Android и UI тестирования

В этой статье предлагаю Вашему вниманию инструкцию по установке и настройке TeamCity для автоматизации сборки и тестирования Android проектов под Windows.
Также буду уделять внимание особенностям настройки environment’а под Android проект (которые находил в процессе исследования) и различного рода вещам, которые могут помочь облегчить жизнь начинающему тестировщику и разработчику

Цели:

При обновлении кода проекта должно происходить:

  • Автоматическая сборка проекта
  • Прогон UI автотестов
  • Экспорт APK файлов debug и release для последующего ручного тестирования
  • Уведомление всех участников команды разработки о результатах

План:

  1. Установка и настройка Java JDK
  2. Установка и настройка Android SDK
  3. Установка отдельного Gradle для дебага
  4. Подготовка Android проекта
  5. Установка TeamCity Server и Build Agent
  6. Настройка TeamCity Project → Build для билда проекта и получения установочного APK
  7. Настройка build steps c UI автотестами

Трансформация кода в Android

Из песочницы

Вместо вступления

Всё началось с того, что мне захотелось изучить тонкости настройки Gradle, понять его возможности в Android разработке (да и вообще). Начал с жизненного цикла и книги, постепенно писал простые таски, попробовал создать свой первый Gradle плагин (в ) и тут понеслось.

Решив сделать что-то, приближенное к реальному миру Android разработки, написал плагин, который парсит layout xml файлы разметки и создает по ним Java объект со ссылками на вьюхи. Затем побаловался с трансформацией манифеста приложения (того требовала реальная задача на рабочем проекте), так как после трансформации манифест занимал порядка 5к строк, а работать в IDE с таким xml файлом довольно тяжело.

Так я разобрался как генерировать код и ресурсы для Android проекта, но со временем захотелось чего-то большего. Появилась мысль, что было бы круто трансформировать AST (Abstract Syntax Tree) в compile time как это делает . Такое метапрограммирование открывает много возможностей, была бы фантазия.

Дабы теория не была просто теорией, я решил подкреплять изучение темы созданием чего-то полезного для Android разработки. Первое, что пришло на ум — сохранение состояния при пересоздании системных компонентов. Грубо говоря, сохранение переменных в Bundle максимально простым способом с минимальным бойлерплейтом.

Other new features and usability improvements

Abbreviation of kebab-case project names

Gradle allows you to . For example, you can execute the task by running .

Up until this release, fuzzy name matching only worked for camelCase names (e.g. ). This is the recommended convention for task names, but it is unusual for project names. In the Java world, directory names are usually all lowercase by convention and in Gradle, project names usually follow the name of the directory the project is in.

Many projects worked around this limitation by using kebab-case project directories (e.g. ) while defining different camelCase project names in their settings scripts. This allowed them to use project name abbreviations in the command line but added additional complexity to the build.

This release changes the fuzzy name matching to support for kebab-case names. Now, you can execute the task in the project with the following command:

Bootstrapping new projects with

The built-in task can be used to quickly create a new Gradle build or convert a Maven build to a Gradle build.

In this release, the projects generated by have been updated to use the latest recommended build authoring practices. Some of the generated builds demonstrate the use of for sharing common build logic.

For new projects, you can now generate a multi-project build for JVM languages. In order to generate a multi-project build, choose , select one of the JVM languages and then choose :

For Maven-to-Gradle conversion, this release adds support for generating Kotlin DSL scripts.

Included builds are now visible to buildSrc

We recommend that builds use the specially named build to organize imperative and common build logic.

Sometimes, you may also need to share build logic between itself and your root build. In the previous releases, that was not possible because could not access build logic from other included builds.

In this release, it’s now possible to share build logic between buildSrc and the root build or any other included build. This makes it easier to share common repository declarations or conventions between buildSrc and other builds as demonstrated in this sample.

APIs for better plugins

Gradle 6.0 makes it easier for you to build fast and correctly behaving plugins.

Minimizing the amount of work a task needs to do

With Gradle, it’s very simple to implement a task that is skipped when all of . This allows Gradle to perform incremental builds where only tasks that need to execute are executed.

For some tasks, less work can be done even when the task needs to execute. If only a few input files have changed since the last execution, the task only needs to reprocess files that have changed. Gradle calls these types of tasks incremental tasks. To implement an incremental task, use the InputChanges API.

Making work parallel-safe

Gradle 6.0 has a tasks can use for submitting units of work to be executed in parallel. Tasks that opt-in to this API give Gradle more flexibility to start other tasks in parallel.

Plugin authors using this API can move a task’s action into a separate classloader or even a separate process. Separate processes are reused when possible and expired if they consume too many resources. Separate classloaders allow the plugin a lot of flexiblity to control the classpath used by the task’s action.

The parameters into a unit of work are type-safe and isolated, so they can’t be modified concurrently to the unit of work’s action. Parameters can be optional (null) or be made up of complex types (e.g., file collections). There are several into an action to perform common functions like copying and deleting files or forking other processes.

Validating task configuration

Tasks that define their inputs or outputs incorrectly can cause problems when running incremental builds or when using the build cache. As part of an ongoing effort to bring these problems to light, Gradle 6.0 now .

When issues are detected, Gradle will show warnings when run with :

Deprecation warnings will always show up in build scans regardless of the command-line arguments used.

Transforming artifacts from dependencies

A dependency’s artifacts can take many forms–JARs, AARs, ZIPs and other formats. You may even need a format that isn’t published by the library you’re using.

As an example, take a Java module that publishes a normal JAR file. As a consumer, you want to use the normal JAR for development, but you need to use an obfuscated JAR for production builds instead.

Since the obfuscated JAR is not available in any repository, you must use the normal JAR and obfuscate it yourself.

Gradle provides an API for registering artifact transforms that hook into the dependency management resolution engine. An artifact transform can specify that whenever an obfuscated JAR is requested but can’t be found, Gradle should run a transform to create the obfuscated JAR and make it appear as an available artifact.

Dependency management improvements

The dependency management documentation has been reorganised and structured around use cases to help users find the information they need faster. We’ve improved the terminology section to explain the commonly used terms.

The publication of Gradle Module Metadata is now the default when using the or plugins.

Many of the features below rely on the production or consumption of additional metadata not found in Ivy or Maven POM files.

Sharing dependency versions between projects

Gradle offers an easy way to recommend and share versions between projects called platforms.

With Gradle platforms, more context around version declaration are available, versions can be recommended and strict versions are enforced.

For interoperability, builds can also leverage .

Handling mutually exclusive dependencies

Gradle uses component capabilities to allow plugins and builds to detect and resolve implementation conflicts between mutually exclusive dependencies.

A well-known example in the JVM world is competing logging implementations. Component capabilities let builds configure which dependency to select.

Upgrading versions of transitive dependencies

Issues with dependency management are often about dealing with transitive dependencies. Often developers incorrectly fix transitive dependency issues by adding direct dependencies. To avoid this, Gradle provides the concept of dependency constraints to influence the version of transitive dependencies.

Aligning versions across multiple dependencies

Dependency version alignment allows builds to express that different modules belong to the same logical group (like a platform) and need to have identical (a.k.a aligned) versions in a dependency graph.

A well-known example in the JVM world is the Jackson libraries.

Expressing intent with context

When declaring a dependency, a build can provide more context to Gradle about its version, including version preferences within a range, strict version requirements or rejected versions. Developers can also provide human readable descriptions for why a dependency is used or needed.

Tweak published metadata

Gradle allows builds to fix or enrich traditional metadata with information that could not be published before, such as dependency constraints, rich versions, capabilities and variants. These are called component metadata rules.

Component metadata rules also make it possible to to new Gradle variants.

Modeling feature variants and optional dependencies

Gradle provides the ability to model optional features of a library. Each feature can have its own set of dependencies and can be consumed separately.

With feature variants, Gradle provides first-class support for to . Test fixtures can be consumed by other projects in a multi-project build.

Built-in javadoc and sources packaging and publishing

You can now activate Javadoc and sources publishing for a Java Library or Java project:

Using the or plugin, this will not only automatically create and publish a and but also publish the information that these exist as variants in Gradle Module Metadata. This means that you can query for the Javadoc or sources variant of a module and also retrieve the Javadoc (or sources) of its dependencies.

If activated, a Java and Java Library project automatically provides the and tasks.

Writing Gradle build logic

You can now write your Gradle build scripts in Kotlin.
Furthermore, has been expanded with project types and interactivity.

Kotlin DSL provides IDE assistance

Kotlin DSL 1.0 is production-ready as of Gradle 5.0.
Static-typing in Kotlin allows tools to provide better IDE assistance, including debugging and refactoring of build scripts, auto-completion and everything else you would expect.

If you are interested in authoring your builds in Kotlin, start with the Gradle Kotlin DSL Primer.

Expanded and interactive

Users wanting to create new Gradle builds have additional project types to choose from: and .
Additionally, you can choose to generate Groovy or Kotlin DSL build scripts, and customize the project name and package.
Finally, a new interactive UI makes the experience especially pleasant.

More navigable and use-case oriented documentation

The Gradle documentation and getting started guides are more informative, discoverable, and accessible with:

  • Several new and improved pages, including: Getting Started, Troubleshooting, CLI Reference, Managing Transitive Dependencies, and several others
  • Searchable reference documentation hosted by Algolia DocSearch.
  • A reformatted PDF for offline viewing
  • Categorized navigation
  • Docs version selection

Мой опыт конфигурирования Gradle

Система сборки Gradle для сборки Android приложений была представлена вместе с Android Studio. Последняя существовала не всегда: если вы разрабатываете Android-приложения более шести лет, то, вероятно, помните Eclipse с Android-плагином. Сегодня эта комбинация считается устаревшей и не поддерживается.

В то время Gradle и Groovy казались магией (и до сих пор кажутся) и я копировал всё подряд со Stack Overflow. Поскольку у приложений редко было больше одного модуля, считалось совершенно нормальным хранить всё в одном файле .

Я начал использовать модули для внешних библиотек каждый раз, когда мне хотелось что-то в них исправить. Я просто копировал всю магию из файла приложения в библиотечный файл. Метод отлично работал, если не считать того, что всё приходилось дублировать, например обновлять версии зависимостей во всех модулях. Позднее я обнаружил, что можно использовать корневой файл для создания общей конфигурации модулей.

Стало намного лучше, но не идеально. Корневой файл оказался слишком большим и сложным в поддержке. Когда в моду вошла модульность и мы начали разделять свои приложения на модули , , и , я открыл другой подход: извлечь эти функции в отдельные скрипты Gradle и применять их.

Такому решению не хватает автодополнения в IDE, которое даже не получится добавить. В эту проблему можно решить с помощью блока , но для всех остальных файлов скриптов он недоступен.

Сейчас, годы спустя, многие разработчики, в том числе и я, используют для управления общими конфигурациями. После многих лет страданий применение в проектах стало настоящим счастьем. Вы можете использовать любой JVM-язык, иметь полноценное автодополнение и поддержку IDE. Вы можете даже писать тесты: модульные (с помощью JUnit или любого другого фреймворка) или интеграционные тесты, которые запускают отдельный экземпляр Gradle в тестовом окружении. Неужто мы, наконец, нашли святой Грааль конфигурирования Gradle?!

Organizing your build logic

Gradle 6.0 helps you get your build under control.

Organization-wide Gradle properties via custom distribution gradle.properties

Gradle now looks for a gradle.properties file in the Gradle distribution used by the build. This file has the and properties defined in other locations will override values defined here.

By placing a gradle.properties file in a , an organization can add default properties for the entire organization or tweak the default Gradle daemon memory parameters with .

Central management of plugin versions from settings.gradle

Gradle 6.0 makes it easier to used by your build. By configuring all plugin versions in the settings script within the new block, build scripts can apply plugins via the block without specifying a version.

One benefit of managing plugin versions in this way is that plugin versions may be loaded from or defined programmatically.

Plugin development with Composite Builds

The block in build scripts can now be used to refer to plugins defined in included builds. In previous versions of Gradle, this was possible but required some additional boiler-plate code in the settings file. This boiler-plate is now no longer required.

This change makes it super easy to add a test build for a Gradle plugin and streamlines the process of implementing a Gradle plugin. You can also use this feature to conveniently work on changes to a plugin and builds that use that plugin at the same time, to implement a plugin that is both published and used by projects in the same source repository, or to structure a complex build into a number of plugins.

Using the block also makes the Gradle Kotlin DSL much more convenient to use.

You can find out more about composite builds in the user manual.

Fine-grained transitive dependency management

Gradle 5.0 provides several new features for customizing how dependencies are selected and features improved POM and BOM support:

  • Dependency constraints allow you to define versions or version ranges to restrict direct and transitive dependency versions (not supported by Maven).
  • Platform definitions, aka Maven BOM dependencies are natively supported, allowing importing things like the Spring Boot platform definition without using an external plugin.
  • Dependency alignment allows different modules in a logical group (Jackson modules, for example) to be aligned to the same version.
  • Dynamic dependency versions can now be locked to allow better build reproducibility.

Dependency constraints

provide robust control of transitive dependencies.
Declared constraints are listed in the improved and build scans.

BOM support

Gradle 5.0 can .

In addition, Gradle 5.0 provides a more seamless experience when consuming dependencies produced by a Maven build.

  • When consuming POM files, Gradle will properly . This avoids reduced performance and dependency leaking caused by previously including dependencies on the compile classpath.
  • Gradle also now honors of POMs.

Dependency alignment

allows different modules belonging to the same logical group (a platform) to have identical versions in a dependency graph.

This solves the problem of ensuring that all your Spring or Hibernate dependencies have the same version (where applicable).
In fact, there are many libraries that are published as a set, with each library in the set having the same version.
There are other use cases for this feature, so please follow the link above to learn more from the docs.

Dependency version locking

You can lock dynamic or ranged dependencies to specific versions using Gradle 5.0 to make dependency resolution more deterministic and reproducible.
This prevents changes in transitive dependencies from breaking your builds unexpectedly.

Other new features and usability improvements

Abbreviation of kebab-case project names

Gradle allows you to . For example, you can execute the task by running .

Up until this release, fuzzy name matching only worked for camelCase names (e.g. ). This is the recommended convention for task names, but it is unusual for project names. In the Java world, directory names are usually all lowercase by convention and in Gradle, project names usually follow the name of the directory the project is in.

Many projects worked around this limitation by using kebab-case project directories (e.g. ) while defining different camelCase project names in their settings scripts. This allowed them to use project name abbreviations in the command line but added additional complexity to the build.

This release changes the fuzzy name matching to support for kebab-case names. Now, you can execute the task in the project with the following command:

Bootstrapping new projects with

The built-in task can be used to quickly create a new Gradle build or convert a Maven build to a Gradle build.

In this release, the projects generated by have been updated to use the latest recommended build authoring practices. Some of the generated builds demonstrate the use of for sharing common build logic.

For new projects, you can now generate a multi-project build for JVM languages. In order to generate a multi-project build, choose , select one of the JVM languages and then choose :

For Maven-to-Gradle conversion, this release adds support for generating Kotlin DSL scripts.

Included builds are now visible to buildSrc

We recommend that builds use the specially named build to organize imperative and common build logic.

Sometimes, you may also need to share build logic between itself and your root build. In the previous releases, that was not possible because could not access build logic from other included builds.

More memory efficient Gradle execution

Features like for tests and command-line arguments for JVM apps allow for better dev workflows, while lower memory requirements and cache cleanup reduce Gradle’s overhead on your system.

Lower memory requirements

Not only will your builds be faster just by upgrading, but they’ll also use significantly less memory.
Many caching mechanisms have been optimized in Gradle 5.0, and as a result the default maximum memory for Gradle processes .

Process Type Gradle 4.x default heap Gradle 5.0 default heap
Command-line client 1 GB 64 MB
Gradle Daemon 1 GB 512 MB
Worker processes 1/4 of physical memory 512 MB

Periodic Gradle cache cleanup

The days of manually cleaning up gigabytes of old Gradle caches are over. Gradle now periodically.
Gradle also tracks stale task outputs more precisely, and cleans them up in cases where not doing so could lead to incorrect results.

Usability improvements

Automatic shortening of long command-lines for Java applications on Windows

When Gradle detects that a Java process command-line will exceed Windows’s 32,768 character limit, Gradle will attempt to shorten the command-line by passing the classpath of the Java application via a «classpath jar».

The classpath jar contains a manifest with the full classpath of the application. Gradle will only pass the generated jar on the command-line to the application. If the command-line is still too long, the Java process will fail to start as before.

If the command-line does not require shortening, Gradle will not change the command-line arguments for the Java process.

More consistent & robust file deletion on Windows

Deleting complex file hierarchies on Windows can sometimes fail with errors like . In the past, Gradle has used workarounds in some but not all cases when deleting files.

Gradle now deletes files in a consistent way that should avoid failures when cleaning output files of a task.

Windows line endings: generates file

To ensure Windows batch scripts retain the appropriate line endings, now generates a file.

This was contributed by Tom Eyckmans.

Gradle now reports the progress of the distribution downloaded.

Initially contributed by Artur Dryomov.

Wrapper tries to recover from an invalid Gradle installation

If the wrapper determines a Gradle distribution installed by the wrapper is invalid, the wrapper will attempt to re-install the distribution. Previous versions of the wrapper would fail and require manual intervention.

Daemon logs contain the date and timestamp

When logging messages to the Gradle daemon log, our log format only contain the time and not the date.

Gradle now logs with ISO-8601 date timestamps.

New Gradle invocation options

Testing

Gradle 5.0 includes support for JUnit 5: JUnit Platform, JUnit Jupiter, and JUnit Vintage. This support allows you to enable and filtering, and to include custom test engines.

You can use the to enable a quicker red-green cycle, which is improved further by Gradle 5.0 by default.

Logging

In Gradle 5.0, log messages are now grouped by the task that generated them for non-interactive environments like continuous integration execution.

In addition to showing which tests are executing, Gradle’s rich command-line console shows a colored build status that tells you at a glance whether any have failed.
You can also ask Gradle to using the “verbose” console mode.

Finally, Gradle warning logs can be summarized, silenced, or expanded by configuring the .
This will be very helpful for upgrading your build to Gradle 5.0.

Build Scan Deprecations View

Composite Builds

allow you to include other independent projects so that you can, for instance, develop an application and a library that it depends on simultaneously.

You can now inspect .
Composite builds are also compatible with .

They build in parallel by default, and can now be nested.

Command-line arguments for JVM applications

Running Java applications with custom arguments gets a lot easier with Gradle 5.0 because you can simply on the command line or through your IDE.

Better builds for Java, Groovy and Scala developers

You can bring improvements to your Java, Groovy or Scala builds by upgrading to Gradle 6.0.

Faster Java incremental compilation

When analyzing the impact of a changed class, the incremental compiler can now exclude classes that are an implementation detail of another class. This limits the number of classes that need to be recompiled. For deep dependency chains, this greatly reduces the number of files that require recompilation.

As an example, compiling a project with 5000 source files after changing a single source file:


Gradle 5.6 takes 21s to compile.

Gradle 6.0 only takes 0.5s to compile the same change.

Faster Groovy Compilation

Gradle 6.0 speeds up compilation for Groovy with two strategies.

Gradle uses to skip re-compiling dependent projects if there are no changes that would affect the output of their compilation.

Gradle also uses incremental Groovy compilation. If only a small set of Groovy source files have been changed, only the affected source files will be recompiled. For example, if you only change one Groovy test class, Gradle doesn’t need to recompile all Groovy test source files. Gradle will recompile only the changed classes and the classes that are affected by them.

The same analysis improvements that also apply to Groovy compilation.

This feature requires changes to your build to use. See and for more details.

Latest Zinc compiler integration

Gradle 6.0 uses the latest Zinc incremental Scala compiler. The Zinc compiler saw major performance improvements in Zinc 1.0.

By default, Gradle uses Zinc 1.3.0.

Support for a wide range of JDKs

Gradle 6.0 now supports Java 13.

Gradle supports running on JDK8 through JDK13. JDK6 and 7 can still be used for compilation and testing.

Add Javadoc and sources jars

You can now activate Javadoc and sources publishing for a Java Library or Java project:

Using the or plugin, this will not only automatically create and publish a -javadoc.jar and -sources.jar but also publish the information that these exist as variants in Gradle Module Metadata. This means that you can query for the Javadoc or sources variant of a module and also retrieve the Javadoc (or sources) of its dependencies.

If activated, a Java and Java Library project automatically provides the javadocJar and sourcesJar tasks.

Sharing test fixtures between projects

Gradle 6.0 allows Java test fixtures from one project to be shared with other projects in the build. Gradle will automatically perform the necessary wiring so that test compilation depends on test fixtures.
The plugin needs to be applied with the plugin.
It can also be combined with other JVM language plugins, like Groovy or Scala, to write test fixtures in these languages.

For example, this will add the test fixtures of “my-lib” to the compile classpath of the tests in this project.

Миграция с buildSrc на композитную сборку

Теперь я расскажу о миграции нашей библиотеки Reaktive на композитную сборку. Это прекрасный пример по ряду причин:

  • у неё есть buildSrc, в котором находятся собственные плагины;
  • у неё есть внешний конфигурационный файл binary-compatibility.gradle;
  • у неё общая логика находится внутри корневого файла build.gradle.

То есть применены все три подхода, описанные в первой части статьи. Я покажу, как работать с каждым из них и как преобразовать их в отдельные плагины.

Копирование

Первый шаг прост. Скопируем папку в папку . Если вы ещё не используете плагины в папке , то самое время начать. Без плагинов классы из нового модуля не будут загружены в classpath скрипта. Пока не удаляйте исходную папку , чтобы была возможность синхронизировать проект. Чтобы сообщить Gradle о появлении нового модуля, добавим в следующий код:

Первая строка добавлена для нашего удобства и для удаления блока . С помощью функции мы заставляем Gradle обращаться с проектом в папке как с включённой сборкой.

Миграция плагинов

Как начать использовать плагины и классы из ? Сначала объявим плагины.

создаст для плагинов соответствующие файлы , так что теперь эти файлы можно удалить. Почитать о можно .

Если у вас пока нет плагинов для управления зависимостями и вы используете только , нужно создать пустой плагин и применить его к проекту, чтобы классы стали доступны в Gradle-скрипте.

После применения к проекту становится доступен класс . И автодополнение будет работать как прежде.

Миграция общих функций

В есть функция .

Она определяет некую общую конфигурацию для всех модулей. Мы применили плагин Kotlin Multiplatform и объявили некоторые важные зависимости.

Для преобразования этой функции в Gradle-плагин нужно добавить зависимость и объявить его:

Также у нас есть параметризованная настройка для с параметром . Корутины не поддерживают , а мы поддерживаем. Поэтому нужно уметь настраивать модули как с поддержкой , так и без неё. Для этого можно отфильтровать , но поддерживать отдельно такой список проектов не хочется. Давайте реализуем это с помощью расширения, как это делают другие плагины.

К сожалению, здесь мы не можем сделать наоборот ( и включать по умолчанию), потому что плагин Kotlin не обрабатывает удаление целевой платформы компиляции (только добавление). Зато мы можем применить конфигурацию с помощью плагина и его расширения .

Автодополнение работает как надо.

Миграция внешнего файла скрипта

Мы используем Binary compatibility validator, который я описывал в другой статье. Его конфигурация определяется внутри binary-compatibility.gradle и применяется в корневом файле . По сути, скрипт просто применяет плагин и задаёт игнорируемые модули.

Теперь можно преобразовать этот скрипт в плагин с помощью описанного выше подхода.

Затем применим наш новый плагин внутри корневого файла .

Зависимости

С нашим новым подходом необходимо управлять зависимостями в основном проекте и во включённых сборках. В последних мы будем использовать в качестве зависимостей разные плагины, чтобы обеспечить доступ к соответствующим классам, таким как расширения проектов, задачи и т. д. Для управления зависимостями создадим ещё одну включённую сборку.

Теперь мы можем создать класс для всех внешних зависимостей. Посмотреть реализацию можно здесь. Добавим в новый модуль с помощью . Теперь можно в любом проекте использовать плагин и класс .

В процессе реализации этого подхода я обнаружил, что если использовать включённую сборку в качестве зависимости внутри другой включённой сборки, то IDEA не подсвечивает её классы в редакторе (хотя проект компилируется без ошибок). Чтобы это исправить, я вручную добавил класс в компиляцию , чтобы он был доступен везде, где применяются плагины из . Это довольно грубый и нестабильный костыль, но я надеюсь, что это поведение исправят. После этого достаточно будет использовать обычную нотацию .

Плагин можно использовать в модулях основного проекта вышеописанным способом.

Оцените статью
Рейтинг автора
5
Материал подготовил
Андрей Измаилов
Наш эксперт
Написано статей
116
Добавить комментарий