feat(devmanual): Refine dependency hell section, recommend bin plugin

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2023-06-05 09:45:12 +02:00
parent 62e8f4aa8e
commit e764556f9a
No known key found for this signature in database
GPG key ID: CC42AC2A7F0E56D8
2 changed files with 36 additions and 1 deletions

View file

@ -13,7 +13,37 @@ Composer
You can add 3rd party php packages with `Composer`_. Composer will download the specified packages to a directory of your choice, typically to ``/vendor``. In order to benefit from Composer's autoloader, you'll want to add a ``require_once`` to the ``register`` method of your ``Application`` class in the :ref:`bootstrapping<Bootstrapping>` code of your app.
.. note:: Be careful with which packages you add to an app. Php can not load two version of the same class twice, hence there can be conflicts between Nextcloud Server and an app or between two or more apps if they ship the same library. So try to keep the number of libraries to a minimum.
.. _app-composer-dependency-hell:
Dependency hell
^^^^^^^^^^^^^^^
Be careful with which packages you add to an app. PHP can not load two version of the same class twice, hence there can be conflicts between Nextcloud Server and an app or between two or more apps if they require the same package. So try to keep the number of production dependencies to a minimum and see :ref:`composer-bin-tools`.
Conflict example
****************
To illustrate the problem imagine app *A* depends on package *foo* in version 1, app *B* depends on package *foo* in version 2. The package *foo* had a breaking change to which app *B* has been adjusted, *A* uses the old API.
Both apps ship a Composer autoloader that autoloads the *foo* functions and classes. There is a race between the two autoloaders. If *A*'s autoloader is asked to load the class first, then v1 will be used. If *B*'s autoloader loads functions and classes first it will be v2. In some scenarios there might be classes of v1 and v2 when autoloaders are invoked without a defined order.
Depending on which functions and classes are loaded, app *A* might work or break. The same applies to *B*.
.. _app-composer-bin-tools:
Development tools
^^^^^^^^^^^^^^^^^
It is very common for an app to use CLI tools for syntax checks, testing and building. Since many tools depend on common Composer packages like ``psr/*`` and ``symfony/console``, it is likely that apps produce a :ref:`dependency hell <app-composer-dependency-hell>` on development environments.
The dependency hell for CLI tools can be avoided by using the *Composer bin plugin*. It's a composer plugin that puts development dependencies into sub directorory with a dedicated autoloader. That autoloader is only used if the CLI tool is used. For Nextcloud apps this means two apps can use conflicting versions of one tool. Moreover dependency conflicts between the tools of one app are no longer an issue.
Tools known to be problematic that should be moved into bin plugin directories include
* ``friendsofphp/php-cs-fixer``
* ``phpunit/phpunit``
* ``vimeo/psalm``
Please see the `package page <https://packagist.org/packages/bamarni/composer-bin-plugin>`_ for up-to-date installation instructions.
.. _Composer: https://getcomposer.org/

View file

@ -42,6 +42,11 @@ Removed APIs
Back-end changes
----------------
Development dependency hell
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Due to the popularity of CLI tools for development of Nextcloud apps, the likelihood of package conflicts has increased. It's highly recommended to see :ref:`app-composer-bin-tools` and migrate to composer bin directories.
Added APIs
^^^^^^^^^^