Лучший способ обработки зависимостей между компонентами PHP-фреймворка с помощью Git и Composer
фон
Я разрабатываю фреймворк на PHP. Я начал с создания каждого компонента отдельно, чтобы его можно было использовать независимо от структуры.
после создания четырех библиотек A, B, C и D:
A не имеет зависимостей
B и C требуются A
D требует A, B и C
теперь у меня есть некоторые проблемы при выпуске новой версии одной библиотеки, мне может потребоваться изменить зависимости других и выпустить новые версии для них. Например: новая версия A означает новую версию B, C и D.
I посмотрел, как другие фреймворки любят Symfony и что Laravel решить эту проблему. Я узнал, что они используют subtree особенность Git и replace функции композитора. Он работает следующим образом:
каждый компонент находится в репозитории только для чтения со своим
composer.jsonкаждый компонент может требовать других компонентов, но не
replaceних.репозиторий framework использует
subtreesвключить все компоненты. Так что не нужноrequireих использование composer. Но так и должно быть!--5--> все их зависимости (так как это больше не обрабатывается Compser).в рамках
replaceвсе его компоненты.
Я также заметил, что
репозиторий компонентов содержит только исходный код (без модульных тестов !)
Laravel сделал компонент контрактов просто хранить все interafces всех компонентов и каждый компонент требует, что.
вопросы
правильно ли мое объяснение того, как Laravel и Symfony решили проблему ?
действительно ли мне нужно удалять тесты из репозиториев компонентов и помещать их в фреймворк?
если да, то как может кто-то, кто хочет просто использовать один компонент уверен, что он проходит тесты независимо от того, что вся структура проходит тесты wole ?
должен ли я убедиться, что все зависимости компонентов совместимы и требуют их вручную в framework
composer.json?в чем смысл наличия компонента для интерфейсов ? Это не может быть использовано автономно в любом случае !
есть ли лучший способ решить эту проблему ?
1 ответов
теперь у меня есть некоторые проблемы при выпуске новой версии одной библиотеки, мне, возможно, придется изменить зависимости других и выпустить новые версии для них. Например: новая версия A означает новую версию B, C и D.
- у вас есть подход с несколькими РЕПО.
- редактирование a => новая версия A => версия bump необходима в B, C и D.
Я думаю, что самое главное, чтобы уйти от использования dev-master и версионизируйте свои компоненты правильно, как только они стабилизируются и будут готовы выйти из фазы разработки. Затем вы можете использовать операторы диапазона композиторов (caret ^ & tilde ~) для автоматического обновления до последней версии в некоторых крупных.ряд минорной версии. Это очень помогает и берет утомительную ручную работу по обновлению версии из ваших рук.
- правильно ли мое объяснение того, как Laravel и Symfony решили проблему ?
- это неправильно. Базовая концепция разработки, публикация и потребление пакетов работают по-разному, то, что вы описали.
- они используют монолитный стиль разработки РЕПО. Это единый репозиторий, который содержит код для группы пакетов. Противоположность
mono-repoismany-repoподход. Альтернативыgit submodules. - все модули / пакеты фреймворка и ядро фреймворка / ядро находятся в одном хранилище! За что Laravel это https://github.com/laravel/framework/tree/5.4/src/Illuminate
- каждая папка модуля / пакета содержит
composer.jsonи сама структура содержитcomposer.json - это позволяет "разделить" папки модуля на автономные репозитории только для чтения. Использование пользовательского помощника git, например
git subsplit publishкак Laravel использует https://github.com/laravel/framework/blob/636020a96a082b80fa87eed07d45c74fa7a4ba70/build/illuminate-split-full.sh илиsplitshhttps://github.com/splitsh/lite, как Symfony использует - развитие происходит в основном РЕПО.
- наконец, с точки зрения пользователя/потребителя (в композиторе.json вашего CMS / app независимо), вам просто нужен модуль / пакет из источника "автономный репозиторий только для чтения". Это много-РЕПО, потому что ваше приложение зависит от многих репозиториев.
когда вы обновляете зависимость с помощью Composer, Composer заменяет ваши пакеты более новой версией.
- действительно ли мне нужно удалять тесты из репозиториев компонентов и помещать их в фреймворк?
нет. Вы также можете оставить тесты в /moduleA/tests папка и настройка сборщика модульных тестов.
- если да, как кто-то, кто хочет просто использовать один компонент, может быть уверен, что он проходит тесты независимо от того, что вся структура проходит тесты wole ?
две вещи. Испытуемый:
- (a) компонент, который идеально независимо тестируемый и
- (b) структура, которая потребляет много компонентов и тестирует функциональные возможности, которые полагаются на функции из нескольких компонентов (например, ядро/ядро). Вы может также разделить ядро, как только оно стабилизируется и тестируется независимо. (например, компонента D)
- должен ли я убедиться, что все зависимости компонентов совместимы и требуют их вручную в framework composer.в JSON ?
перспектива разработчика monorepo: Разработчик / сопровождающий фреймворка может выпустить только новую версию, когда все модульные тесты всех компонентов и все модульные тесты рамки сами проходят, верно? Затем он может начать разделение поддерева и автоматически версионизировать новые компоненты.
перспектива разработчика приложений:
Да. Как пользователь компонентов monorep вы просто потребляя зависимости standaloen (от чтения РЕПО). Это означает, что вы должны поддерживать версии компонентов, которые вам требуются в вашем composer.json вручную или автоматически.
- в чем смысл наличия компонента для Интерфейсы ? Это не может быть использовано автономно в любом случае !
хороший вопрос!
возможно, разработчики хотят делать все по-другому и"держать вещи отсортированными"
или у них на уме плохая идея оптимизации:
можно утверждать, что интерфейсы - это только контракты на разработку. Когда все компоненты написаны против интерфейсов, вы можете просто вытащить заткните дальше их, после испытывать и перед делать отпуск продукции. Другими словами: вы можете оставить репозиторий интерфейсов и запустите удаление интерфейса, когда вы выпускаете для производства.
выход из репозитория интерфейсов приведет к фатальным ошибкам" интерфейсы X не найдены". Затем вы запускаете " optimizer pass "над остальными классами и удаляете все строки" implements interfaceX". Меньше файлов. Меньше кода для разбора. Меньше ИО. И теперь я, вероятно, буду убит в разделе комментариев, предложив это :) и нет, Laravel или Symfony этого не делают.
- есть ли лучший способ решить эту проблему?
Я бы предложил сделать следующее: для проекта с 5 компонентов, перейти монорепо.
в целом там не так много вариантов, чтобы решить эту проблему:
- git подмодули
- mono-repo
- multi-repo
каждый из подходов имеет pro и con.:
- обновление подмодулей git a.к. a. git версия натыкаясь и обновление подмодуля приводит к Git безумие, потому что он будет постоянно нарушен. а безумие Гита ведет на темную сторону. :)
- Mono-repo легко поддерживать и легко публиковать. Это дает вам легкое обслуживание для разработчика и multi-repo для потребителя. Вы смогите заменить / переименовать / рефактор через все модули / компоненты сразу.
- много-РЕПО трудно поддерживать, когда у вас есть большое количество компонентов.
Читайте также: