之前我发布了一个关于如何从命令行更改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)

当前回答

我最近开发了发布候选Maven插件来解决这个确切的问题,这样您就不必求助于任何hack shell脚本并解析Maven -help-插件的输出。

例如,要将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] ------------------------------------------------------------------------

将输出保存到一个文件中(这样CI服务器(如Jenkins)就可以使用它):

mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
   -DoutputTemplate="PROJECT_VERSION={{ version }}" \
   -DoutputUri="file://\${project.basedir}/version.properties"

最终的版本。属性文件将如下所示:

PROJECT_VERSION=1.0.0-SNAPSHOT

在上述所有功能之上,Release Candidate还允许您基于在POM中定义的API版本设置项目的版本(这可能是您在CI服务器上所做的事情)。

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

其他回答

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

org.slf4j.simpleLogger.defaultLogLevel =警告和 org.slf4j.simpleLogger.log.org.apache.maven.plugins.help =信息

详见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插件来解决这个确切的问题,这样您就不必求助于任何hack shell脚本并解析Maven -help-插件的输出。

例如,要将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] ------------------------------------------------------------------------

将输出保存到一个文件中(这样CI服务器(如Jenkins)就可以使用它):

mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
   -DoutputTemplate="PROJECT_VERSION={{ version }}" \
   -DoutputUri="file://\${project.basedir}/version.properties"

最终的版本。属性文件将如下所示:

PROJECT_VERSION=1.0.0-SNAPSHOT

在上述所有功能之上,Release Candidate还允许您基于在POM中定义的API版本设置项目的版本(这可能是您在CI服务器上所做的事情)。

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

一种替代方法是使用yq (https://github.com/kislyuk/yq)进行解析,如下所示:

cat pom.xml | xq -r '.project.version'

注意,可执行文件是xq而不是yq

为了获得xq,像pip安装yq那样安装yq

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

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

一个简单的专家解决方案

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}'