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

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

Что такое архетип?

Архетип maven - это шаблонный проект. Maven предлагает несколько архетипов, которые позволяют создавать новые модули maven, готовые к запуску за несколько секунд.

Как использовать общий архетип?

Использовать архетип довольно просто. Если вы хотите сгенерировать архетип на основе списка по умолчанию, просто запустите:

mvn archetype:generate

Затем выберите один из вариантов, укажите детали и подтвердите. Новый проект уже будет создан.

Как использовать стандартный архетип?

В этом случае нам нужно указать groupId и artifactId архетипа, чтобы иметь возможность использовать настраиваемый. В качестве примера давайте посмотрим на архетип, предоставленный Adobe для AEM:

mvn archetype:generate  \
     -DarchetypeGroupId=com.adobe.aem \
     -D archetypeArtifactId=aem-project-archetype \
     -D archetypeVersion=27

Если вы запустите команду, вас спросят о некоторых свойствах вашего проекта. Некоторые свойства являются стандартными (groupIdversionartifactId и package), но другие были специфичны этого артефакта, как appTitle и sdkVersion. Эти свойства помогут архетипу сгенерировать для вас новый проект, и через несколько секунд, ничего не зная об Adobe AEM, вы получите свой новый проект, готовый к запуску.

Как работает архетип?

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

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>${groupId}</groupId>
        <artifactId>${rootArtifactId}</artifactId>
        <version>${version}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>${artifactId}</artifactId>
    <name>${appTitle} - Core</name>
    <description>Core bundle for ${appTitle}</description>
...

Пример извлечен из проекта Github adobe/aem-project-archetype.

В Maven есть хорошая документация, как организовать и создать свой архетип с нуля.

Создание архетипа из проекта

В большинстве случаев поддерживать архетип сложно, потому что:

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

  2. Шаблоны - это хорошо, но их трудно читать, и вам нужно «представить», как будет выглядеть код после.

  3. Мы ленивы, и если это трудно понять, то будет сложно поддерживать. Люди вернутся к проектам копирования и вставки и заменят текст.

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

Создайте свой пример проекта для архетипа

Некоторые желательные характеристики в проекте примера для архетипа:

  1. Он должен быть простым, но полным. Не забудьте включить все зависимости и по одному примеру каждого элемента вашего проекта. Например, если проект представляет собой микросервис, имеет смысл включить контроллер, службу и репозиторий.

  2. Назовите его связным образом (вы увидите это на следующих шагах). Я бы порекомендовал, например, иметь контроллер под названием ArchetypeExampleController, который общается с ArchetypeExampleService.

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

  4. Включите dot-файлы как часть этого проекта и хороший файл readme.

archetype:create-from-project

Цель maven archetype:create-from-project - ключ к созданию архетипа из проекта.

В рамках конфигурации вы можете передать файл archetype.properties в качестве параметра. Этот файл свойств должен выглядеть так:

# these are standard properties
package=com.almeida.tomas
groupId=archetype.it
artifactId=basic
version=1.0.0-SNAPSHOT

# here we add our personalized properties
defaultClassPrefix=ArchetypeExample
defaultVariablePrefix=archetypeVariable

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

Шаг-за-шагом

Давайте пройдем все шаги от нашего примера проекта архетипа до нашего архетипа.

1. Переименуйте все dot-файлы.

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

mv .gitignore dot.gitignore
mv .file dot.file

2. Вызовите цель maven с желаемыми параметрами.

mvn -U clean archetype:create-from-project \
      -Dinteractive=false \
      -DkeepParent=true \
      -DpropertyFile=archetype.properties \
      -DpackageName=com.almeida.tomas \
      -Darchetype.filteredExtensions=java,xml,md

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

  • -Dinteractive=false: интерактивный режим отключен.

  • -DkeepParent=true: оставить родителя.

  • -DpropertyFile=archetype.properties: используйте наш файл archetype.properties для проверки переменных.

  • -DpackageName=com.almeida.tomas: имя пакета для источников java, который должен быть включен в архетип.

  • -Darchetype.filteredExtensions=java,xml,md: файлы с выбранными расширениями будут проверены, а содержимое и имя файлов будут изменены переменными.

3. Очистите сгенерированные метаданные архетипа.

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

cd target/generated-sources/archetype/
sed -i 's/.*defaultValue.*//g' src/main/resources/META-INF/maven/archetype-metadata.xml 

4. Установите или разверните архетип.

Если вы запускаете эти команды локально, архетип в вашем локальном репо:

# be sure to be in the target/generated-sources/archetype folder
mvn -B -U clean install

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

# deploy the archetype to repository
mvn -B -U clean deploy

Используйте созданный вами архетип

Созданный архетип будет иметь такой же artifactId с суффиксом -archetype. Итак, исходя из нашего примера:

mvn archetype:generate \
     -DarchetypeGroupId=tomas.examples \
     -DarchetypeArtifactId=archetypeProject-archetype \
     -DarchetypeVersion=1.0.0-SNAPSHOT

Теперь нас попросят указать значение для переменных по умолчанию и персонализированных переменных:

Define value for property 'groupId': com.tomas.almeida
Define value for property 'artifactId': demo-project
Define value for property 'version' 1.0-SNAPSHOT: 1.0.0-SNAPSHOT
Define value for property 'package' com.tomas.almeida: com.tomas.almeida.domain 
Define value for property 'defaultClassPrefix': Demo 
Define value for property 'defaultVariablePrefix': demo 

Подтвердите, что значения, которые вы ввели, верны:

Confirm properties configuration:
groupId: com.tomas.almeida
artifactId: demo-project
version: 1.0.0-SNAPSHOT
package: com.tomas.almeida.domain 
defaultClassPrefix: Demo
defaultVariablePrefix: demo
 Y: : Y 

Будет создана новая папка с именем artifacId. В нашем примере demo-project.

cd demo-project

Необходимо переименовать dot-файлы:

mv dot.gitignore .gitignore
mv dot.file .file

Итак, теперь вы можете создать несколько клонов вашего примера проекта архетипа за считанные минуты!