Как встроить архетипную версию проекта в архетип Maven? - PullRequest
17 голосов
/ 28 августа 2011

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

Например, исходный проект выглядит так:

origin/archetype/... archetype for generating project 
      /core/... core services 
      /extra/... extra services 

и архетип сгенерирует проект с POM, который содержит зависимости вроде так:

<dependencies> 
  <dependency> 
    <groupId>com.foo</groupId> 
    <artifactId>origin-core</artifactId> 
    <version>SOMEVERSION</code> 
  </dependency> 
</dependencies> 

Я хочу, чтобы SOMEVERSION была версией исходного проекта в то время что архетип построен и установлен в хранилище.

Так что, если исходный проект имеет версию 1.0-SNAPSHOT и mvn install ed, то я хочу, чтобы архетип генерировал зависимость от origin-core 1.0-SNAPSHOT. И когда исходный проект выпущен, и автоматически столкнулся с версией 1.0, я хочу, чтобы архетип генерировал зависимость от origin-core 1.0.

В основном, я хотел бы использовать ${archetypeVersion} в качестве переменной Velocity в архетипе. ПОМ, но это не представляется возможным.

Есть ли другой способ выполнить то, что я пытаюсь сделать здесь?

Ответы [ 3 ]

36 голосов
/ 28 августа 2011

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

Используйте фильтрацию Maven в файле src/main/resources/archetype-resources/pom.xml для замены в текущей версии проекта при создании архетипа.

Вот как это делается:

Измените ваш файл archetype/pom.xml, чтобы включить фильтрацию для файла archetype-resources/pom.xml, а не для чего-либо еще (поскольку ваши файлы архетипов будут, естественно, иметь ${variable} s повсеместно, и вы не хотите, чтобы их заменяли время сборки, вы хотите, чтобы они были заменены при создании архетипа).

<resources>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
      <include>archetype-resources/pom.xml</include>
    </includes>
  </resource>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <excludes>
      <exclude>archetype-resources/pom.xml</exclude>
    </excludes>
  </resource>
</resources>

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

<pluginManagement>
  <plugins>
    ...
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-resources-plugin</artifactId>
      <version>2.5</version>
      <configuration>
        <escapeString>\</escapeString>
      </configuration>
    </plugin>
  </plugins>
</pluginManagement>

(Обратите внимание, что элементы <resources> и <pluginManagement>, показанные выше, должны быть размещены внутри элемента <build> вашего POM.)

Используйте ${project.version} в вашем архетипе pom, куда вы хотите вставить версию своего проекта архетипа, и избегайте всех других переменных, которые должны оставаться незамещенными до времени генерации архетипа:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  <modelVersion>4.0.0</modelVersion>

  <groupId>\${groupId}</groupId>
  <artifactId>\${artifactId}</artifactId>
  <version>\${version}</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>com.foo</groupId>
      <artifactId>origin-core</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

</project>
13 голосов
/ 10 марта 2014

Альтернативным решением для принятого ответа является фильтрация свойства по умолчанию в дескрипторе / метаданных архетипа файла

Это сделано так:

Фильтр maven фильтрует только этот файл:

<resources>
<resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
        <include>META-INF/maven/archetype-metadata.xml</include>
    </includes>
</resource>
<resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <excludes>
        <exclude>META-INF/maven/archetype-metadata.xml</exclude>
    </excludes>
</resource>
</resources>

Файл метаданных архетипа:

<archetype-descriptor ...>
    <requiredProperties>
        <requiredProperty key="projectVersion">
            <defaultValue>${project.version}</defaultValue>
         </requiredProperty>
    </requiredProperties>

    ...
</archetype-descriptor>

и POM архетипа будет аналогичен ранее, за исключением того, что в качестве версии проекта будет использоваться обязательное значение свойства projectVersion:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  <modelVersion>4.0.0</modelVersion>

  <groupId>${groupId}</groupId>
  <artifactId>${artifactId}</artifactId>
  <version>${version}</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>com.foo</groupId>
      <artifactId>origin-core</artifactId>
      <version>${projectVersion}</version>
    </dependency>
  </dependencies>

</project>

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

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

0 голосов
/ 19 июня 2014

Я попробовал что-то довольно глупое, и, похоже, сработало. Я добавил следующее в мой файл META-INF / maven / archetype-metadata.xml:

<requiredProperties>
    <requiredProperty key="archetypeVersion"> </requiredProperty>
</requiredProperties>

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

...