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.
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
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)
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
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
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
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.
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)
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"
j'ai fait quelques recherches et trouvé ce qui suit:
-
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 )
-
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)
-
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 )
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=''
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.
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}'
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.
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 .
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 .
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:
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
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 dupom.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.
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.
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
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