Лучший способ обработки зависимостей между компонентами 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-repo
ismany-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 илиsplitsh
https://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 для потребителя. Вы смогите заменить / переименовать / рефактор через все модули / компоненты сразу.
- много-РЕПО трудно поддерживать, когда у вас есть большое количество компонентов.
Читайте также: