Используется ли семантическое управление версиями для совместимости с исходными или двоичными файлами?

Этот вопрос относится к любому языку, который написан на одном языке ( "источник" ), например. C или Java, и распределяется в другом ( "двоичном" ), например. машинный код или байт-код Java, используя динамическое связывание.


Предположим, что пользователь уже использует версию A моей библиотеки. Я выпускаю новую версию B.

Если он может скомпилировать свой код без изменений против B и правильно запустить с B, изменение от A до B называется совместимым с исходным кодом.

Если он может скомпилировать свой код против A и правильно запустить с B, изменение от A до B называется совместимым с двоичными файлами. Эта ситуация является общей при использовании транзитивных графиков зависимостей без загрузки изолированных модулей (например, OSGI). X скомпилирован против некоторых версий Y и Z, а Y был скомпилирован против другой определенной версии Z. Во время выполнения Y-вызовы в Z могут быть неправильными и могут выходить из строя.

Возможно, что изменения совместимы с исходным кодом, но двоичные несовместимы. Также возможно, что изменения несовместимы с источником и совместимы с бинарными.

Какую совместимость я использую для семантического управления версиями? Использую ли я исходную совместимость для различения основных и второстепенных/патч-обновлений, или я использую бинарную совместимость для различения обновлений основных и второстепенных/патчей?


Моя текущая мотивация - это библиотека Scala. Scala двоичная совместимость может быть очень сложной для анализа и требует хорошего понимания деталей компилятора. Совместимость источников и двоичная несовместимость очень распространены.

Это не какой-то причудливый краевой случай; эта проблема может появиться на большинстве компилируемых динамически связанных языков.

Ответ 1

Несколько месяцев спустя, я думаю, у меня есть хороший вывод.

Семантическое управление версиями должно учитывать и то, и другое "наиболее измененное".

  • Разрыв исходной компиляции - это несовместимое изменение для пользователей библиотеки.
  • Нарушение исполнения во время выполнения - это несовместимое изменение для пользователей библиотеки.

Если совместимость с исходным кодом или бинарной совместимостью, она должна - в соответствии с семантическим версированием - стать новой основной версией.

В моем случае для Scala бинарную совместимость иногда бывает довольно сложно определить. Существует несколько различных инструментов JAR API, например. JDiff.

Ответ 2

Чтобы ответить на этот вопрос, притворитесь, что вы являетесь пользователем, который также не является программистом. С их точки зрения, исходный код бесполезен; они не понимают этого, и это им бессмысленно. С другой стороны, у них есть файл, содержащий объектный код, и они знают, что ему нужно куда-то идти. Для них важна только версия двоичного кода.

Это, однако, не конец истории. Ваш вопрос неявно содержит ядро ​​гораздо лучшего ответа. Существует два вида совместимости, поэтому должны быть две последовательности версий. Сам вопрос содержит дисфункциональное предположение, а именно, что должна быть только одна последовательность версий.

Теперь, если у вас есть две последовательности версий и, кроме того, создать автоматический путь в конце пользователя для преобразования версий, совместимых с версиями, в объектно-совместимые версии, вы облегчили свою проблему. Чтобы сделать это, необходимо явно указать, как вы выполняете преобразование, например такие, как версия компилятора, версия интерпретатора, аргументы командной строки и т.д.

Короче говоря, лучший ответ на поставленный вопрос заключается в том, что он применяется к обоим им.