Comment obtenir la version du projet Maven en ligne de commande bash

précédent j'ai émis une question sur comment changer la lésion du projet Maven de la ligne de commande qui m'a mené à un nouveau numéro.

auparavant, j'étais capable d'obtenir le numéro de version puisque la version était stockée comme une propriété qui était facile à grep et à parse à partir de la ligne de commande (bash). Maintenant que le pom.l'élément xml est utilisé pour cela, il n'est plus unique puisque toutes les dépendances et peut-être d'autres l'utilisent aussi. Je pense qu'il n'y a aucun moyen de obtenez le numéro de version actuel avec un script bash sans outils externes pour analyser xml ou une commande sed très sensible au contexte.

la solution la plus propre à mon avis serait que Maven distribue cette information de version. Je pensais écrire un plugin maven personnalisé pour récupérer différentes propriétés mais j'ai pensé que je demanderais ici en premier.

donc, y a-t-il un moyen facile d'obtenir la valeur de ${project.version} ligne de commande? Merci à l'avance.

Solution

Merci pour l'aide. J'ai du cd au répertoire manuellement mais cela peut être fait facilement. Dans mon scénario bash j'ai

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

qui me donne la version actuelle que je peux alors avancer. Gropping pourrait être plus simple, mais je pensais que je voudrais aussi robuste que possible, donc je suis satisfait de la première ligne qui commence par un nombre et essayer pour gérer cela comme un numéro de version.

# Advances the last number of the given version string by one.
function advance_version () {
    local v=
    # 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/"
}

et je l'utilise en appelant simplement

new_version=$(advance_version $version)

J'espère que ça aidera quelqu'un.

137
demandé sur Community 2010-08-23 10:53:31

21 réponses

le Maven Help Plugin propose déjà quelque chose pour cela:

  • help:evaluate évalue les expressions Maven données par l'utilisateur en mode interactif.

Voici comment vous l'invoqueriez sur la ligne de commande pour obtenir le ${project.version} :

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
    -Dexpression=project.version
166
répondu Pascal Thivent 2010-08-23 07:06:01

de Tom solution avec le Exec Plugin Maven est beaucoup mieux, mais toujours plus compliqué qu'il doit être. Pour moi, c'est aussi simple que:

set -o errexit

MVN_VERSION=$(mvn -q \
    -Dexec.executable=echo \
    -Dexec.args='${project.version}' \
    --non-recursive \
    exec:exec)
130
répondu rjrjr 2018-09-05 16:13:52
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
45
répondu user1712021 2013-07-08 13:14:58

la réponse la plus importante est assez vulgaire à mon avis, vous devez utiliser un tas de grep pour hacker la sortie de la console maven. Pourquoi ne pas utiliser le bon outil pour le travail? L'utilisation de la syntaxe xpath est la meilleure approche pour extraire le numéro de version, puisqu'il s'agit de la méthode prévue pour accéder à une structure de données XML. L'expression ci-dessous traverse le pom en utilisant le "nom local" des éléments, c'est-à-dire en ignorant les déclarations namespace qui peuvent ou non être présentes dans le xml.

xmllint --xpath "//*[local-name()='project']/*[local-name()='version']/text()" pom.xml
28
répondu lukeforehand 2016-05-08 15:52:18

on évitera ainsi d'avoir à Gropper les entrées log de la sortie:

mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
22
répondu Jose Alban 2017-09-29 15:10:02
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)"

aussi longtemps Que vous avez python 2.5 ou plus, cela devrait fonctionner. Si vous avez une version inférieure, installez python-lxml et changez l'importation en lxml.programme etree. Cette méthode est rapide et ne nécessite pas le téléchargement de plugins supplémentaires. Il fonctionne également sur pom malformé.les fichiers xml qui ne sont pas validés avec xmllint, comme ceux que je dois analyser. Testé sur Mac et Linux.

11
répondu pdr 2015-03-20 23:43:13

j'ai continué à courir dans des cas secondaires en utilisant certaines des autres réponses ici, donc voici encore une autre alternative.

version=$(printf 'VER\t${project.version}' | mvn help:evaluate | grep '^VER' | cut -f2)
8
répondu slow 2016-07-06 12:21:52

si cela ne vous dérange pas d'écrire la version dans un fichier temporaire, il y a une autre solution (sans grep/sed) qui fonctionne bien pour moi. ( MODIFIER : voir rjrjr la réponse de pour une solution beaucoup plus simple, sans aucun fichier temporaire tracas)

j'utilise le Exec Plugin Maven avec la echo binaire. Contrairement au Plugin Maven Help, le Plugin Exec permet une redirection de sortie dans un fichier, qui peut être utilisé pour contourner grep / sed, et rend même possible de parser des choses étranges comme des chaînes de version multilignes (avec bloc CDATA dans la balise de version), au moins dans une certaine mesure.

#!/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"
7
répondu Tom 2014-10-23 06:13:35

j'ai fait quelques recherches et trouvé ce qui suit:

  1. Maven a été blâmé pour ne pas être facilement intégrable dans les scripts d'exploitation du système car il ne suit pas certaines bonnes pratiques concernant les outils CLI. (réf: https://youtu.be/1ILEw6Qca3U?t=372 )

  2. inspiré de l'assertion précédente, j'ai décidé de jeter un oeil sur le code source de maven ainsi que sur maven-aide-plugin. Il semble qu'ils aient corrigé un peu le commutateur maven's-q (j'utilise la version 3.5.3), donc maintenant si vous le passez, vous n'obtiendrez pas tous les trucs ennuyeux de journalisation non-sens qui empêchent maven d'être utilisé dans les scripts automatisés. Vous devriez donc pouvoir utiliser quelque chose comme ceci:

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

    le problème est que cette commande n'imprime rien car par défaut le plugin help sort par l'intermédiaire de l'enregistreur qui a été réduit au silence par le commutateur-Q. (la dernière version disponible du plugin est 3.1.0 sorti le 3 juin 2018)

  3. Karl Heinz Marbaise ( https://github.com/khmarbaise ) fixé en ajoutant un paramètre optionnel qui vous permet de l'appeler de la façon suivante:

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

    La validation de la description est disponible à: ( https://github.com/apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014 )

7
répondu montoyaedu 2018-06-20 09:23:10

j'ai remarqué quelques fausses lignes Downloaded: venant dans la sortie qui cassaient ma tâche originale. Voici le filtre sur lequel je me suis installé; j'espère qu'il vous aidera!

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

MODIFIER

N'est pas sûr à 100% de la raison, mais lors de l'exécution d'un script de post-construction dans Jenkins, la sortie était [INFO]version , par exemple [INFO]0.3.2 .

j'ai jeté la sortie dans un fichier et je l'ai lancé grâce à mon premier filtre directement à partir de BASH, il fonctionne très bien.. Je ne sais pas ce qui se passe à Jenkins land.

pour obtenir 100% à Jenkins, j'ai ajouté un filtre de suivi sed ; voici mon dernier

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

MODIFIER

un dernier mot ici.. J'ai découvert que tr était encore résultant en des choses comme /r/n0.3.2 (encore une fois seulement en cours d'exécution via Jenkins). Passé à awk , et le problème a disparu! Mon dernier de travail résultat

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=''
5
répondu quickshiftin 2013-10-28 22:11:38

juste pour mémoire, il est possible de configurer la simple connexion SLF4J de Maven directement dans la ligne de commande pour ne sortir que ce dont nous avons besoin en configurant:

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

comme documenté à 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

en conséquence, on peut exécuter simplement tail -1 et obtenir:

$ 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

noter qu'il s'agit d'une doublure unique. MAVEN_OPTS sont en cours de réécriture seulement pour cette exécution mvn particulier.

5
répondu Stepan Vavra 2016-08-09 17:14:57

Un simple maven seule solution

mvn -q -N org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
    -Dexec.executable='echo' \
    -Dexec.args='${project.version}'

et pour les points bonus parsed partie d'une 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}'
4
répondu Jakob O. 2017-07-13 09:12:03

la solution tout-en-un facile à comprendre qui produit la version du projet maven, et supprime les sorties étrangères de [INFO] et Download messages:

mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['

même chose, mais divisé sur deux lignes:

mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
      -Dexpression=project.version | grep -v '\['

sorties: 4.3-SNAPSHOT

ainsi, en utilisant votre project.version dans un script bash simple:

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

les autres solutions sur cette page ne semblaient pas se combiner tous les trucs en un.

3
répondu Peter Dietz 2014-08-30 05:18:41

j'ai récemment développé le plugin Release Candidate Maven plugin qui résout ce problème exact afin que vous n'ayez pas à recourir à des scripts shell hacky et à analyser la sortie du maven-help-plugin .

par exemple, pour imprimer la version de votre projet Maven sur un terminal, exécutez:

mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version

qui donne une sortie similaire à maven-help-plugin :

[INFO] Detected version: '1.0.0-SNAPSHOT'
1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

cependant, vous pouvez également spécifier un format de sortie arbitraire (afin que la version puisse être récupérée à partir du log par un serveur CI tel que TeamCity ):

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

qui se traduit par:

[INFO] Detected version: '1.0.0-SNAPSHOT'
##teamcity[setParameter name='env.PROJECT_VERSION' value='1.0.0-SNAPSHOT']
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

pour sauvegarder la sortie dans un fichier (de sorte qu'un serveur CI tel que Jenkins pourrait l'utiliser ):

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

le fichier version.properties qui en résulte ressemblera à ce qui suit:

PROJECT_VERSION=1.0.0-SNAPSHOT

en plus de tout ce qui précède, Release Candidate vous permet également de définir la version de votre projet (ce qui est quelque chose que vous feriez probablement sur votre serveur CI) basé sur la version API que vous avez défini dans votre POM.

si vous souhaitez voir un exemple de candidat de libération utilisé comme faisant partie du cycle de vie de Maven, jetez un coup d'oeil sur le pom.xml de mon autre projet open-source - Build Monitor for Jenkins .

3
répondu Jan Molak 2017-09-29 18:45:00

devrait être plus facile puisque ce bug est corrigé dans maven-help-plugin 3.0.0: MPH-99 Evaluate n'a pas de sortie en mode calme .

2
répondu mturra 2017-09-29 18:47:12

le plugin Exec fonctionne sans aucun parsing de sortie car la sortie peut être redirigée dans le fichier et injectée de nouveau dans l'environnement de travail via le plugin EnvInject:

enter image description here

1
répondu Ondřej Kmoch 2016-03-09 08:37:00

cela a fonctionné pour moi, hors ligne et sans dépendre de mvn:

VERSION=$(grep --max-count=1 '<version>' <your_path>/pom.xml | awk -F '>' '{ print  }' | awk -F '<' '{ print  }')
echo $VERSION
0
répondu George 2015-11-24 09:19:30

soit vous avez mvn vous donnez la réponse (comme la plupart des réponses le suggèrent), soit vous extrayez la réponse du pom.xml . Le seul inconvénient de la seconde approche est que vous pouvez très facilement extraire la valeur de la balise <version/> , mais elle ne sera significative que si elle est littérale , c'est-à-dire, pas une propriété Maven. J'ai choisi cette approche de toute façon parce que:

  • mvn est une façon de parler et je n'aime tout simplement pas le filtrage de sa sortie.
  • Démarrer mvn est très lent par rapport à la lecture du pom.xml .
  • j'utilise toujours des valeurs littérales dans <version/> .

mvn-version est un script shell zsh qui utilise xmlstarlet pour lire pom.xml et imprimer la version du projet (s'il existe) ou la version du projet parent (s'il existe):

$ mvn-version .
1.0.0-SNAPSHOT

l'avantage est qu'il est chemin plus rapide que l'exécution 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

la différence sur ma machine est supérieure à deux ordres de grandeur.

0
répondu Enrico M. Crisostomo 2016-11-28 23:15:49
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'

Je ne fais qu'ajouter une petite amélioration du filtre sed que j'ai récemment implémentée pour extraire project.version de la sortie maven.

-2
répondu websigni 2013-06-19 13:20:42
VERSION=$(head -50 pom.xml | awk -F'>' '/SNAPSHOT/ {print }' | awk -F'<' '{print }')

C'est ce que j'ai utilisé pour obtenir le numéro de version, je pensais qu'il y aurait eu une meilleure façon maven de le faire

-2
répondu Tristik 2015-07-07 21:43:16

Maven pied de page est assez standard:

[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] ------------------------------------------------------------------------

donc vous pouvez utiliser le code suivant:

> version=$(mvn help:evaluate -Dexpression=project.version | tail -8 | head -1)
> echo $version
-4
répondu ursa 2014-05-21 17:34:12