-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prefix four dependencies during composer install/update (symfony/console, twig, monolog & php-di) #19712
Conversation
FYI @tsteur. Not sure if there's anyone else I should ping, apologies if I missed someone. |
Nice, I just checked out the branch and ran the command and it renamed things nicely. Ideally, when running composer in the future then it would indeed need to run php-scoper directly as part of the composer command.
Not fully understanding what is meant by this one @diosmosis ? Would that mean that if someone uses Matomo for WordPress, and they install another Matomo plugin from the Marketplace in their WordPress, and this marketplace doesn't use the prefixed version, then it may cause issues that it could use a wrong vendor version from a completely different WordPress plugin? I guess if we were to only replace Twig and Monolog this could be fine potentially as it's maybe usually not expected that these libraries would be used too often directly. I guess from my perspective I just want to keep On-Premise and Matomo for WordPress as similar as possible to not have any unnoticed possible regressions in Matomo for WordPress because they run different code. Looking at the PR I think that doesn't seem to be the case though if I understand it right and would only apply to plugins. |
Yes, that could be an issue. If scoping in the composer workflow, then I guess the plugin developer would be forced to use the prefixed namespace otherwise it wouldn't work for a normal Matomo, so this wouldn't happen.
I understand. For a proof of concept I wanted to provide a solution the was as minimal as possible and show that if it turns out to be more complicated to prefix a dependency correctly and predictably, there was an easy way to go back. I also wanted to show its possible to externalize the mechanism and not have it in core if desired. All of this mostly because there was a lot of manual replacing required for twig, though it's probably an exception given it defines so many functions and generates php code that uses them. Regardless, I can make it part of the composer workflow if desired, should I move forward with that? (I don't have a big opinion here, I think it's workable either way.) |
@tsteur I'm going to assume adding to the compost workflow is required. Can you tell me what release this is intended to be a part of or point me to someone who can? |
We shouldn't do that before Matomo 5. As plugin developers should adjust their code, that imho shouldn't be done in a minor release. Also using the scoped classes in plugins would make those incompatible with older Matomo releases... |
Clarified on slack this should be targeting 5.x-dev. |
…fix dependency command
Sorry about the late reply
Yes, that be great |
…e/bootstrap.php (eg the phpunit entry file)
…dencies from autoload files, since dependencies of prefixed dependencies may not be included
…for prefixed dependencies so unprefixed dependencies of prefixed dependencies will have psr classmaps generated correctly
@sgiehl OneClickUpdate tests are passing. The other failures look unrelated, let me know if otherwise. |
This issue is in "needs review" but there has been no activity for 7 days. ping @matomo-org/core-reviewers |
This PR was last updated more than one month ago, maybe it's time to close it. Please check if there is anything we still can do or close this PR. ping @matomo-org/core-reviewers |
If you don't want this PR to be closed automatically in 28 days then you need to assign the label 'Do not close'. |
If you don't want this PR to be closed automatically in 28 days then you need to assign the label 'Do not close'. |
If you don't want this PR to be closed automatically in 28 days then you need to assign the label 'Do not close'. |
Fixes #16905
Refs #8568
In environments when Matomo runs alongside other PHP software, such as in Matomo for WordPress, hard to debug issues caused by conflicting dependencies can arise. Given there is no way to know exactly which other versions of dependencies might
end up being used in a user's setup, dealing with them on a version-by-version basis is undesirable (if at all possible).
This PR provides the ability to prefix dependencies in core and in plugins as part of the composer workflow, making sure the
dependencies we use do not conflict with different versions in other software.
twig & monolog are currently configured to be prefixed in this PR. An example of prefixing composer dependencies in a plugin can be found here: matomo-org/plugin-GoogleAnalyticsImporter#279
Adding support for dependency prefixing
Prefixing is accomplished via a new
composer:prefix-dependency
command. It is added as a post install and post update script in composer.json files, eg:or
For plugins, the dependencies that you want prefixed are listed in the
plugin.json
file, in theprefixedDependencies
property. For core, the list is hardcoded in the Prefixer class.Prefixing a dependency
Once the command is added to composer.json, you can add dependencies to prefixedDependencies. However, this alone may not be enough. If the dependency you want to prefix dynamically references classes and functions, php-scoper, the tool used to prefix the namespaces, may not be able to detect and change those uses. In that case, you need to manually replace code via a patcher that you define in scoper.inc.php. An example of this is the extra replaces done for twig in the scoper.inc.php file for Matomo core, and https://github.com/matomo-org/plugin-GoogleAnalyticsImporter/blob/a7f6b48bec018338bb815bdf9bfa2e17223aa5f7/scoper.inc.php for google's compiled PHP protobuf code.
How prefixing is accomplished
Prefixing is accomplished using the php-scoper project. php-scoper processes a folder, adding a prefix to all namespace/use
statements, and anything else it recognizes. It works pretty well, but doesn't replace more dynamic usages. Those can be
replaced manually, however, by adding code to a scoper.inc.php file (as mentioned above).
The entire process, encapsulated by the
composer:prefix-dependency
command and thePiwik\Dependency\Prefixer
class is as follows:Matomo\Dependencies
for core orMatomo\Dependencies\{PluginName}
for a plugin.MATOMO_DEPENDENCIES_TO_PREFIX
environment variable. scoper.inc.php uses aFinder
to limit the processed files to those dependencies' directories.MATOMO_NAMESPACES_TO_PREFIX
environment variable. scoper.inc.php specifies those namespaces in a include_namespaces configuration for php-scoper (NOTE: this option is actually added via a fork on my personal github, more info below.) This lets us limit prefixing to just the dependencies we want to prefix.vendor/prefixed
directoryMatomo\Dependencies
as the prefix and the namespace just for prefixed core dependencies. So in core, since we prefix monolog, this part of the process will replace uses of Monolog in plugin dependencies withMatomo\Dependencies\Monolog
, for instance.The process is slightly different if prefixing for a plugin that has an empty
prefixedDependencies
property. In this case, since we don't need to prefix anything, but still need to replace references to prefixed core dependencies, only the second php-scoper pass is done.include_namespaces
Currently php-scoper only has
exclude_***
configuration options. This is pretty inconvenient when we want to prefix X and exclude everything else, so I added an include_namespaces feature in https://github.com/diosmosis/php-scoper/tree/included-namespaces. An official fork in the matomo-org organization will need to be made eventually. No other changes to php-scoper are needed, and we probably won't need to ever update it. I'll try to get the changes accepted upstream after this is reviewed.Review