Open windbridges opened 2 years ago
As far as my experience goes, you should always strive for a consistent installation across all environments (between collaborators, staging, and production). To that end, at the very least you should commit the project's lock file and always use composer install
.
You could ignore the lock files for your project's extensions. I try to ensure each extension can run on its own so I will often commit their lock files as well, if ever I need to cross reference inconsistencies between the project's lock file (which includes all the extensions' dependencies) and the extensions' lock files.
I usually use composer update
when updating and/or testing the latest versions of dependencies.
I absolutely agree, there is a rule - commit the .lock file in the project, and ignore it in the library/extension. This is the rule I want to follow, but it gets messy.
Suppose the project supports extensions, they should be loaded into a certain directory of the project. Initially, the extensions directory in the main project repository is empty. After the main project is deployed, the user deploys the necessary extensions to this directory.
Because initially there are no extensions, composer.lock contains only the dependencies of the main project. But after the user deploys the extensions he will need to do a composer update
to get the composer to read the extensions dependencies and include them to the autoload. That's what the README says. But once we do a composer update
, we lose the consistency of the versions for which we include composer.lock in the repository. And there is no other way to include extension dependencies, because composer install
will not work in this case.
That's why I have this question. Maybe I don't fully understand the workflow when using this plugin?
Hrm. Indeed, I have not had the opportunity to work with such a scenario where extensions are added "externally".
It is a tricky scenario. Maybe we need a custom command, or argument for an existing command, to tackle these kinds of scenarios which would minimize impact on the project's dependencies.
Something like:
composer update --merge-plugin-reqs="extensions/*/composer.json"
Here we need some kind of scenario that allows us not to modify the composer.lock of the main project, only the autoload map. Otherwise, no matter what this command does, the dependencies of the extensions will always be injected into the main project. Since composer.lock is part of the repository, there will always be a chance to accidentally commit changes when developing locally, and that's bad.
composer-merge-plugin is meant for projects that cannot ship their composer.lock file because of the strange need to mix upstream project dependencies and local deployment dependencies. It is a giant hack to make possible MediaWiki's use of Composer to manage PHP library dependencies while also supporting the legacy functionality of installing MediaWiki extensions in a local deployment using Composer.
The fix used by MediaWiki core for the lack of a versioned lock file is the use of exact versions where the library version is important for the deployment.
We're running into a similar issue. Using exact versions will work but we would also like to have a way of soft removing the local dependencies instead of removing the composer.json files.
For example, we have a local extension A that was picked up by the merge and has its dependencies added. We would love to be able to ignore the extension A folder on the fly. And run something like composer update --merge-plugin-exclude="extensions/A/composer.json"
(or an include override statement where we could remove the include) which would effectively update the lock file and vendor folder, removing all dependencies in A.
This is currently possible by removing the A extension entirely (or A composer file) and running an update with exact versions. And this can work fine for generating deployment artifacts, but for a variety of reasons we would love to have the softer option as well as that would allow us to generate our artifacts differently.
I don't quite understand how to correctly separate dependencies between the main project and extensions. When I do a
composer update
, a newcomposer.lock
is created which contains the dependencies of the project and extensions. Since I commit this file to the repository, runningcomposer install
in production will install all the dependencies it contains, even if no extensions are installed and those dependencies are not needed.If I understand correctly, it is assumed that
composer.lock
should not be present in the repository and the production should usecomposer update
instead ofcomposer install
?