Быстрые пакеты и конфликтующие зависимости
Одна из самых сложных задач каждого менеджера пакетов, которую я видел, - это обработка противоречивых зависимостей.
Позвольте работать со следующим мнимым приложением SwiftApp, которое зависит от некоторых сторонних пакетов.
- SwiftApp - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected]
Из приведенного выше графика зависимости мы видим, что обе зависимости SwiftApp используют packageC, но с разными основными идентификаторами версии. Для большинства языковых экосистем это становится проблемой - основная ошибка в версии обычно означает, что были внесены изменения в код, которые не совместимы с предыдущей версией.
В зависимости от технических возможностей языка/компилятора/другого соответствующего компонента менеджер пакетов может быть реализован одним из следующих способов:
- Отказать в установке/компиляции (php, ruby, python?, другие?)
- Не волнует, пусть разработчик имеет дело с потенциальными ошибками компилятора (???)
- Установить пакет 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 - установите обе версии самостоятельно