Auparavant, j’ai posé une question sur comment changer la version du projet Maven à partir de la ligne de commande , ce qui m’a amené à un nouveau problème.
Auparavant, je pouvais obtenir le numéro de version car celle-ci était stockée dans une propriété facile à grep et à analyser à partir de la ligne de commande (bash). Maintenant que l’élément pom.xml est utilisé pour cela, il n’est plus unique car toutes les dépendances et peut-être d’autres aussi l’utilisent. Je pense qu’il n’ya aucun moyen d’obtenir 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 ces informations de version. Je pensais écrire un plugin personnalisé maven pour récupérer différentes propriétés, mais je pensais que je demanderais d'abord ici.
Donc, existe-t-il un moyen simple d’obtenir la valeur de ${project.version}
en ligne de commande? Merci d'avance.
Solution
Merci pour l'aide. Je devais cd
dans le répertoire manuellement, mais cela peut être fait facilement. Dans mon script 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 } }'`
Ce qui me donne la version actuelle que je peux ensuite avancer. Grepping est peut-être plus simple, mais je pensais que je voudrais être aussi robuste que possible. Je suis donc satisfait de la première ligne qui commence par un numéro et essayez de le gérer comme un numéro de version.
# 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/"
}
Et j'utilise cela en appelant simplement
new_version=$(advance_version $version)
J'espère que ça aide quelqu'un.
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 l'invoquer 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
La solution de Tom avec le Exec Maven Plugin est bien meilleure, mais toujours plus compliquée qu'elle ne devrait l'être. Pour moi c'est aussi simple que:
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 '\['
À mon avis, la réponse la plus imparfaite est que j’ai du mal à utiliser des tas de grep pour pirater 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, car il s'agit de la méthode envisagée 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 d'espace de noms qui peuvent être présentes ou non dans le xml.
xmllint --xpath "//*[local-name()='project']/*[local-name()='version']/text()" pom.xml
Cela évitera d'avoir à rechercher des entrées de journal dans la sortie:
mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
J'ai fait des recherches et trouvé ce qui suit:
On a reproché à Maven de 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 de la CLI. (ref: https://youtu.be/1ILEw6Qca3U?t=372 )
Inspiré par l'assertion précédente, j'ai décidé de jeter un coup d'oeil sur le code source de maven ainsi que sur maven-help-plugin. Il semble qu'ils aient un peu corrigé le commutateur -q de maven (j'utilise la version 3.5.3), donc maintenant, si vous le transmettez, vous n'obtiendrez pas tous les trucs de journalisation ennuyants et non-sens qui empêchent d'utiliser maven. dans des 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 plug-in d'aide est transmis via le consignateur qui a été désactivé par le commutateur -q. (La dernière version disponible du plugin est la 3.1.0 publiée le 3 juin 2018)
Karl Heinz Marbaise ( https://github.com/khmarbaise ) l'a corrigé en ajoutant un paramètre facultatif lui permettant de l'appeler de la manière suivante:
mvn help:evaluate -Dexpression=project.version -q -DforceStdout
La description du commit est disponible sur: ( https://github.com/Apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014 )
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)"
Tant que vous avez Python 2.5 ou supérieur, cela devrait fonctionner. Si vous avez une version inférieure, installez python-lxml
et modifiez l'importation en lxml.etree. Cette méthode est rapide et ne nécessite pas le téléchargement de plugins supplémentaires. Cela fonctionne également sur les fichiers pom.xml malformés qui ne sont pas validés avec xmllint, comme ceux que je dois analyser. Testé sur Mac et Linux.
Je n'arrêtais pas de me heurter à certaines des autres réponses ici, alors voici 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 existe une autre solution (sans grep/sed) qui fonctionne bien pour moi. (EDIT: voir la réponse de rjrjr pour une solution beaucoup plus simple, sans aucun problème de fichier temporaire)
J'utilise le Exec Maven Plugin avec le binaire echo
. Contrairement au plug-in d'aide Maven, le plug-in Exec permet de rediriger la sortie vers un fichier, qui peut être utilisé pour contourner grep/sed, et permet même d'analyser des éléments étranges tels que des chaînes de version multilignes (avec CDATA block dans la version tag) 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 remarqué quelques lignes Downloaded:
parasites apparaissant dans la sortie qui rompaient mon affectation d'origine. Voici le filtre sur lequel je me suis installé; J'espère que ça aide!
version=$(mvn org.Apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | egrep -v '^\[|Downloading:' | tr -d ' \n')
MODIFIER
Pas tout à fait sûr de savoir pourquoi, mais lors de l’exécution de celui-ci par le biais d’un script post-génération dans Jenkins, la sortie sortait sous la forme [INFO]version
, par exemple. [INFO]0.3.2
.
J'ai vidé la sortie dans un fichier et l'ai passé dans mon premier filtre directement à partir de BASH, cela fonctionne très bien .., donc encore une fois, incertain de ce qui se passe dans le pays de Jenkins.
Pour l'obtenir à 100% dans 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
Une dernière note ici .. J'ai découvert que tr
était still, entraînant des choses comme /r/n0.3.2
(à nouveau uniquement lorsque vous exécutez via Jenkins). Passé à awk
et le problème est parti! Mon dernier 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=''
Pour rappel, il est possible de configurer la journalisation Simple SLF4J de Maven directement dans la ligne de commande pour ne générer que ce dont nous avons besoin en configurant:
org.slf4j.simpleLogger.defaultLogLevel=WARN
etorg.slf4j.simpleLogger.log.org.Apache.maven.plugins.help=INFO
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
Notez que ceci est un one-liner. MAVEN_OPTS
sont en cours de réécriture uniquement pour cette exécution mvn
particulière.
Une simple solution maven
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 analysés 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}'
J'ai récemment développé le plug-in Release Candidate Maven qui résout ce problème afin que vous n'ayez pas à recourir à des scripts de hacky Shell ni à l'analyse du résultat 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
ce qui donne une sortie similaire à maven-help-plugin
:
[INFO] Detected version: '1.0.0-SNAPSHOT'
1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Toutefois, vous pouvez également spécifier un format de sortie arbitraire (afin que la version puisse être extraite du journal par un serveur de CI, tel que TeamCity ):
mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
-DoutputTemplate="##teamcity[setParameter name='env.PROJECT_VERSION' value='{{ version }}']"
Ce qui résulte en:
[INFO] Detected version: '1.0.0-SNAPSHOT'
##teamcity[setParameter name='env.PROJECT_VERSION' value='1.0.0-SNAPSHOT']
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Pour enregistrer la sortie dans un fichier (afin qu'un serveur CI tel que Jenkins puisse l'utilise ):
mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
-DoutputTemplate="PROJECT_VERSION={{ version }}" \
-DoutputUri="file://\${project.basedir}/version.properties"
Le fichier version.properties
résultant ressemblera à ceci:
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 que vous feriez probablement sur votre serveur CI) en fonction de la version de l'API que vous avez définie. dans votre POM.
Si vous souhaitez voir un exemple d'utilisation de Release Candidate dans le cadre du cycle de vie de Maven, consultez le pom.xml
de mon autre projet open source - Build Monitor pour Jenkins .
Solution tout-en-un facile à comprendre qui génère la version du projet maven et supprime les sorties superflues des messages [INFO]
et Download
:
mvn -o org.Apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
Même chose, mais divisé en deux lignes:
mvn -o org.Apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
-Dexpression=project.version | grep -v '\['
Sorties: 4.3-SNAPSHOT
Donc, 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 combiner toutes les astuces.
J'ai trouvé le juste équilibre pour moi. Après mvn package
, le plugin maven-archiver crée target/maven-archiver/pom.properties
avec un contenu comme celui-ci.
version=0.0.1-SNAPSHOT
groupId=somegroup
artifactId=someArtifact
et j'utilise bash juste pour l'exécuter
. ./target/maven-archiver/pom.properties
puis
echo $version
0.0.1-SNAPSHOT
Bien sûr, l’exécution de ce fichier n’est pas sûre du tout, mais l’exécution peut facilement être convertie en script Perl ou bash pour lire et définir la variable d’environnement à partir de ce fichier.
Devrait être plus facile puisque ce bogue est corrigé dans maven-help-plugin 3.0.0: MPH-99 Evaluate n’a pas de sortie en mode silencieux .
Il y a aussi une option sans besoin Maven:
grep -oPm1 "(?<=<version>)[^<]+" "pom.xml"
C'est la solution la plus propre j'ai trouvé:
mvn org.Apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout
Cela fonctionne bien sur tous les systèmes d'exploitation. Pas besoin d'outils externes!
Le -q
supprime les messages verbeux. maven-help-plugin
version 3.2.0
(et supérieur) a l'option forceStdout
.
Soit vous avez mvn
vous donnez la réponse (comme le suggèrent la plupart des réponses), 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 n’aura de sens que si c’est literal, c’est-à-dire pas une propriété Maven. J'ai choisi cette approche quand même parce que:
mvn
est une façon de parler et je n'aime simplement pas filtrer sa sortie.mvn
est très lent comparé à lire le pom.xml
.<version/>
.mvn-version
est un script shell zsh
qui utilise xmlstarlet
pour lire le pom.xml
et imprimer la version du projet (le cas échéant) ou la version du projet parent (le cas échéant):
$ mvn-version .
1.0.0-SNAPSHOT
L'avantage est que way est plus rapide que d'exécuter 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.
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 $2 }' | awk -F '<' '{ print $1 }')
echo $VERSION