Poprzednio zadałem pytanie, jak zmienić wersję projektu Maven z wiersza poleceń, co doprowadziło mnie do nowego problemu.
Wcześniej byłem w stanie uzyskać numer wersji, ponieważ wersja była przechowywana jako właściwość, którą łatwo było grepować i analizować z linii poleceń (bash). Teraz, gdy użyto do tego elementu pom.xml, nie jest on już unikalny, ponieważ wszystkie zależności i być może niektórzy inni też tego używają. Myślę, że nie ma sposobu, aby uzyskać bieżący numer wersji za pomocą skryptu bash bez zewnętrznych narzędzi do parsowania xml lub jakiegoś bardzo kontekstowego polecenia sed.
Moim zdaniem najczystszym rozwiązaniem byłoby przekazanie przez Maven tej informacji o wersji. Myślałem o napisaniu niestandardowej wtyczki maven do wyszukiwania różnych właściwości, ale pomyślałem, że najpierw zapytam tutaj.
Czy jest więc jakiś prosty sposób na uzyskanie wartości w ${project.version}
wierszu poleceń? Z góry dziękuję.
Rozwiązanie
Dziękuję za pomoc. Musiałem cd
ręcznie przejść do katalogu, ale można to łatwo zrobić. W moim skrypcie bash mam
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 } }'`
Co daje mi aktualną wersję, którą mogę później ulepszyć. Grepping może być prostszy, ale pomyślałem, że chciałbym być tak solidny, jak to możliwe, więc jestem zadowolony z pierwszej linii, która zaczyna się od cyfry i staram się traktować to jako numer wersji.
# 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/"
}
I używam tego po prostu dzwoniąc
new_version=$(advance_version $version)
Mam nadzieję, że to komuś pomoże.
źródło
grep -e '^[[:digit:]]'
Odpowiedzi:
Maven Pomoc Plugin jest w jakiś sposób już proponuje coś dla tego:
Oto jak wywołałbyś go w wierszu poleceń, aby uzyskać
${project.version}
:źródło
[INFO]
wiadomości? Nie znalazłem przełącznika na maven. W przeciwnym razie dodam skrypty z wiersza poleceń, aby przeanalizować numer wersji.mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version|grep -Ev '(^\[|Download\w+:)'
printf 'VERSION=${project.version}\n0\n' | mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate | grep '^VERSION'
mvn help:evaluate -Dexpression=project.version -q -DforceStdout
. Aby uchwycić ją w zmiennej w bashu użytkuversion=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
Rozwiązanie Toma z wtyczką Exec Maven jest znacznie lepsze, ale wciąż bardziej skomplikowane, niż musi być. Dla mnie jest to tak proste, jak:
źródło
mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive exec:exec
-Dexec.args='${project.groupId}:${project.artifactId}:${project.version}'
.[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (default-cli) on project audit-events-processor-parent: Command execution failed. Cannot run program "maven" (in directory "/tmp"): error=2, No such file or directory
wzruszając ramionami jeszcze jedna odpowiedź, która nie działa dla mnie, no cóżset -o errexit
Przeprowadziłem badania i znalazłem następujące informacje:
Winę ponosi Maven, ponieważ integracja z narzędziami DevOps nie jest łatwa, ponieważ nie przestrzega dobrych praktyk dotyczących narzędzi CLI. (zob .: https://youtu.be/1ILEw6Qca3U?t=372 )
Zainspirowany poprzednim stwierdzeniem postanowiłem przyjrzeć się kodowi źródłowemu maven, a także wtyczce maven-help-plugin. Wygląda na to, że naprawili trochę przełącznik -q maven (używam wersji 3.5.3), więc teraz, jeśli go przejdziesz, nie dostaniesz wszystkich irytujących, nie sensownych logowań, które uniemożliwiają użycie maven w ramach automatycznych skryptów. Powinieneś być w stanie użyć czegoś takiego:
Problem polega na tym, że to polecenie nic nie drukuje, ponieważ domyślnie wtyczka pomocy wyświetla dane wyjściowe przez program rejestrujący, który został wyciszony przez przełącznik -q. (najnowsza dostępna wersja wtyczki to 3.1.0 wydana 3 czerwca 2018 r.)
Karl Heinz Marbaise ( https://github.com/khmarbaise ) naprawił go, dodając opcjonalny parametr, który pozwala na wywołanie go w następujący sposób:
Opis zatwierdzenia jest dostępny na stronie: ( https://github.com/apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014 )
źródło
-q
przełącznika, drukuje on poprawnie wersję (pomiędzy wierszami dziennika). Jakieś pomysły?-q
przełącznikiem.-q -DforceStdout
były puste, nawet upewniając się, że wersja 3.1.0 wtyczki była używana z pluginManagement); skonfigurowałem owijarkę maven z wersją 3.5.4 maven i działało to poprawnieźródło
2> /dev/null
ponieważ w przeciwnym razie możesz dostaćPicked up _JAVA_OPTIONS:
| findstr /v "["
.Najlepsza odpowiedź to dość śmieci, moim zdaniem, musisz użyć kilku grepów, aby zhakować wyjście konsoli maven. Dlaczego nie skorzystać z odpowiedniego narzędzia do pracy? Najlepszą metodą uzyskania numeru wersji jest użycie składni xpath, ponieważ jest to zamierzona metoda dostępu do struktury danych XML. Wyrażenie poniżej przemierza pom za pomocą „lokalnej nazwy” elementów, innymi słowy ignorując deklaracje przestrzeni nazw, które mogą, ale nie muszą być obecne w xml.
źródło
mvn
jest właściwym podejściem, aexec
wtyczka faktycznie działa dobrze, ale wszystkie rozwiązania mvn muszą zostać rozwiązane, a ja próbuję uruchomić bootstrap kompilacji, w której rozwiązywanie zależności nie będzie działać, więc zamierzam zastąpić toexec
podejście tym rozwiązaniem. Na szczęście nie muszę się martwić wersjami odziedziczonymi po rodzicach.${revision}
na przykład właściwością . Nr ref. maven.apache.org/maven-ci-friendly.htmlPozwoli to uniknąć konieczności odczytywania wpisów dziennika z danych wyjściowych:
źródło
To najczystsze rozwiązanie, jakie znalazłem:
Zalety:
Uwaga:
maven-help-plugin
wersja3.2.0
(i wyżej) maforceStdout
opcję. Możesz zastąpić3.2.0
powyższą komendę nowszą wersją z listy dostępnych wersji mvn-help-plugin od artifactory, jeśli jest dostępna.-q
tłumi zbyt obszerne wiadomości ([INFO]
,[WARN]
etc.)Jeśli chcesz, aby pobrać
groupId
iartifactId
jak dobrze, sprawdź tę odpowiedź .źródło
Tak długo, jak masz Python 2.5 lub nowszy, to powinno działać. Jeśli masz niższą wersję, zainstaluj
python-lxml
i zmień import na lxml.etree. Ta metoda jest szybka i nie wymaga pobierania żadnych dodatkowych wtyczek. Działa również na zniekształconych plikach pom.xml, które nie sprawdzają poprawności za pomocą xmllint, takich jak te, które muszę przeanalizować. Testowane na komputerach Mac i Linux.źródło
Ciągle spotykałem się z przypadkami pobocznymi, używając niektórych innych odpowiedzi tutaj, więc oto jeszcze jedna alternatywa.
źródło
printf 'VER\t${project.version}' | mvn help:evaluate 2> /dev/null | grep '^VER' | cut -f2
Jeśli nie masz nic przeciwko zapisaniu wersji do pliku tymczasowego, istnieje inne rozwiązanie (bez grep / sed), które działa dobrze dla mnie. ( EDYCJA : patrz odpowiedź rjrjr na znacznie prostsze rozwiązanie bez żadnych tymczasowych problemów z plikami)
Używam wtyczki Exec Maven wraz z
echo
plikiem binarnym. W przeciwieństwie do wtyczki Maven Help, wtyczka Exec umożliwia przekierowanie wyjścia do pliku, którego można użyć do obejścia grep / sed, a nawet umożliwia analizowanie dziwnych rzeczy, takich jak ciągi wersji wielowierszowej (z blokiem CDATA w znaczniku wersji), przynajmniej do pewnego stopnia.źródło
Dla przypomnienia możliwe jest skonfigurowanie prostego logowania SLF4J Maven bezpośrednio w wierszu poleceń, aby wyświetlać tylko to, czego potrzebujemy, konfigurując:
org.slf4j.simpleLogger.defaultLogLevel=WARN
iorg.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO
zgodnie z dokumentacją na stronie http://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html
W rezultacie można uruchomić po prostu
tail -1
i uzyskać:Pamiętaj, że jest to jedna linijka.
MAVEN_OPTS
są przepisywane tylko dla tego konkretnegomvn
wykonania.źródło
Zauważyłem,
Downloaded:
że na wyjściu pojawiły się fałszywe linie, które łamały moje pierwotne zadanie. Oto filtr, na którym się zdecydowałem; mam nadzieję, że to pomoże!EDYTOWAĆ
Nie jestem w 100% pewien, dlaczego, ale kiedy uruchomiłem to za pomocą skryptu po kompilacji w Jenkins, wyjście wychodziło jak
[INFO]version
np[INFO]0.3.2
.Zrzuciłem dane wyjściowe do pliku i przepuściłem je przez mój pierwszy filtr bezpośrednio z BASH, działa dobrze .., więc znów nie jestem pewien, co się dzieje w krainie Jenkins.
Aby uzyskać go w 100% w Jenkins, dodałem
sed
filtr uzupełniający ; oto moje najnowszeEDYTOWAĆ
I ostatnia uwaga tutaj .. I okazało się,
tr
był nadal skutkuje rzeczy jak/r/n0.3.2
(ponownie tylko wtedy, gdy uruchomiony poprzez Jenkins). Przełączono naawk
i problem zniknął! Mój końcowy wynik pracyźródło
Proste rozwiązanie tylko dla maven
A dla punktów bonusowych przeanalizowano część wersji
źródło
Niedawno opracowałem wtyczkę Release Candidate Maven, która rozwiązuje dokładnie ten problem, dzięki czemu nie musisz uciekać się do żadnych zhackowanych skryptów powłoki i analizowania danych wyjściowych
maven-help-plugin
.Na przykład, aby wydrukować wersję projektu Maven na terminalu, uruchom:
co daje wynik podobny do
maven-help-plugin
:Można jednak również określić dowolny format wyjściowy (aby wersja mogła zostać pobrana z dziennika przez serwer CI, taki jak TeamCity ):
Co skutkuje w:
Aby zapisać dane wyjściowe w pliku (aby serwer CI taki jak Jenkins mógł z niego skorzystać ):
Wynikowy
version.properties
plik będzie wyglądał następująco:Oprócz wszystkich powyższych, Release Candidate pozwala również ustawić wersję projektu (co prawdopodobnie zrobiłbyś na serwerze CI) na podstawie wersji API zdefiniowanej w POM.
Jeśli chcesz zobaczyć przykład użycia kandydata do wydania jako części cyklu życia Maven, spójrz na
pom.xml
mój inny projekt open source - Build Monitor dla Jenkinsa .źródło
Jest też jedna opcja bez potrzeby Maven:
źródło
grep -oPm2 "(?<=<version>)[^<]+" pom.xml | sed -n 2p
Aby uzyskać trzecie wystąpienie użyj:grep -oPm3 "(?<=<version>)[^<]+" pom.xml | sed -n 3p
i tak dalejŁatwe do zrozumienia, kompleksowe rozwiązanie, które wyświetla wersję projektu maven i eliminuje zbędne dane wyjściowe
[INFO]
iDownload
komunikaty:To samo, ale podzielone na dwie linie:
Wyjścia:
4.3-SNAPSHOT
Używając twojego
project.version
w prostym skrypcie bash:Inne rozwiązania na tej stronie nie łączyły wszystkich sztuczek w jedną.
źródło
Powinno być łatwiejsze, ponieważ ten błąd został naprawiony w maven-help-plugin 3.0.0: MPH-99 Evaluate nie ma danych wyjściowych w trybie cichym .
źródło
Jest to zdecydowanie najłatwiejsze rozwiązanie do wycinania i wklejania bash:
odbija się echem
źródło
Znalazłem dla siebie odpowiednią równowagę. Po tym, jak
mvn package
maven-archiver tworzy wtyczkętarget/maven-archiver/pom.properties
z zawartością taką jak tai używam bash tylko po to, aby go wykonać
następnie
Oczywiście wykonanie tego pliku wcale nie jest bezpieczne, ale wykonanie można łatwo przekonwertować na skrypt perl lub bash, aby odczytać i ustawić zmienną środowiskową z tego pliku.
źródło
Działa to dla mnie offline i bez zależności od mvn:
źródło
Wtyczka Exec działa bez analizowania danych wyjściowych, ponieważ dane wyjściowe można przekierować do pliku i wstrzyknąć z powrotem do środowiska zadania za pomocą wtyczki EnvInject:
źródło
Bazując na pytaniu, używam tego skryptu poniżej, aby automatycznie zwiększyć numer wersji we wszystkich rodzicach / submodułach maven:
źródło
Albo
mvn
dałeś ci odpowiedź (jak sugeruje większość odpowiedzi), albo wyciągasz odpowiedź zpom.xml
. Jedyną wadą drugiego podejścia jest to, że można bardzo łatwo wyodrębnić wartość<version/>
znacznika, ale będzie on sensowny tylko wtedy, gdy będzie dosłowny , to znaczy nie będzie własnością Maven. Mimo to wybrałem to podejście, ponieważ:mvn
jest sposobem na gadatliwe i po prostu nie lubię filtrować jego wyników.mvn
jest bardzo wolne w porównaniu do czytaniapom.xml
.<version/>
.mvn-version
tozsh
skrypt powłoki, który używaxmlstarlet
do odczytupom.xml
i wydruku wersji projektu (jeśli istnieje) lub wersji projektu nadrzędnego (jeśli istnieje):Zaletą jest to, że jest znacznie szybszy niż bieganie
mvn
:Różnica na mojej maszynie jest większa niż dwa rzędy wielkości.
źródło
Potrzebuję dokładnie tego wymagania podczas mojej pracy Travis, ale z wieloma wartościami. Zaczynam od tego rozwiązania, ale dzwonienie wielokrotne jest bardzo wolne (potrzebuję 5 wyrażeń).
Napisałem prostą wtyczkę maven, aby wyodrębnić wartości pom.xml do pliku .sh.
https://github.com/famaridon/ci-tools-maven-plugin
Wyprodukuje to:
teraz możesz po prostu źródło pliku
Baw się dobrze.
źródło
Używam jednowierszowego w mojej powłoce unix ...
Możesz ukryć tę linię w skrypcie powłoki lub jako alias.
źródło
to jest edycja z góry
Przetestowałem to na cmdline działa dobrze
grep "" pom.xml | głowa -n 1 | sed -e "s / version // g" | sed -e "s / \ s * [<> /] * // g”
jest inną wersją tego samego. Muszę uzyskać numer wersji w Jenkins CI w k8s bez zainstalowanego mvn, więc jest to najbardziej pomocne
Dziękuje wszystkim.
źródło
Właśnie dodałem małe
sed
ulepszenie filtra, które niedawno wdrożyłem, aby wyodrębnićproject.version
z wyjścia maven.źródło
Właśnie tak otrzymywałem numer wersji, pomyślałem, że byłby lepszy sposób na zrobienie tego
źródło