Как maven сортирует номера версий?

Maven, похоже, имеет возможность указывать ряд версий, таких как<version>[1.2.3,)</version> как maven выясняет, что является более новой или более старой версией, если не существует согласованной схемы управления версиями, которой следуют все пакеты с открытым исходным кодом. Например

JUnit4.10SLF4J1.7.2зимовать4.1.7.Finalвесна3.1.2.RELEASE

Как maven определяет, какая версия пакета старше или новее в maven? Что делать, если пакет использует буквы в качестве версий номера что-то вроде A, B, C или A2, A2, A4 ... и т. Д.

Должен ли быть стандартный официальный путь к пакетам версий в maven? Являются ли обычные пакеты с открытым исходным кодом, такие как spring и hibernate, игнорирующими это соглашение о версиях?

 ams22 окт. 2012 г., 14:44
@ Stefhen Я согласен, я думаю, что Maven путает зависимость времени сборки с совместимостью времени выполнения, им действительно нужен элемент <comptabileWith>, который представляет собой список авторов инфраструктуры, с которой они совместимы, но даже для которых все еще требуется стабильный способ сортировки номеров версий. Например, Spring Security 3.1.3 объявляет зависимость от Spring 3.0.7, потому что он работает как с 3.0.7, так и с 3.1.2, и если вы используете плагин Enforcer для принудительной конвергенции версий, то вы должны исключить Spring как зависимость безопасности Spring. Я не использую диапазоны версий, и я использую плагин принудительного применения для принудительной конвергенции.
 Stephen Connolly22 окт. 2012 г., 10:48
Не используйте диапазоны версий. Это была соблазнительная идея, которая на самом деле оказалась плохим планом. Что было бы намного лучше, было бы, если бы Maven позволял напрямую перечислять диапазон и указанную версию. Указанная версия будет тем, что было разрешено, и диапазон будет использоваться для предоставления подсказок о том, насколько далеко он может быть обновлен и / или какой диапазон диапазонов действителен во время выполнения. Диапазоны версий путают проблемы времени сборки с проблемами времени выполнения, и в настоящее время рекомендации с Maven просты:НЕ ИСПОЛЬЗУЙТЕ ВЕРСИИ

Ответы на вопрос(4)

который был написан непосредственно противComparableVersion класс от мавена.

package org.codehaus.mojo.buildhelper.versioning;

import org.apache.maven.artifact.versioning.ComparableVersion;
import org.junit.Assert;
import org.junit.Test;

public class TempTest {
    @Test
    public void testVersions() {
        Assert.assertTrue(new ComparableVersion("1.0-beta1-SNAPSHOT").compareTo(
                new ComparableVersion("1.0-beta1")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-beta1").compareTo(
                new ComparableVersion("1.0-beta2-SNAPSHOT")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-beta2-SNAPSHOT").compareTo(
                new ComparableVersion("1.0-rc1-SNAPSHOT")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-rc1-SNAPSHOT").compareTo(
                new ComparableVersion("1.0-rc1")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-rc1").compareTo(
                new ComparableVersion("1.0-SNAPSHOT")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-SNAPSHOT").compareTo(
                new ComparableVersion("1.0")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0").compareTo(
                new ComparableVersion("1")) == 0);
        Assert.assertTrue(new ComparableVersion("1.0").compareTo(
                new ComparableVersion("1.0-sp")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-sp").compareTo(
                new ComparableVersion("1.0-whatever")) < 0);
        Assert.assertTrue(new ComparableVersion("1.0-whatever").compareTo(
                new ComparableVersion("1.0.1")) < 0);
    }
}

В этом тесте утверждается, что следующие версии Maven рассматриваются как самые низкие:

1,0-бета1-СНАПШОТ1,0-бета11,0-бета2-СНАПШОТ1.0-rc1-СНАПШОТ1.0-rc11,0-СНАПШОТ1,0 и 1 (они равны)1,0-SP1,0-независимо1.0.1

cremtal / etc. просто неверно. Сравнение сделано вComparableVersion который содержит реализацию. Ктор позвонитparseVersion(...) который используетComparableVersion который хранится как экземпляр вDefaultArtifactVersion и он используется во времяcompareTo(..)

Есть такие части, какgetMajor..и т. д., но они работают неправильно. Это причина, почемубыть отмеченным как устаревший.

Информация Stehpen Collony верна для Maven 2, но больше не для Maven 3.

Maven использует согласованную систему для сравнения номеров версий для отдельных версий и диапазонов версий. Система теперь имеет большой смысл, как только вы поняли несколько ошибок.

Все сравнения теперь сделаныComparableVersion, который говорит:

смешивание-'(тире) и'.'(точечные) разделители,Переход между символами и цифрами также составляет разделитель:1.0alpha1 =>[1, 0, alpha, 1]неограниченное количество компонентов версии,Компоненты версии в тексте могут быть цифрами или строками,Строки проверяются на наличие известных классификаторов, а порядок классификаторов используется для упорядочения версий. Хорошо известными классификаторами (без учета регистра) являются:alpha или жеabeta или жеbmilestone или жеmrc или жеcrsnapshot(пустая строка) илиga или жеfinalspНеизвестные классификаторы рассматриваются после известных классификаторов в лексическом порядке (всегда без учета регистра),тире обычно предшествует определителю и всегда менее важна, чем то, что предшествует точке.

Это означает, что версии выходят в следующем порядке, который, я думаю, имеет смысл, кроме 1.0-SNAPSHOT прямо посередине:

1.0-beta1-SNAPSHOT1.0-beta11.0-beta2-SNAPSHOT1.0-rc1-SNAPSHOT1.0-rc11.0-SNAPSHOT1.01.0-sp1.0-whatever1.0.1

Главное, что я нашел во всем этом, это то, чтоsnapshot выходитпосле beta или жеrc, так что вы не можете иметь версию для разработки1.0-SNAPSHOTзатем отпустите1.0-beta1 или же1.0-rc1 и пусть Мэйвен поймет, что это позже.

Также обратите внимание, что1.0-beta-1 точно так же, как1.0beta1, а также1.0 точно так же, как1 или же1.0.0.

Диапазоны версий теперь работают (почти) так, как вы ожидаете. Например,[1.0-alpha-SNAPSHOT,1.0] найду1.0-beta1-SNAPSHOT, 1.0-beta1, 1.0-rc1-SNAPSHOT, 1.0-rc1, 1.0-SNAPSHOT или же1.0, предпочитая более поздние предметы более ранним. Это полностью поддерживаетсяmvn versions:resolve, M2Eclipse и так далее.

 Jelaby17 мая 2017 г., 19:50
Я отредактировал ответ, чтобы соответствовать. В Javadoc, на который вы ссылались, говорится, что SNAPSHOT предшествует «альфе», но реализация (в Grepcode) указывает, что это не так, и фактически после RC, как я сказал в своем ответе.
 khmarbaise13 мая 2017 г., 11:27
Данная ссылка на Maven версии 3.2.0 неверна, поскольку она была изменена в версии Maven 3.0.maven.apache.org/ref/3.0/maven-artifact/apidocs/org/apache/...
 Jelaby17 мая 2017 г., 19:46
Вы правы. Maven на самом деле использует DefaultArtifactVersion, который использовался для реализации compareTo () путем сравнения major / minor / incremental / qualifier, возвращаясь к квалификатору, если он не мог понять версию. Я не потратил время на то, чтобы разобраться, когда именно реализация DefaultArtifactVersion была изменена так, чтобы compareTo () использовала ComparableVersion, но похоже, что это было в версии 3.0, как вы сказали:grepcode.com/file/repo1.maven.org/maven2/org.apache.maven/...
Решение Вопроса

эта ссылкаMaven требует, чтобы версия имела вид:

<MajorVersion [> . <MinorVersion [> . <IncrementalVersion ] ] [> - <BuildNumber | Qualifier ]>

гдеMajorVersion, MinorVersion, IncrementalVersion а такжеНомер сборки все числовые испецификатор это строкаЕсли номер вашей версии не соответствует этому формату, тогда весь номер версии считается классификатором.

Эта ссылка объясняет, что вы можете «столкнуться с проблемами» (особенно с диапазонами версий Maven), если вы работаете с артефактами, которые не следуют этой схеме управления версиями. Глядя наMaven исходный код ссылка на статью весьма полезна.

Из приведенных вами примеров артефакты Hibernate и Spring, похоже, расходятся в использовании »." скорее, чем "-разделить классификатор.

Некоторые эксперименты с моей стороны показывают, чтоDefaultArtifactVersion проанализирует номера версий точно так, как описано выше. То есть приведенный пример Spring (3.1.2.RELEASE) будет интерпретироваться как:

Главный:0Незначительный:0Инкрементальный:0Классификатор:3.1.2.RELEASE

Что еще более важносравнение двух номеров версий (если используется Maven 3.0 или новее)много более гибкий. Номера версий разбиты на списки элементов (где либо. или же- отмечает границу между элементами, обратите внимание, что. имеет более высокий приоритет, чем-). Затем выполняется сравнение, принимая каждый элемент в срок и выполняя естественное сравнение порядка. следовательно3.1.2.RELEASE будет рассматриваться как меньше, чем3.1.3.RELEASE, Строки сравниваются тоже, следовательно3.1.2.RELEASD будет рассматриваться как меньше, чем3.1.2.RELEASE, Есть некоторые специальные строки, которые имеют специальные эквиваленты, например3.1.3.a.1 будет сортировать так же, как3.1.3.alpha.1

Однако покасравнение более гибок в новых версиях Maven. Границы диапазона версий по-прежнему оцениваются с использованием схемы Major: Minor: Incremental: Qualifier, поэтому, если вы используете диапазоны версий, гибкость менее полезна.

 Sparr03 дек. 2015 г., 22:28
Указывает ли maven, что только 0-9 являются «числовыми»? Как насчет пакетов, пронумерованных в базе 36?
 Duncan Jones22 окт. 2012 г., 15:52
@StephenConnolly Хорошие правки, спасибо. Всегда приятно, когда автор заходит :-)
 Nate R.04 июл. 2015 г., 18:42
Это был невероятно полезный ответ, особенно намек на то, что сравнение обрабатывается иначе, чем четырехкомпонентная схема синтаксического анализа, упомянутая выше. Чтобы сравнить строки версий Maven в приложении C, я написал вспомогательную библиотеку, которая может оказаться полезной для других:github.com/flandr/c-maven-utils
 userab16 июн. 2017 г., 10:17
из 3.1.2.RELEASE и 3.2.0.RELEASE, какая из них будет меньше?

Ваш ответ на вопрос