Должен ли я увеличить основную версию при обновлении зависимостей

Я знаю, что подобные вопросы задавались раньше, но я специально включил maven тег на этом вопросе по причине. Сценарий:

  • Проект P имеет две зависимости: D1-1.2.3 и D2-2.0.0.
  • D1-1.2.3 имеет D2-1.0.0 в качестве зависимости
  • Класс C в D1 использует (но не предоставляет) класс из D2, в котором произошли критические изменения с версии 1.0.0 на 2.0.0.
  • P использует C

Модель зависимости maven предписывает, что, поскольку P в pom.xml явно указывает зависимость D2, будет использоваться версия из pom. Это приводит к разрыву P с ошибкой компоновки из-за несовместимого изменения транзитивной зависимости.

semver FAQ утверждает, что это совместимое изменение. В нем говорится «поскольку это не влияет на общедоступный API», но в описанном мной сценарии каждое обновление зависимости неявно несет в себе риск поломки потребителей из-за ошибок компоновки.

Должен ли D1 увеличить основную версию? Является ли этот фрагмент спецификации semver просто непригодным для проектов maven из-за его модели зависимости?


person EvenLisle    schedule 10.08.2018    source источник
comment
Вопрос в том, нужно ли изменить ваш класс C (его интерфейс) на основе транзитивного изменения. Если вы можете сохранить его. Чем это не критическое изменение, потому что ваш API стабилен, если вам нужно изменить свой интерфейс, это будет критическое изменение... и приведет к серьезному изменению версии... Кроме того, я бы явно назвал изменение версии в вашем журнале изменений. ..   -  person khmarbaise    schedule 10.08.2018


Ответы (1)


Совместимость изменения или нет, в данном случае полностью зависит от того, как его использует потребитель API, и это не входит в обязанности разработчика API.

Что касается разработчиков D1, общедоступный API остался без изменений, и, ИМО, будет правильно заявить, что это не критическое изменение.

Если приложение, использующее D1, также напрямую использует D2, потому что это зависимость в области компиляции, то ответственность за это полностью лежит на потребителе. Как? В любом случае потребитель может исключить транзитивную зависимость и заменить ее другой версией, а несколько потребителей по-разному управляют транзитивными зависимостями.

Как вы сказали, большая часть этого является результатом того, как зависимости работают в Maven или Java, но разумно ограничить ответственность разработчиков API общедоступным API.

person ernest_k    schedule 10.08.2018
comment
В любом случае потребитель может исключить транзитивную зависимость. Но ведь это не поможет, не так ли? Метод, представленный в общедоступном API D1, использует (и был скомпилирован) раннюю версию D2. Причина ошибки связывания в первую очередь заключается в том, что P имеет более новую версию (которая изменилась несовместимо) в своем pom, а не наоборот - person EvenLisle; 10.08.2018
comment
@EvenLisle, тогда проблема более проста, чем управление версиями ... подробности реализации просочились в общедоступный API. Если это принято / приемлемо, то я согласен с вами, что более новая версия будет уместной. Но это неуправляемо. - person ernest_k; 10.08.2018
comment
Что касается разработчиков D1, публичный API остался без изменений — я и согласен, и не согласен. Я согласен, что они не могут знать, произойдет ли нечто подобное. Но я имею в виду, что в случае с maven мы никогда не можем предполагать, что обновление зависимости с критическим изменением не нарушит общедоступный API. - person EvenLisle; 10.08.2018
comment
@EvenLisle В вашем вопросе не упоминалось, что компоненты транзитивной зависимости представлены в общедоступном API. Смотрите мой предыдущий комментарий. - person ernest_k; 10.08.2018
comment
В вашем вопросе не упоминалось, что компоненты из транзитивной зависимости представлены в общедоступном API - да, это так: класс C в D1 использует (но не предоставляет) класс из D2, в котором произошли критические изменения с версии 1.0.0 на 2.0.0. Несмотря на то, что он не подвергается воздействию (т.е. возвращается потребителю), его использование по-прежнему ломает потребителей D1 - person EvenLisle; 10.08.2018
comment
Я создал задачу, предлагающую изменить формулировку, чтобы спецификация semver не делала предположений о моделях зависимости: github.com/semver/semver/issues/456 - person EvenLisle; 10.08.2018
comment
Если он не предоставляет класс в общедоступном API, то я все равно утверждаю, что это не критическое изменение. Если вам не нужно рефакторить/перекомпилировать код, то это не критическое изменение. - person ernest_k; 10.08.2018
comment
Я допускаю, что это, вероятно, выходит за рамки самого semver. Принят и проголосовал за ваш ответ - person EvenLisle; 10.08.2018
comment
С каких пор манифесты, включенные в ваш пакет, не являются частью общедоступных API, содержащихся в этом пакете? Одно дело прикрепить метку версии к API, и совсем другое — поместить ее на пакет, содержащий этот API и другой контент. Внесите изменения в этот пакет, который ломает мою сборку, вам лучше увеличить номер его основной версии, иначе я напишу об ошибке против вас и, возможно, перестану использовать ваши продукты. Мне нужно рассчитывать на то, что я смогу автоматически исправлять ошибки, не тратя часы на изучение/исправление сбоев в сборке. - person jwdonahue; 18.08.2018
comment
Когда среда обеспечивает параллельное развертывание API/пакетов, удовлетворяется большинство временных зависимостей. В средах, в которых нет параллельных развертываний, при обновлении пакетов необходимо учитывать временные зависимости. - person jwdonahue; 18.08.2018
comment
@jwdonahue, у тебя интересное мнение. Включаете ли вы собственное дерево зависимостей в файлы манифеста? А как насчет затемненных банок? И понимаете ли вы, что является ли это фактически критическим изменением в данном случае, зависит исключительно от того, как переходная зависимость используется пользователем библиотеки? - person ernest_k; 18.08.2018
comment
@ernest_k, я не хочу знать, что такое заштрихованная банка. Я стараюсь избегать Java, потому что мой опыт работы с ней показал, что она продвигает нездоровые методы. Когда вы производите продукт, который содержит алмазную точечную зависимость, а параллельное развертывание/исполнение нескольких версий одних и тех же компонентов не является нормой, вы производите бомбы замедленного действия. Если я неправильно понял постановку задачи OP, последняя версия P теперь зависит от двух разных версий D2, где раньше требовалась одна. Если java или maven не обеспечивают параллельное развертывание, это изменение в P является критическим изменением. - person jwdonahue; 18.08.2018
comment
@jwdonahue, вероятно, вы неправильно понимаете, как работают транзитивные зависимости maven. Но дело в том, что разработчик API не менял публичный API. Клиент решил использовать транзитивную зависимость напрямую, поэтому он несет ответственность за решение проблемы, вызванной обновлением. Ваше мнение о Java, мягко говоря, интригует. Вы использовали maven раньше? - person ernest_k; 18.08.2018
comment
Я в основном говорю, что утверждение, что X зависит от Y, является слабым, если полное закрытие дерева зависимостей недоступно, и потребитель не может легко прибегнуть к параллельному развертыванию и выполнению. Под слабым я подразумеваю неуверенного и совершенно ненадежного. Отсюда и эксплуатируемая сеть, которую мы имеем сегодня. - person jwdonahue; 18.08.2018
comment
@ernest_k, я думаю, что, вероятно, я неправильно понимаю эту конкретную проблему, учитывая мои слепые пятна как в java, так и в maven. - person jwdonahue; 18.08.2018
comment
Пересматриваю это, потому что у OP есть активный поток в проекте semver на github. - person jwdonahue; 20.09.2018
comment
@jwdonahue Может быть, вы, ребята, поделитесь своим мнением/решением в комментариях или ответах на этот вопрос (всякий раз, когда вы решите эту проблему) - person ernest_k; 20.09.2018
comment
@ernest_k, хороший план. Я собирался изменить один из своих ответов в ветке проблемы и опубликовать его, но теперь я думаю, что подожду решения в этой ветке. - person jwdonahue; 20.09.2018