之前我在how to change Maven project vesion from command line上发了一个问题,引出了一个新问题。
以前我能够获得版本号,因为版本存储为易于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 } }'`
这给了我当前版本,然后我可以推进。 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/"
}
我通过简单地打电话来使用它
new_version=$(advance_version $version)
希望这有助于某人。
Maven Help Plugin在某种程度上已经为此提出了一些建议:
help:evaluate
评估用户在交互模式下给出的Maven表达式。
以下是如何在命令行上调用它来获取${project.version}
:
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
-Dexpression=project.version
我注意到输出中出现了一些伪造的Downloaded:
线,它们破坏了我原来的任务。这是我已经确定的过滤器;希望能帮助到你!
version=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | egrep -v '^\[|Downloading:' | tr -d ' \n')
编辑
不是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')
编辑
最后一点注意到这里..我发现tr
仍然会产生像/r/n0.3.2
这样的东西(再次只能通过Jenkins运行)。切换到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=''
只是为了记录,可以直接在命令行中配置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
因此,人们可以简单地运行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
执行。
一个简单的maven唯一解决方案
mvn -q -N org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
-Dexec.executable='echo' \
-Dexec.args='${project.version}'
并且奖励积分解析了版本的一部分
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}'
我最近开发了Release Candidate Maven插件,它可以解决这个问题,这样你就不必使用任何hacky shell脚本并解析maven-help-plugin
的输出。
例如,要将Maven项目的版本打印到终端,请运行:
mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version
它给出类似于maven-help-plugin
的输出:
[INFO] Detected version: '1.0.0-SNAPSHOT'
1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
但是,您还可以指定任意输出格式(以便可以通过CI服务器(如TeamCity)从日志中获取版本):
mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
-DoutputTemplate="##teamcity[setParameter name='env.PROJECT_VERSION' value='{{ version }}']"
结果如下:
[INFO] Detected version: '1.0.0-SNAPSHOT'
##teamcity[setParameter name='env.PROJECT_VERSION' value='1.0.0-SNAPSHOT']
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
要将输出保存到文件(以便像Jenkins这样的CI服务器可以use it):
mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
-DoutputTemplate="PROJECT_VERSION={{ version }}" \
-DoutputUri="file://\${project.basedir}/version.properties"
生成的version.properties
文件如下所示:
PROJECT_VERSION=1.0.0-SNAPSHOT
除此之外,Release Candidate还允许您根据您在POM中定义的API版本设置项目的版本(这是您可能在CI服务器上执行的操作)。
如果您希望看到Release Candidate的一个例子被用作Maven生命周期的一部分,请查看我的其他开源项目的pom.xml
- Build Monitor for Jenkins。
易于理解的一体化解决方案,输出maven项目版本,并抑制来自[INFO]
和Download
消息的无关输出:
mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
同样的事情,但分为两行:
mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
-Dexpression=project.version | grep -v '\['
产出:4.3-SNAPSHOT
所以,在一个简单的bash脚本中使用你的project.version
:
projectVersion=`mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['`
cd "target/"$projectVersion"-build"
此页面上的其他解决方案似乎并未将所有技巧合二为一。
应该更容易,因为在maven-help-plugin 3.0.0中修复了这个bug:MPH-99 Evaluate has no output in quiet mode。
我找到了适合自己的平衡点。在mvn package
maven-archiver插件创建target/maven-archiver/pom.properties
之后,这样的内容
version=0.0.1-SNAPSHOT
groupId=somegroup
artifactId=someArtifact
我正在使用bash来执行它
. ./target/maven-archiver/pom.properties
然后
echo $version
0.0.1-SNAPSHOT
当然,执行此文件根本不安全,但可以轻松地将执行转换为perl或bash脚本,以从该文件中读取和设置环境变量。
还有一个选项,不需要Maven:
grep -oPm1 "(?<=<version>)[^<]+" "pom.xml"
这是我发现的最干净的解决方案:
mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout
它适用于所有操作系统。无需任何外部工具!
-q
抑制了冗长的信息。 maven-help-plugin
版本3.2.0
(及以上)有forceStdout
选项。
汤姆与Exec Maven Plugin的解决方案要好得多,但仍然比它需要的更复杂。对我来说,它很简单:
MVN_VERSION=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.version}' \
--non-recursive \
exec:exec)
这对我有用,离线并且不依赖于maven:
VERSION=$(grep --max-count=1 '<version>' <your_path>/pom.xml | awk -F '>' '{ print $2 }' | awk -F '<' '{ print $1 }')
echo $VERSION
要么你有mvn
给你答案(大多数答案建议),或者你从pom.xml
提取答案。第二种方法的唯一缺点是你可以很容易地提取<version/>
标签的值,但只有它是文字的,即不是Maven属性才有意义。无论如何我选择了这种方法,因为:
mvn
是详细的方式,我只是不喜欢过滤它的输出。mvn
相比,开始pom.xml
非常慢。<version/>
中使用文字值。mvn-version
是一个zsh
shell脚本,使用xmlstarlet
读取pom.xml
并打印项目的版本(如果存在)或父项目的版本(如果存在):
$ mvn-version .
1.0.0-SNAPSHOT
优点是它比运行mvn
更快:
$ time mvn-version .
1.1.0-SNAPSHOT
mvn-version . 0.01s user 0.01s system 75% cpu 0.019 total
$ time mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
> -Dexpression=project.version
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate 4.17s user 0.21s system 240% cpu 1.823 total
我机器上的差异大于两个数量级。
我在我的unix shell中使用了一个单行程...
cat pom.xml | grep“”|头-n 1 | sed -e“s / version // g”| sed -e“s / \ s * [<> /] * // g”
您可以在shell脚本中或作为别名隐藏此行。
这是上面的编辑
cat pom.xml | grep“”|头-n 1 | sed -e“s / version // g”| sed -e“s / \ s * [<> /] * // g”
我在cmdline上测试它的效果很好
erp“”你好hed-n 1 se-is“c / version // d” “”“”“”“”“”“”“”
是另一个版本。我需要在没有安装mvn的情况下在k8s中获取Jenkins CI中的版本号,所以这是最有帮助的
谢谢大家。
mvn help:evaluate -Dexpression=project.version | sed -e 1h -e '2,3{H;g}' -e '/\[INFO\] BUILD SUCCESS/ q' -e '1,2d' -e '{N;D}' | sed -e '1q'
我只是添加了我最近实施的小型sed
滤波器改进,以从maven输出中提取project.version
。
VERSION=$(head -50 pom.xml | awk -F'>' '/SNAPSHOT/ {print $2}' | awk -F'<' '{print $1}')
这是我以前得到的版本号,认为有更好的maven方式这样做
Maven页脚很标准:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.609s
[INFO] Finished at: Wed May 21 18:02:38 MSK 2014
[INFO] Final Memory: 17M/736M
[INFO] ------------------------------------------------------------------------
所以你可以使用以下代码:
> version=$(mvn help:evaluate -Dexpression=project.version | tail -8 | head -1)
> echo $version
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
我一直在做一些研究,发现以下内容:
mvn help:evaluate -Dexpression=project.version -q
问题是此命令不打印任何内容,因为默认情况下,帮助插件通过-q开关静音的记录器输出。 (该插件的最新可用版本是在2018年6月3日发布的3.1.0)mvn help:evaluate -Dexpression=project.version -q -DforceStdout
提交说明位于:(https://github.com/apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014)在我看来,最重要的答案是非常垃圾,你必须使用一堆grep来破解maven控制台输出。为什么不使用合适的工具呢?使用xpath语法是检索版本号的最佳方法,因为它是访问XML数据结构的预期方法。下面的表达式是使用元素的“本地名称”遍历pom,换句话说,忽略可能存在或不存在于xml中的名称空间声明。
xmllint --xpath "//*[local-name()='project']/*[local-name()='version']/text()" pom.xml
这样可以避免从输出中删除日志条目:
mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
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。这种方法很快,不需要下载任何额外的插件。它也适用于不使用xmllint验证的格式错误的pom.xml文件,就像我需要解析的那样。在Mac和Linux上测试过。
当我在这里使用其他一些答案时,我一直遇到不好的情况,所以这里还有另一种选择。
version=$(printf 'VER\t${project.version}' | mvn help:evaluate | grep '^VER' | cut -f2)
如果你不介意将版本写入临时文件,那么另一种解决方案(没有grep / sed)对我来说效果很好。 (编辑:请参阅rjrjr's answer以获得更简单的解决方案,无任何临时文件麻烦)
我使用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"