Кодогенерация с помощью Maven Archetype

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

В принципе, для этого и был придуман Maven Archetype.

Стандартизация и единообразие

Maven Archetype позволяет установить стандартную структуру для всех проектов: то есть все проекты будут иметь одинаковую организацию директорий, конфигурационные файлы и базовые зависимости. Благодаря этому новые члены команды могут легко погружаться в любой проект, так как все они будут выглядеть практически одинаково. Это снижает время обучения и упрощает управление проектами.

Экономия времени и усилий

С использованием Archetype можно быстро создать целый проект с нужной настройкой и структурой каталогов. Не нужно больше вручную настраивать pom.xml, создавать стандартные структуры папок или настраивать основные зависимости. Всё создаётся автоматически, что позволяет сразу приступить к написанию кода, избегая рутинных операций.

Лучшая поддержка и расширяемость

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

Легкость интеграции с CI/CD

Maven прекрасно интегрируется с популярными системами непрерывной интеграции и доставки (CI/CD), такими как Jenkins, GitLab CI, CircleCI и так далее. Используя стандартизированные Maven Archetypes, можно легко создавать проекты, полностью готовые к интеграции с вашими CI/CD конвейерами, посредством добавляения необходимых файлов. Это ускоряет процесс выпуска и повышения качества за счет автоматизации тестирования и деплоя.

Снижение количества ошибок

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

Создание собственного архетипа

Для создания собственного архетипа можно воспользовать уже готовым архетипом :)

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-archetype -DarchetypeVersion=1.4 -DgroupId=ru.maksimvoloshin.maven -DartifactId=archetype -Dversion=1.0.0

Заполнив необходимые поля, мы на выходе получим необходимую структуру каталогов:

Кодогенерация с помощью Maven. Сгенированные файлы и каталоги
Кодогенерация с помощью Maven. Сгенированные файлы и каталоги

Всё, что нам потребуется в будущем коде – находится в папке src/main/resources/META-INF/maven. Конкретно – файл archetype-metadata-xml:

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
  name="${artifactId}">
  <fileSets>
    <fileSet filtered="true" packaged="true">
      <directory>src/main/java</directory>
    </fileSet>
    <fileSet filtered="true" packaged="true">
      <directory>src/test/java</directory>
    </fileSet>
  </fileSets>
</archetype-descriptor>

Здесь у нас основной корневой элемент, который содержит в себе набор правил, как обрабатывать файлы. Поскольку Maven достаточно косноязычен (но прост и быстр, в целом), приходится каждую папку описывать отдельно.

Элемент fileSets содержит в себе fileSet’ы, которые мы будем переносить при генерации. Тэг fileSet имеет два аттрибута: filtered и packaged

  • filtered – указывает, нужно ли при переносе использовать Velocity движок. То есть мы можем писать условия и вообще творить магию, используя Apache Velocity.
  • packaged – указывает, надо ли упаковать это в директорию указанного пакета (то есть в каталоги

Как видно на скриншоте, часть файлов мне нужно исключить (потому что в них используется знак $). Поэтому сначала я копирую то, что нужно скопировать с фильтрацией и исключаю. А потом наоборот.

Кодогенерация с помощью Maven. Использование fileSet -> include / exclude
Кодогенерация с помощью Maven. Использование fileSet -> include / exclude

А вот пример обработки, используя Apache Velocity:

Кодогенерация с помощью Maven. Использование Apache Velocity
Кодогенерация с помощью Maven. Использование Apache Velocity

Также в archetype-metadata.xml есть полезный тэг requiredProperties, содержащий в себе requiredProperty, которые можно стребовать при генерации или задать их по умолчанию:

Кодогенерация с помощью Maven. Использование requiredProperty
Кодогенерация с помощью Maven. Использование requiredProperty

В целом, для каких-то простых вещей, этого хватает. Но я для себя открыл ещё один лайфхак. Maven поддерживает пост обработку после генерации архетипа. Делается это через добавление файла archetype-post-generate.groovy в директорию src/main/resources/META-INF

import java.nio.file.Path
import java.nio.file.Paths

// путь, куда сгенерируется проект
Path projectPath = Paths.get(request.outputDirectory, request.artifactId)

// проперти, заданные при создании архетипа
Properties properties = request.properties

// Имя пакета
String packageName = properties.get('package')

// конвертируем имя пакета в путь
String packagePath = packageName.replace('.', '/')

// настройки
boolean withParam = Boolean.valueOf(properties.get('withParam') as String)

Используя этот файл, можно создать, удалить, изменить уже существующие файлы под какие-то условия. Например, withParam задаётся через requiredProperty (предполагается, что он будет типа boolean) и дальше мы можем что-то сделать, опираясь на это условие.

После того, как всё готово, просто требуется выполнить mvn install для отправки в артефакта в локальный репозиторий. После чего, он будет доступен для Maven. Также, при отправке в удалённый репозиторий, потребуется обновления (автоматическое или ручное) файла archetype-catalog.xml, чтобы Maven увидел этот артефакт.

Ну и не забываем, что в центральном репозитории Maven уже лежит свыше 3000 готовых артефактов :)

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *