Быстрые пакеты и конфликтующие зависимости

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

Позвольте работать со следующим мнимым приложением SwiftApp, которое зависит от некоторых сторонних пакетов.

- SwiftApp - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected]

Из приведенного выше графика зависимости мы видим, что обе зависимости SwiftApp используют packageC, но с разными основными идентификаторами версии. Для большинства языковых экосистем это становится проблемой - основная ошибка в версии обычно означает, что были внесены изменения в код, которые не совместимы с предыдущей версией.

В зависимости от технических возможностей языка/компилятора/другого соответствующего компонента менеджер пакетов может быть реализован одним из следующих способов:

  1. Отказать в установке/компиляции (php, ruby, python?, другие?)
  2. Не волнует, пусть разработчик имеет дело с потенциальными ошибками компилятора (???)
  3. Установить пакет C для обоих пакетов независимо (Node.js, другие?)

Третий вариант может быть достигнут только при правильной поддержке языка или самого компилятора.

Может ли этот график зависимостей быть достигнут без разрыва в Swift?

Другими словами, технически ли возможно, чтобы packageA имел (и использовал) версию 1.0.0 пакета C, в то время как у пакета B будет версия 2.0.0?

Учитывая недавнее выражение о том, что Swift теперь является открытым исходным кодом и приходит с собственным менеджером пакетов, я думаю, что этот вопрос может быть очень ценным для будущих читателей, заинтересованных в разработке пакета Swift.

Ответ 1

Короткий ответ:

Теперь он вариант 2, не удалось построить.
Это дает ошибку: swift-build: The dependency graph could not be satisfied

Это потому, что SPM находится на очень ранней стадии разработки, очень ранней бета-версии.
Разрешение зависимостей

В настоящее время диспетчер пакетов Swift не предоставляет механизм автоматического разрешения конфликтов в дереве зависимостей. Однако это будет обеспечено в будущем.

Длительный ответ:

У Swift есть пространства имен. Это означает, что packageC в packageA будет иметь полное имя packageA.packageC. А в packageB это будет packageB.packageC

Из-за этого возможно, что одна и та же структура включена более одного раза.
SPM также выбирает зависимости с суффиксом версии (packageC-1.0.0). Поэтому я думаю, что должно быть возможно проверить, какая версия требуется в определенном пакете и получить ее.

Также Swift поддерживает динамические рамки. Это означает, что у вас может быть много версий одной и той же структуры, и они не должны конфликтовать друг с другом.

Как я вижу, в будущем у него будет возможность использовать вариант 3 (Install packageC для обоих пакетов независимо).

Резюме:

  • Теперь: Вариант 2 - не удалось построить.
  • Будущее: Вариант 3 - установите обе версии самостоятельно