如何将Maven项目版本发送到bash命令行

mkk*_*kko 176 command-line maven-2

之前我发布了一个关于如何从命令行更改Maven项目版本的问题,这引出了一个新问题.

以前我能够获得版本号,因为版本存储为易于grep并从命令行解析的属性(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 } }'`
Run Code Online (Sandbox Code Playgroud)

这给了我当前版本,然后我可以推进.Grepping可能更简单,但我认为我想尽可能健壮,所以我对以数字开头的第一行感到满意,并尝试将其作为版本号处理.

# 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/"
}
Run Code Online (Sandbox Code Playgroud)

我通过简单地打电话来使用它

new_version=$(advance_version $version)
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人.

Pas*_*ent 201

Maven的帮助插件以某种方式已经提出的东西这样的:

  • help:evaluate 评估用户在交互模式下给出的Maven表达式.

以下是如何在命令行上调用它来获取${project.version}:

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
    -Dexpression=project.version
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用`mvn org.apache.maven.plugins删除所有日志记录(INFO,WARNING等)和'Download'消息:maven-help-plugin:2.1.1:evaluate -Dexpression = project.version | grep -Ev '(^\[|下载\ w + :)'` (75认同)
  • 这是我喜欢的方法:`printf'VERSION = $ {project.version} \n0 \n'| mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate | grep'^ VERSION'` (23认同)
  • @montoyaed发布了[最佳答案](/sf/answers/3542963371/),它只是`mvn help:evaluate -Dexpression = project.version -q -DforceStdout`.要在Bash中的变量中捕获它,请使用`version = $(mvn help:evaluate -Dexpression = project.version -q -DforceStdout) (21认同)
  • 不会指望从maven那里得到更多的冗长 (9认同)
  • 好的谢谢.我认为这是最接近清洁解决方案的.任何想法我怎么能抑制maven输出并过滤掉那些`[INFO]`消息?我找不到maven的开关.否则我只需添加一些命令行脚本来解析版本号. (7认同)
  • 我不确定“-q”选项突然隐藏了所有内容,包括表达式结果。 (6认同)
  • 你可能还想添加`2>/dev/null`,否则你可以得到`Picked up _JAVA_OPTIONS:` (4认同)
  • 根据之前的答案,这给出了一个简洁的答案:`printf'VERSION = $ {project.version}'| mvn help:评估| grep'^ VERSION ='| sed's/^ VERSION = // g'` (3认同)
  • 要过滤除版本之外的所有内容,这对我有用:`mvn help:evaluate -Dexpression = project.version | grep -e'^ [^\[]'` (2认同)

rjr*_*rjr 184

使用Exec Maven插件的 Tom的解决方案要好得多,但仍然比它需要的更复杂.对我来说,它很简单:

MVN_VERSION=$(mvn -q \
    -Dexec.executable=echo \
    -Dexec.args='${project.version}' \
    --non-recursive \
    exec:exec)
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最简单的方法,因为它并不意味着使用grep或类似的东西.快速说明:你可以缩短一点:`mvn -q -Dexec.executable ="echo"-Dexec.args ='$ {project.version}' - 非递归exec:exec` (26认同)

Edu*_*oya 60

我一直在做一些研究,发现以下内容:

  1. Maven因系统操作脚本中没有易于集成而受到指责,因为它没有遵循一些关于CLI工具的良好实践.(参考:https://youtu.be/1ILEw6Qca3U? t = 372)

  2. 受到前一个断言的启发,我决定看看maven的源代码以及maven-help-plugin.看起来他们已经修改了maven的-q开关(我使用的是3.5.3版本),所以现在如果你通过它,你将不会得到所有令人讨厌的非感知日志记录内容,以防止maven被使用在自动脚本中.所以你应该可以使用这样的东西:

    mvn help:evaluate -Dexpression=project.version -q
    
    Run Code Online (Sandbox Code Playgroud)

    问题是此命令不打印任何内容,因为默认情况下,帮助插件通过-q开关静音的记录器输出.(该插件的最新可用版本是在2018年6月3日发布的3.1.0)

  3. Karl Heinz Marbaise(https://github.com/khmarbaise)通过添加一个可选参数来修复它,允许您通过以下方式调用它:

    mvn help:evaluate -Dexpression=project.version -q -DforceStdout
    
    Run Code Online (Sandbox Code Playgroud)

    提交说明位于:(https://github.com/apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014)

  • 这将是我的首选解决方案,并且也在官方[帮助页面](https://maven.apache.org/plugins/maven-help-plugin/evaluate-mojo.html)中提到。但是,它对我不起作用。我在使用Maven v3.5.3的MacOS上。当我不使用`-q`开关时,它将正确打印出版本(在日志行之间)。有任何想法吗? (2认同)
  • 这应该是公认的答案。它可以在Windows和Linux(我没有尝试过Max OSX)中工作,而且很简单。谢谢。 (2认同)
  • @gucce我可以确认使用的maven版本会影响这一点:在3.5.2(debian 9上的软件包版本)中,`-q -DforceStdout`的输出为空,甚至确保插件管理的版本3.1.0);我使用 3.5.4 版本的 Maven 配置了 Maven 包装器,并且它工作正常 (2认同)
  • 最后,2019年没有grep的实用解决方案-(这应该成为公认的答案)。也适用于[CI友好版本](https://maven.apache.org/maven-ci-friendly.html)-在3.3.9、3.5.3、3.5.4、3.6.0上进行了测试 (2认同)

小智 45

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
Run Code Online (Sandbox Code Playgroud)

  • 如果按照@NathanBubna的建议使用-o,则会将maven置于"离线"模式.如果您还没有下载maven帮助插件和从属jar,则构建将失败.被那个烧了一点,希望它能帮助别人. (10认同)
  • 使 mvn -o 更快执行 (2认同)
  • 在 Windows 上,将命令的结尾替换为 `| findstr /v "["`. (2认同)

luk*_*and 37

在我看来,最重要的答案是非常垃圾,你必须使用一堆grep来破解maven控制台输出.为什么不使用合适的工具呢?使用xpath语法是检索版本号的最佳方法,因为它是访问XML数据结构的预期方法.下面的表达式是使用元素的"本地名称"遍历pom,换句话说,忽略可能存在或不存在于xml中的名称空间声明.

xmllint --xpath "//*[local-name()='project']/*[local-name()='version']/text()" pom.xml
Run Code Online (Sandbox Code Playgroud)

  • 那个从父pom继承的项目怎么样? (3认同)
  • 这不适用于 ci-friendly 版本控制,例如,版本是像 `${revision}` 这样的属性。参考 https://maven.apache.org/maven-ci-friendly.html (3认同)
  • “为什么不使用正确的工具来完成这项工作?” IE浏览器! (2认同)

Jos*_*ban 28

这样可以避免从输出中删除日志条目:

mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
Run Code Online (Sandbox Code Playgroud)


pdr*_*pdr 13

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)"
Run Code Online (Sandbox Code Playgroud)

只要你有python 2.5或更高版本,这应该工作.如果您的版本低于该版本,请安装python-lxml并将导入更改为lxml.etree.这种方法很快,不需要下载任何额外的插件.它也适用于不使用xmllint验证的格式错误的pom.xml文件,就像我需要解析的那样.在Mac和Linux上测试过.


slo*_*low 10

当我在这里使用其他一些答案时,我一直遇到不好的情况,所以这里还有另一种选择.

version=$(printf 'VER\t${project.version}' | mvn help:evaluate | grep '^VER' | cut -f2)
Run Code Online (Sandbox Code Playgroud)


Man*_*ath 9

这是我发现的最干净的解决方案

mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout
Run Code Online (Sandbox Code Playgroud)

好处:

  • 在所有操作系统上都能正常工作
  • 无需任何外部工具!

注意:

  • 选项-q禁止显示详细消息。
  • maven-help-plugin版本3.2.0(及更高版本)具有forceStdout选项。您可以使用来自工件的mvn-help-plugin3.2.0可用版本列表(如果可用)中的较新版本替换上述命令。

  • 恕我直言,这是最好的答案,因为所有其他人都未能指出(正如我艰难地发现的那样)您至少需要 3.1.0 版本的 maven-help-plugin,因为否则 -DforceStdout 选项[将是未知的] (https://issues.apache.org/jira/browse/MPH-144)并运行“mvn -q help:evaluate ....”将根本不产生任何输出。 (3认同)

小智 8

还有一种不需要 Maven 的选择:

grep -oPm1 "(?<=<version>)[^<]+" "pom.xml"
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 7

如果你不介意将版本写入临时文件,那么另一种解决方案(没有grep/sed)对我来说效果很好.(编辑:请参阅rjrjr的答案,找到一个更简单的解决方案,没有任何临时文件麻烦)

我使用Exec Maven插件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"
Run Code Online (Sandbox Code Playgroud)

  • 这是一个比helper插件更好的解决方案,你不需要所有的i/o.只需添加-q标志,唯一的输出就是版本.所以:mvn -q -Dexec.executable ="echo"-Dexec.args ='$ {project.version}' - non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec (6认同)

fre*_*dev 7

这是迄今为止最简单的 bash 剪切和粘贴解决方案:

VERSION=$(mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q)
echo $VERSION
Run Code Online (Sandbox Code Playgroud)

它呼应

1.4
Run Code Online (Sandbox Code Playgroud)


Ste*_*vra 6

只是为了记录,可以直接在命令行中配置Maven的Simple SLF4J日志记录,仅通过配置输出我们需要的内容:

  • 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
Run Code Online (Sandbox Code Playgroud)

因此,人们可以简单地运行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
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个单行.MAVEN_OPTS正在为这个特定的mvn执行重写.


qui*_*tin 5

我注意到Downloaded:输出中有一些虚假的线条破坏了我原来的任务.这是我已经确定的过滤器; 希望能帮助到你!

version=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | egrep -v '^\[|Downloading:' | tr -d ' \n')
Run Code Online (Sandbox Code Playgroud)

编辑

不是100%肯定为什么,但是当通过Jenkins的后期构建脚本运行时,输出就像是[INFO]version,例如[INFO]0.3.2.

我将输出转储到一个文件并直接从BASH通过我的第一个过滤器运行它,它运行正常...,再次,不确定Jenkins土地上发生了什么.

为了在詹金斯100%获得它,我添加了一个后续sed过滤器; 这是我的最新消息

version=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | egrep -v '^\[|Downloading:' | tr -d ' \n' | sed -E 's/\[.*\]//g')
Run Code Online (Sandbox Code Playgroud)

编辑

最后一点在这里..我发现tr仍在造成之类的东西/r/n0.3.2(又只能通过詹金斯运行时).切换到awk,问题已经消失!我的最终工作成果

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version \
| egrep -v '^\[|Downloading:' | sed 's/[^0-9\.]//g' | awk 1 ORS=''
Run Code Online (Sandbox Code Playgroud)


Jan*_*lak 5

我最近开发了Release Candidate Maven 插件来解决这个确切的问题,这样您就不必求助于任何 hacky shell 脚本并解析maven-help-plugin.

例如,要将 Maven 项目的版本打印到终端,请运行:

mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version
Run Code Online (Sandbox Code Playgroud)

其输出类似于maven-help-plugin

[INFO] Detected version: '1.0.0-SNAPSHOT'
1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

但是,您也可以指定任意输出格式(以便可以通过 CI 服务器(例如TeamCity)从日志中获取版本):

mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
   -DoutputTemplate="##teamcity[setParameter name='env.PROJECT_VERSION' value='{{ version }}']"
Run Code Online (Sandbox Code Playgroud)

结果是:

[INFO] Detected version: '1.0.0-SNAPSHOT'
##teamcity[setParameter name='env.PROJECT_VERSION' value='1.0.0-SNAPSHOT']
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

将输出保存到文件中(以便像Jenkins这样的 CI 服务器可以使用它):

mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
   -DoutputTemplate="PROJECT_VERSION={{ version }}" \
   -DoutputUri="file://\${project.basedir}/version.properties"
Run Code Online (Sandbox Code Playgroud)

生成的version.properties文件将如下所示:

PROJECT_VERSION=1.0.0-SNAPSHOT
Run Code Online (Sandbox Code Playgroud)

最重要的是,Release Candidate还允许您根据您在 POM 中定义的 API 版本来设置项目的版本(这可能是您在 CI 服务器上执行的操作)。

如果您想查看作为 Maven 生命周期一部分的 Release Candidate 的示例,请查看pom.xml我的另一个开源项目 - Build Monitor for Jenkins的示例。


小智 5

一个简单的行家解决方案

mvn -q -N org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
    -Dexec.executable='echo' \
    -Dexec.args='${project.version}'
Run Code Online (Sandbox Code Playgroud)

并为奖励积分解析了一部分版本

mvn -q -N org.codehaus.mojo:build-helper-maven-plugin:3.0.0:parse-version \
    org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
    -Dexec.executable='echo' \
    -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}'
Run Code Online (Sandbox Code Playgroud)