Skip to content

Instantly share code, notes, and snippets.

@devanych
Last active September 16, 2021 15:50
Show Gist options
  • Save devanych/9475d7d3b0e2507b564c8d174a3c0fa7 to your computer and use it in GitHub Desktop.
Save devanych/9475d7d3b0e2507b564c8d174a3c0fa7 to your computer and use it in GitHub Desktop.
Варианты расположения дефолтных конфигурационных файлов для yiisoft/config

Варианты расположения дефолтных конфигурационных файлов

Issue: yiisoft/config#72

В текущей реализации все дефолтные конфигурационные файлы, которые расположены в вендоре в соответствующих пакетах, копируются в приложение автоматически при установке приложения (composer <create-project|install|update>). Таким образом все конфигурации пакетов контролирует пользователь.

Предлагается не копировать конфигурации в приложение, а оставлять их в вендоре. Если же пользователю нужно будет переопределить конфигурацию пакета, то он скопирует файлы из вендора (используя консольную команду) в приложение и переопределит. Команда будет выглядеть следующим образом:

// Копировать конфигурацию одного пакета.
composer yii-config-copy yiisoft/aliases

// Копировать конфигурации нескольких пакетов.
composer yii-config-copy yiisoft/aliases yiisoft/view

Текущая реализация

Плюсы:

  • Не нужно самостоятельно копировать файлы, они уже скопированы и разложены по папкам с названиями пакетов.
  • Полный контроль над всеми файлами конфигураций, если при обновлении пакетов, конфигурация новой версии пакета изменилась, то будут предложены действия:
    • "Игнорировать, ничего не делать."
    • "Заменить локальную версию файла новой версией."
    • "Скопировать новую версию файла с постфиксом .dist."
    • "Вывести diff-файлов в консоль."

Минусы:

  • Большое количество файлов конфигураций в приложении.
  • Все дефолтные файлы конфигураций хранятся в приложении и визуально не понятно, что в приложении сконфигурировано кастомно (для этого нужно вызвать composer config-diff).

Предлагаемая реализация

Плюсы:

  • Действия для измененных файлов при обновлении пакета, будут предложены только для переопределенных конфигураций, а дефолтные файлы в вендоре будут перезаписываться автоматически.
  • Все дефолтные конфигурационные файлы находятся в вендоре, а в приложении только переопределенные. Визуально мало файлов. Проще ориентироваться. Легко понять, что именно сконфигурировано в приложении.

Минусы:

  • Меньше контроля над файлами.
    • Дефолтные конфигурации в вендоре будут перезаписаны при обновлении пакета и могут возникать конфликты с кодом приложения.
    • Пользователь может не использовать консольную команду для копирования файлов из вендора, а скопировать их вручную, таким образом служебная информация о конфигурациях в dist.lock и merge_plan.php не обновится.

Альтернативная реализация

PR: yiisoft/config#81

Глобальные зменения:

  • Все дефолтные конфигурационные файлы находятся в вендоре, а в приложении только переопределенные.
  • Добавлена команда yii-config-copy для копирования конфигурационных файлов из вендора в приложение.
  • Добавлена команда yii-config-rebuild для обновления плана слияния.
  • Удален параметр output-directory, осталась только source-directory для всех пакетов.
  • Удален весь интерактив и отслеживание изменений файлов.
  • Удалена папка config/packages и файл dist.loc.
  • План слияния перенесен в папку config.

Конфигурации загружаются следующим образом:

  • Сначала загружаются дефолтные конфигурации пакетов из вендора.
  • Затем загружаются конфигурации корневого пакета.
  • Если есть совпадение ключей, то конфигурация корневого пакета перезапишет конфигурацию пакета из вендора.

Полноценного слияния также не происходит. Существует три слоя: пакеты из вендора, корневой пакет (приложение) и окружения приложения. Одинаковые ключи могут быть в разных слоях, но если в пакетах из вендора или корневой пакете, или в окружениях приложения есть совпадение ключей, то будет брошено исключение о дубликате ключей.

В текущей реализации в подавляющем большинстве, нужно переопределить один ключ, в логгере например, это реализация Psr\Log\LoggerInterface, из-за этого в приложение копируется все конфиг-файлы пакета. В альтернативной реализации, он может в любом конфиг-файле приложения переопределить только реализацию интерфейса, а все остальное подтянется из вендора.

При таком подходе у пользователя практически нет ограничений не в чем. Он сможет создать любую структуру папок. Пользователь может копировать куски кода вручную (как в Yii2 было) или использовать команду. Работать будет и так и так.

Команда копирования

Команда копирует файлы конфигурации пакета от поставщика в каталог конфигурации корневого пакета (приложения):

composer yii-config-copy <package-name> [target-path] [files]

Копирует все файлы конфигурации пакета yiisoft/view:

# To the `config` directory
composer yii-config-copy yiisoft/view

# To the `config/my/path` directory
composer yii-config-copy yiisoft/view my/path

Копирует указанные файлы конфигурации пакета yiisoft/view:

# To the `config` directory
composer yii-config-copy yiisoft/view / params.php web.php

# To the `config/my/path` directory and without the file extension
composer yii-config-copy yiisoft/view my/path params web

Чтобы избежать конфликтов с именами файлов, к именам скопированных файлов добавляется префикс: yiisoft-view-params.php, yiisoft-view-web.php.

Команда обновления плана слияния

Команда обходит все файлы конфигурации и обновляет файл плана слияния. Это может потребоваться, если в структуру файлов конфигураций приложения добавлены файлы или папки, которые не были указаны в composer.json корневого пакета. Необходимо добавить в информацию о новых файлах в composer.json корневого пакета и вызвать команду:

composer yii-config-rebuild
@Nex-Otaku
Copy link

Nex-Otaku commented Sep 10, 2021

  1. Вариант с тем чтобы оставить дефолтные конфиги в вендоре до тех пор пока не потребуется что-то переопределить, однозначно лучше затаскивания всех подряд конфигов в приложение, потому что будет меньше бессмысленных файлов, меньше мусора. Меньше файлов - проще приложение.

  2. Название для команды спорное, что за "copy"? Что куда копируется? Название ничего не проясняет. Можно назвать "extract-config" или "publish-config" по примеру "vendor:publish" в Laravel: https://laravel.com/docs/8.x/packages#configuration

Вообще в Laravel более продуманная система, так как "публиковать" действительно может понадобиться не только конфиг, но и вьюхи с ассетами, допустим какой-то модуль с фронтенд частями предполагающими кастомизацию пользователем. На текущем этапе конечно можно ограничиться конфигом, но на будущее стоит иметь в виду.

  1. "служебная информация о конфигурациях в dist.lock и merge_plan.php не обновится."

Тут два варианта решения.

Вариант 1. Выкидываем вообще dist.lock и merge_plan - непонятно зачем они вообще нужны.

Вариант 2. Делаем команду для ручного обновления при необходимости, а также делаем команду, которая проверяет что эти файлы рассинхронизированы и требуют обновления. Если это покажется целесообразным, можно даже запускать команду проверки в CI или при каждом старте консольного приложения в DEV-окружении.

Я конечно за то чтобы выкинуть и merge_plan и dist.lock. Можно прекрасно обойтись без них, как обходится и Yii2 и любой другой фреймворк.

@devanych
Copy link
Author

devanych commented Sep 10, 2021

В альтернативной реализации удален dist.lock, мерж план нужен для чтения крнфигурации, это самое быстрое и производительное решение, когда все файлы уже сложены и разрулены. Добавлена команда для ручного обновления мерж плана. Практически все ваши замечания решены в предлогаемой реализации, мелкие нюнсы доработаются.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment