Как получить версию проекта Maven в командной строке bash - PullRequest
163 голосов
/ 23 августа 2010

Раньше я задавал вопрос на , как изменить версию проекта Maven из командной строки , что привело меня к новой проблеме.

Ранее я мог получить номер версии, начиная с версиибыл сохранен как свойство, которое было легко найти и проанализировать из командной строки (bash).Теперь, когда для этого используется элемент pom.xml, он больше не является уникальным, поскольку все зависимости и, возможно, некоторые другие тоже используют это.Я думаю, что нет способа получить номер текущей версии с помощью bash-скрипта без внешних инструментов для разбора xml или какой-либо очень контекстно-зависимой команды sed.

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

Итак, есть ли простой способ получить значение ${project.version} в командной строке?Заранее спасибо.

Решение

Спасибо за помощь.Мне пришлось cd в каталог вручную, но это можно сделать легко.В моем bash-скрипте у меня есть

version=`cd $project_loc && mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | sed -n -e '/^\[.*\]/ !{ /^[0-9]/ { p; q } }'`

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

# Advances the last number of the given version string by one.
function advance_version () {
    local v=$1
    # Get the last number. First remove any suffixes (such as '-SNAPSHOT').
    local cleaned=`echo $v | sed -e 's/[^0-9][^0-9]*$//'`
    local last_num=`echo $cleaned | sed -e 's/[0-9]*\.//g'`
    local next_num=$(($last_num+1))
    # Finally replace the last number in version string with the new one.
    echo $v | sed -e "s/[0-9][0-9]*\([^0-9]*\)$/$next_num/"
}

ИЯ использую это, просто позвонив по номеру

new_version=$(advance_version $version)

Надеюсь, это кому-нибудь поможет.

Ответы [ 26 ]

191 голосов
/ 23 августа 2010

Плагин Maven Help как-то уже предлагает что-то для этого:

  • help:evaluate вычисляет выражения Maven, заданные пользователем в интерактивном режиме.

Вот как вы можете вызвать его в командной строке, чтобы получить ${project.version}:

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
    -Dexpression=project.version
173 голосов
/ 22 октября 2014

Решение Тома с плагином Exec Maven намного лучше, но все же сложнее, чем должно быть. Для меня это так просто, как:

MVN_VERSION=$(mvn -q \
    -Dexec.executable=echo \
    -Dexec.args='${project.version}' \
    --non-recursive \
    exec:exec)
44 голосов
/ 31 мая 2018

Я провел некоторое исследование и обнаружил следующее:

  1. Maven обвиняют в том, что он не может быть легко интегрирован в сценарии работы системы, поскольку он не следует некоторым рекомендациям относительно инструментов CLI,(ref: https://youtu.be/1ILEw6Qca3U?t=372)

  2. Вдохновленный предыдущим утверждением, я решил взглянуть на исходный код maven, а также на maven-help-plugin. Кажется, они немного исправленыключ -q maven (я использую версию 3.5.3), так что теперь, если вы передадите его, вы не получите всю раздражающую логику бессмысленного ведения журнала, которая не позволяет использовать maven в автоматизированных сценариях.использовать что-то вроде этого:

    mvn help:evaluate -Dexpression=project.version -q
    

    Проблема в том, что эта команда ничего не печатает, потому что по умолчанию плагин справки выводит через регистратор, который был отключен переключателем -q. (последняя доступная версия плагина)3.1.0 выпущено 3 июня 2018 года)

  3. Карл Хайнц Марбейс (https://github.com/khmarbaise) исправил его, добавив необязательный параметр, который позволяет вызывать его следующим образом:

    mvn help:evaluate -Dexpression=project.version -q -DforceStdout
    

    Описание фиксации доступно по адресу: (https://github.com/apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014)

44 голосов
/ 04 октября 2012
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
34 голосов
/ 06 мая 2016

Лучший ответ, на мой взгляд, довольно мусор, вы должны использовать кучу grep, чтобы взломать вывод консоли maven.Почему бы не использовать правильный инструмент для работы?Использование синтаксиса xpath - лучший подход для получения номера версии, поскольку это предполагаемый метод доступа к структуре данных XML.Выражение ниже пересекает pom, используя «локальное имя» элементов, другими словами, игнорируя объявления пространства имен, которые могут присутствовать или не присутствовать в xml.

xmllint --xpath "//*[local-name()='project']/*[local-name()='version']/text()" pom.xml
26 голосов
/ 12 апреля 2016

Это позволит избежать необходимости извлечения записей журнала из вывода:

mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
12 голосов
/ 21 марта 2015
python -c "import xml.etree.ElementTree as ET; \
  print(ET.parse(open('pom.xml')).getroot().find( \
  '{http://maven.apache.org/POM/4.0.0}version').text)"

Пока у вас есть Python 2.5 или выше, это должно работать.Если у вас более низкая версия, установите python-lxml и измените импорт на lxml.etree.Этот метод быстрый и не требует загрузки дополнительных плагинов.Он также работает с искаженными файлами pom.xml, которые не проверяются с помощью xmllint, например, те, которые мне нужно проанализироватьПротестировано на Mac и Linux.

9 голосов
/ 06 июля 2016

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

7 голосов
/ 12 июня 2014

Если вы не возражаете записать версию во временный файл, есть другое решение (без grep / sed), которое мне подходит.( РЕДАКТИРОВАТЬ : см. ответ rjrjr для более простого решения без каких-либо временных проблем с файлами)

Я использую Exec Maven Plugin вместе сecho бинарный.В отличие от плагина справки Maven, плагин Exec позволяет перенаправлять вывод в файл, который можно использовать для обхода grep / sed, и даже позволяет анализировать странные вещи, такие как строки многострочных версий (с блоком CDATA в теге версии),по крайней мере, в определенной степени.

#!/usr/bin/env sh

MVN_VERSION=""
VERSION_FILE=$( mktemp mvn_project_version_XXXXX )
trap "rm -f -- \"$VERSION_FILE\"" INT EXIT

mvn -Dexec.executable="echo" \
    -Dexec.args='${project.version}' \
    -Dexec.outputFile="$VERSION_FILE" \
    --non-recursive \
    --batch-mode \
    org.codehaus.mojo:exec-maven-plugin:1.3.1:exec > /dev/null 2>&1 ||
    { echo "Maven invocation failed!" 1>&2; exit 1; }

# if you just care about the first line of the version, which will be
# sufficent for pretty much every use case I can imagine, you can use
# the read builtin
[ -s "$VERSION_FILE" ] && read -r MVN_VERSION < "$VERSION_FILE"

# Otherwise, you could use cat.
# Note that this still has issues when there are leading whitespaces
# in the multiline version string
#MVN_VERSION=$( cat "$VERSION_FILE" )

printf "Maven project version: %s\n" "$MVN_VERSION"
6 голосов
/ 09 августа 2016

Только для записи, можно настроить ведение журнала простого SLF4J в Maven непосредственно в командной строке для вывода только того, что нам нужно, путем настройки:

  • org.slf4j.simpleLogger.defaultLogLevel=WARN и
  • org.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO

как указано на http://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html

MAVEN_OPTS="\
-Dorg.slf4j.simpleLogger.defaultLogLevel=WARN \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO" \
mvn help:evaluate -o -Dexpression=project.version

В результате можно просто запустить tail -1 и получить:

$ MAVEN_OPTS="\
-Dorg.slf4j.simpleLogger.defaultLogLevel=WARN \
-Dorg.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO" \
mvn help:evaluate -o -Dexpression=project.version | tail -1

1.0.0-SNAPSHOT

Обратите внимание, что это однострочник. MAVEN_OPTS переписываются только для этого конкретного mvn исполнения.

...