Всем, кто создавал библиотеки или сервисы с публичным API, хорошо знакома боль, когда документация отстает от изменений в коде и рутинный процесс обновления документации на сайте становится настолько неинтересным, что про него просто забывают. Можно ли как-то автоматизировать генерацию технической документации (а в идеале, еще и создание руководства пользователя с возможностью навигации и красивыми картинками)? В этой статье мы обсудим возможности Dokka (Kotlin-инструмента для создания документации) и подходы к генерации артефактов документации с использованием плагинов Gradle.
Сначала подойдем к решению простой задачи — обновление документации публичных методов библиотеки. По традиции, идущей еще из Java, в исходный текст могут добавляться специальные виды комментариев, которые получили название Doc Comment и записываются с префиксом /**
(важно использовать две звездочки) и суффиксом */
. Doc Comment может добавляться как к файлу в целом, так и к классу, методу или свойству класса, описывает функциональность данного фрагмента кода и также может декларировать набор метаданных (например, @author
для определения автора), а также описывать параметры и ожидаемые результаты метода (@param
для указания парметра метода, @return
для описания результата, @throws
для уточнения возможных выбрасываемых исключений), а также связывать фрагменты между собой (@see
). Похожий подход к блокам документации используется сейчас во многих языках программирования и есть даже кроссязыковые инструменты, анализирующие исходные тексты и создающие HTML или PDF-представление документации к библиотеке (например, Doxygen). Также для каждой технологии есть свой инструмент для создания документации на основе комментариев (javadoc в Java, PHPDocumentor для PHP). Для приложений на Kotlin рекомендуется использовать инструмент Dokka, который также поддерживает как комментарии JavaDoc, новый формат комментариев KDoc.
Основной способ интеграции генерации документации для проектов Kotlin — встраивание Dokka в Gradle, для этого необходимо добавить плагин, который добавит дополнительные задачи gradle (dokkaHtml, dokkaGfm, dokkaJavadoc, dokkaJekill):
plugins {
id("org.jetbrains.dokka") version "1.7.10"
}
Создадим простую реализация класса Api:
/**
* My Api Implementation
*
* @author Dmitrii Zolotov
*/
class MyApi {
/**
* @return API version
*/
fun getVersion() = "v1.0"
}
И запустим сборку документации в формате html:
./gradlew dokkaHtml
Документация будет сгенерирована в build/dokka/html и может быть добавлена как артефакт сборки в CI. Если мы хотим получить вариант документации в PDF, одним из решений может быть создание Markdown документации (dokkaGfm или dokkaJekill) и дальнейшая конвертация в PDF с помощью gradle-плагинов, этот вариант мы рассмотрим позднее. Также можно создать документации в стилизации, привычной для java-разработчиков (задача dokkaJavadoc).
Функциональность Dokka может быть расширена с использование плагинов, например, можно подключить дополнение для включения в документацию mermaid-диаграмм (например, графов):
dependencies {
dokkaPlugin("com.glureau:html-mermaid-dokka-plugin:0.3.2")
}
И добавим в документацию описание графа:
/**
* ```mermaid
* graph LR
* A --> B
* B --> C
* C --> A
* ```
*/
fun buildGraph() {
}
После выполнения dokka* задачи будет добавлено изображение графа, созданное mermaid. При необходимости использования других типов содержания можно разработать свой плагин, как расширение класса DokkaPlugin, который представляет из себя сочетание парсера и препроцессора HTML, которые могут подключать ресурсы в HTML (js, css) и создавать HTML-фрагмент на основе обнаруженного фрагмента в doc comment. Пример реализации можно посмотреть здесь.
Альтернативно можно использовать консольный вариант:
java -jar dokka-cli.jar -sourceset -src src/
Любой Javadoc-комментарий также является комментарием KDoc, но при этом в KDoc можно добавлять возможность помечать символы ссылками (в квадратных скобках), указывать название параметра непосредственно в @param[name]
, а также описывать расширенные языковые возможности Kotlin (например, @receiver
для уточнения класс-получателя при описании функции-расширения).
Такой подход к описанию может быть полезен при описании программного интерфейса библиотек, но как быть с API? Здесь могут использоваться расширения, например Ktor OpenAPI Generator для Ktor, которые создают файл в формате OpenAPI 3.0 (json). Для преобразования документации в Markdown можно использовать внешний open source инструмент widdershins или плагин org.openapitools:openapi-generator-gradle-plugin:6.0
.
Markdown-документы (которые могут также включать в себя дополнительные страницы для пользователя) могут быть преобразованы в PDF с помощью плагина io.smartio.gradle.plugin:
plugin {
id "it.smartio.gradle.markdown" version "0.1.19"
}
Также можно выполнить преобразование документов Markdown в HTML:
plugin {
id 'org.kordamp.gradle.markdown' version '2.2.0'
}
Таким образом, полученные артефакты документации из кода (предпочтительно GFM), из реализации сервера (Ktor -> OpenAPI -> Markdown) и инструкция пользователя могут быть преобразованы в единый формат (Markdown или, как возможный вариант, AsciiDoc) и в дальнейшем сконвертированы с помощью плагинов Gradle в HTML или PDF и сохранены как артефакты сборки для дальнейшей автоматической загрузки внутри CI/CD на соответствующий сервер.
Руководство пользователя и прочая сопроводительная документация тоже может располагаться в коде (например, в формате Markdown) и на нее могут быть указаны ссылки в комментариях к соответствующим методам и классам через аннотацию @see
, чтобы сохранить связь функциональности в реализации и в руководстве по использованию, а также иметь возможность быстрого перехода к текстовому описанию, что может помочь поддерживать документацию в актуальном состоянии.
Скоро состоится открытое занятие «Основы классов и объектов». На этом занятии мы посмотрим на принципы проектирования классов и их реализации в Kotlin. Поймем, как объектно-ориентированное программирование работает изнутри, создадим свои структуры и посмотрим на возможности языка Kotlin. Спроектируем объектную модель данных. Записывайтесь по ссылке.