Зависимости для пользовательской задачи инкрементальной компиляции Gradle

Я задаюсь вопросом о наилучшем подходе к управлению пользовательским шагом компиляции с файлами, которые имеют транзитивные зависимости, если я хочу, чтобы моя задача компиляции была инкрементной. Вот конкретный вариант использования: у меня есть каталог, полный шаблонов (шаблоны руля в этом случае). Допустим, это в pages каталог. Некоторые из этих шаблонов включают другие шаблоны (партиалы Handlebars). Допустим, включенные шаблоны находятся в includes, Компилировать все шаблоны довольно легко. Например, я мог бы использовать команду handlebars как handlebars <input-file> скомпилировать каждый файл в pages (например for (File file : srcDir) { project.exec { commandLine 'handlebars', file.name }}.

При вызове команды handlebars компилируется input-file и, при необходимости, вытягивает любой из шаблонов input-file include и любые из включенных, которые включают в себя add и т. д. Не вдаваясь в ненужные детали, я также могу изучить полный набор транзитивных зависимостей для шаблона при его компиляции. Так, например, если шаблон A включает в себя B и C, а B включает E в процессе компиляции A I, то узнает, что если B, C или E изменятся, мне нужно перекомпилировать A. Обратите внимание, что мне в значительной степени нужно скомпилировать шаблон изучать эту информацию по мере необходимости, чтобы проанализировать ее и определить все места, которые она включает, как она включает в себя, и т. д.

Я хотел бы создать пользовательскую инкрементную задачу, которая компилирует файлы, но только при необходимости. Я знаю, как объявлять входные данные для этой задачи, и я знаю, как поддерживать в памяти карту из файлов в каталоге include для шаблонов на страницах, которые зависят от нее напрямую или транзитивно. Таким образом, если, например, IncrementalTaskInputs.outOfDate включает в себя включает в себя /E I, я знаю, что мне нужно перекомпилировать A. Пока все хорошо, но я не знаю, как лучше всего это сделать на самом деле.

Ясно, что хранение зависимостей только в памяти не будет работать, так как демон может перезапуститься или даже не работать (и я не совсем понимаю, какие объекты выживают в памяти в демоне между запусками в любом случае). Насколько я понимаю, Gradle поддерживает некоторый вид кеша, поэтому он мог бы вычислять надлежащие IncrementalTaskInputs и знать, что, например, включает только / E, измененный с момента его последнего запуска. Поэтому мне как-то нужно поддерживать кеш зависимостей, которые я могу при необходимости считывать с диска. Я могу сделать это вручную, просто записав их в файл, но это кажется подверженным ошибкам. Например, несвоевременное нажатие клавиши Ctrl-C может привести к устареванию моего кэша с помощью кэша Gradle. Я предполагаю, что есть встроенная система, которая позволяет мне просто объявлять зависимости и заставлять Gradle позаботиться об этом вместе с собственным кешем. Или еще лучше, может быть, существует существующий базовый класс, который обрабатывает подобные вещи, и все, что мне нужно сделать, это объявить, каковы зависимости? Есть ли такие вещи?

1 ответ

Я также разместил это в списке разработчиков Gradle. Стефан Оеме ответил следующим ответом, который, я считаю, правильный:

Такого готового к повторному использованию механизма пока нет. У нас есть инкрементная компиляция для Java, и идея ее дальнейшего развития возникла изнутри. Но пока нет конкретного плана, о котором я знаю.

Я не совсем понимаю, какие объекты выживают в памяти в любом случае между пробегами

Пока путь к классу buildscript не изменяется, классы выживают между вызовами Gradle. Однако экземпляры (например, проект) воссоздаются при каждой сборке. Таким образом, в качестве первого кадра вы можете хранить вещи в статических переменных. Если это состояние отсутствует, вы делаете полную сборку. Это уже очень поможет любому, кто использует демон с вашим плагином.

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