Лучший способ обработки зависимостей между компонентами 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 всех компонентов и каждый компонент требует, что.

вопросы

  1. правильно ли мое объяснение того, как Laravel и Symfony решили проблему ?

  2. действительно ли мне нужно удалять тесты из репозиториев компонентов и помещать их в фреймворк?

  3. если да, то как может кто-то, кто хочет просто использовать один компонент уверен, что он проходит тесты независимо от того, что вся структура проходит тесты wole ?

  4. должен ли я убедиться, что все зависимости компонентов совместимы и требуют их вручную в framework composer.json ?

  5. в чем смысл наличия компонента для интерфейсов ? Это не может быть использовано автономно в любом случае !

  6. есть ли лучший способ решить эту проблему ?

П. С.: вот ссылки на A, B, C и D

1 ответов


теперь у меня есть некоторые проблемы при выпуске новой версии одной библиотеки, мне, возможно, придется изменить зависимости других и выпустить новые версии для них. Например: новая версия A означает новую версию B, C и D.

  • у вас есть подход с несколькими РЕПО.
  • редактирование a => новая версия A => версия bump необходима в B, C и D.

Я думаю, что самое главное, чтобы уйти от использования dev-master и версионизируйте свои компоненты правильно, как только они стабилизируются и будут готовы выйти из фазы разработки. Затем вы можете использовать операторы диапазона композиторов (caret ^ & tilde ~) для автоматического обновления до последней версии в некоторых крупных.ряд минорной версии. Это очень помогает и берет утомительную ручную работу по обновлению версии из ваших рук.

  1. правильно ли мое объяснение того, как Laravel и Symfony решили проблему ?
  • это неправильно. Базовая концепция разработки, публикация и потребление пакетов работают по-разному, то, что вы описали.
  • они используют монолитный стиль разработки РЕПО. Это единый репозиторий, который содержит код для группы пакетов. Противоположность mono-repo is many-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 заменяет ваши пакеты более новой версией.

  1. действительно ли мне нужно удалять тесты из репозиториев компонентов и помещать их в фреймворк?

нет. Вы также можете оставить тесты в /moduleA/tests папка и настройка сборщика модульных тестов.

  1. если да, как кто-то, кто хочет просто использовать один компонент, может быть уверен, что он проходит тесты независимо от того, что вся структура проходит тесты wole ?

две вещи. Испытуемый:

  • (a) компонент, который идеально независимо тестируемый и
  • (b) структура, которая потребляет много компонентов и тестирует функциональные возможности, которые полагаются на функции из нескольких компонентов (например, ядро/ядро). Вы может также разделить ядро, как только оно стабилизируется и тестируется независимо. (например, компонента D)
  1. должен ли я убедиться, что все зависимости компонентов совместимы и требуют их вручную в framework composer.в JSON ?

перспектива разработчика monorepo: Разработчик / сопровождающий фреймворка может выпустить только новую версию, когда все модульные тесты всех компонентов и все модульные тесты рамки сами проходят, верно? Затем он может начать разделение поддерева и автоматически версионизировать новые компоненты.

перспектива разработчика приложений: Да. Как пользователь компонентов monorep вы просто потребляя зависимости standaloen (от чтения РЕПО). Это означает, что вы должны поддерживать версии компонентов, которые вам требуются в вашем composer.json вручную или автоматически.

  1. в чем смысл наличия компонента для Интерфейсы ? Это не может быть использовано автономно в любом случае !

хороший вопрос!

  • возможно, разработчики хотят делать все по-другому и"держать вещи отсортированными"

  • или у них на уме плохая идея оптимизации:

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

выход из репозитория интерфейсов приведет к фатальным ошибкам" интерфейсы X не найдены". Затем вы запускаете " optimizer pass "над остальными классами и удаляете все строки" implements interfaceX". Меньше файлов. Меньше кода для разбора. Меньше ИО. И теперь я, вероятно, буду убит в разделе комментариев, предложив это :) и нет, Laravel или Symfony этого не делают.

  1. есть ли лучший способ решить эту проблему?

Я бы предложил сделать следующее: для проекта с 5 компонентов, перейти монорепо.

в целом там не так много вариантов, чтобы решить эту проблему:

  1. git подмодули
  2. mono-repo
  3. multi-repo

каждый из подходов имеет pro и con.:

  • обновление подмодулей git a.к. a. git версия натыкаясь и обновление подмодуля приводит к Git безумие, потому что он будет постоянно нарушен. а безумие Гита ведет на темную сторону. :)
  • Mono-repo легко поддерживать и легко публиковать. Это дает вам легкое обслуживание для разработчика и multi-repo для потребителя. Вы смогите заменить / переименовать / рефактор через все модули / компоненты сразу.
  • много-РЕПО трудно поддерживать, когда у вас есть большое количество компонентов.

Читайте также: