Skip to content
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

Documentation on how autoloading works when running a composer plugin. #10587

Closed
pieterw2w opened this issue Mar 3, 2022 · 3 comments
Closed
Labels

Comments

@pieterw2w
Copy link

I write a(n internal) composer plugin and in my plugin I have an optional dependency to symfony/yaml. If symfony/yaml is loaded I expect to parse a yaml file.

So the code in plugin is doing something like this (not the actual code):

<?php
use Composer\InstalledVersions;
use Symfony\Component\Yaml\Yaml;

if (InstalledVersions::isInstalled('symfony/yaml')) {
    $yamlParsed = Yaml::parse(file_get_contents($projectRoot . '/config.yml'));
}

I get the following output:

PHP Fatal error:  Uncaught Error: Class 'Symfony\Component\Yaml\Yaml' not found

And I expected that class Symfony\Component\Yaml\Yaml is autoloaded and usable.
However if I move it to its own php file that explicitly loads the generated composer autoloader and try to run it in a separate php process I can load the Yaml class just fine.

I can imagine that a composer plugin is running in its own php process when composer is running to avoid loading classes before composer install/update has been executed, so I assume that a composer plugin is not loading the composer autoloader by default.

I can not find any documentation how this works in composer. It is not an option for me to add the dependency in my plugin as a non-dev dependency as that would mean every application using the plugin has an extra dependency.

Or could it be related to this issue? #10509

@Seldaek
Copy link
Member

Seldaek commented Mar 15, 2022

Does your plugin require symfony/yaml? Only packages explicitly required by a plugin will be made available by the Composer runtime autoloader.

Also using InstalledVersions there may be unwise, it may not yet be fully populated depending on when your plugin runs, so I would say doing a class_exists(Yaml::class) check instead would be better.

@pieterw2w
Copy link
Author

pieterw2w commented Mar 15, 2022

yes, I thought that was the case with the explicit dependencies. It's a dev dependency so I can use it my own tests, but I don't want to make it a hard dependency if a project uses the composer plugin as I don't want to limit the number of hard dependencies

So it will 'fail' in this case:
project depends on plugin + symfony/yaml
plugin has dev dependency to symfony/yaml
the runtime autoloader does not load symfony/yaml as it ignores dev dependencies of dependencies when the plugin is being called even though technically it could use it.

Still it would be nice how the autoloading works in a composer plugin is documented in the documentation, because it's a blackbox to me now (and maybe document about the gotcha's)

If there's a way how I should do it properly without making it a hard dependency it would be nice . Currently I have it fixed to run php in a extra php process running the autoloader after the plugin is done.

@Seldaek
Copy link
Member

Seldaek commented Mar 15, 2022

If there's a way how I should do it properly without making it a hard dependency it would be nice . Currently I have it fixed to run php in a extra php process running the autoloader after the plugin is done.

There is no way and IMO a conditional dependency here is such a rare case that I'd rather not explore changes in that direction.

I'll see if I can improve the docs relating to autoloading on the plugin page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants