之前我发布了一个关于如何从命令行更改Maven项目版本的问题,这导致我遇到了一个新问题。

以前我能够获得版本号,因为版本存储为一个属性,很容易从命令行(bash)进行grep和解析。现在pom.xml <version>元素用于此,它不再是唯一的,因为所有依赖项(也许其他一些依赖项也使用它)。我认为,如果没有用于解析XML的外部工具或一些非常能感知上下文的sed命令,就无法用bash脚本获得当前版本号。

在我看来,最干净的解决方案是Maven发布这个版本信息。我想写一个自定义的maven插件检索不同的属性,但我想我应该先问这里。

那么,是否有任何简单的方法来获取${project的值。版本}到命令行?

解决方案

我必须手动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)

当前回答

Exec插件不需要任何输出解析,因为输出可以重定向到文件中,并通过EnvInject插件注入到作业环境中:

其他回答

我找到了适合自己的平衡。在mvn包后,maven-archiver插件创建了target/maven-archiver/pom。属性具有如下内容

version=0.0.1-SNAPSHOT
groupId=somegroup
artifactId=someArtifact

我使用bash来执行它

. ./target/maven-archiver/pom.properties

then

echo $version
0.0.1-SNAPSHOT

当然,执行这个文件一点也不安全,但是可以很容易地将执行转换为perl或bash脚本,以便从该文件读取和设置环境变量。

易于理解的一体化解决方案,输出maven项目版本,并抑制来自[INFO]和下载消息的无关输出:

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快照

所以,使用你的项目。版本在一个简单的bash脚本:

projectVersion=`mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['`
cd "target/"$projectVersion"-build"

本页上的其他解决方案似乎并没有把所有的技巧结合在一起。

我注意到一些虚假的下载:行来的输出打破了我原来的任务。这是我选定的滤镜;希望能有所帮助!

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

EDIT

不是100%确定为什么,但是当在Jenkins中运行后构建脚本时,输出是[INFO]版本,例如[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')

EDIT

这里还有最后一点。我发现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=''

为什么不使用正确的工具呢?使用xpath语法是检索版本号的最佳方法,因为它是访问XML数据结构的预期方法。下面的表达式使用元素的“本地名称”遍历pom,换句话说,忽略xml中可能存在也可能不存在的名称空间声明。

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

最快捷的方式,让你只看到文字,而没有任何装饰

mvn help:evaluate -q -DforceStdout -D"expression=project.version"