captainhook: Fatal Error During Execution After Branch Change

We use local Composer repositories, so our composer.json contains something like this:

"local-packages": {
    "type": "path",
    "url": "./local-packages/*/*"
}

This means that our local packages reside under ./local-packages/Namespace/Module and can be included via Composer. Since these are client-specific packages, we require the @dev version from it. This way, the modules are symlinked into the vendor directory and we always have the latest version installed. Example:

$ ll vendor/namespace/module
lrwxrwxrwx 1 www-data tape 23 May  6 07:52 vendor/namespace/module -> ../../local-packages/Namespace/Module

When I now switch branches and one of these local modules is not available in the new branch, we have a broken symlink and I get a fatal error during the CaptainHook execution:

$ vendor/captainhook/captainhook/bin/captainhook -vvv                                                                                07:49:25
PHP Warning:  require(/var/www/html/vendor/composer/../namespace/module/registration.php): failed to open stream: No such file or directory in /var/www/html/vendor/composer/autoload_real.php on line 75

Warning: require(/var/www/html/vendor/composer/../namespace/module/registration.php): failed to open stream: No such file or directory in /var/www/html/vendor/composer/autoload_real.php on line 75
PHP Fatal error:  require(): Failed opening required '/var/www/html/vendor/composer/../namespace/module/registration.php' (include_path='/var/www/html/vendor/magento/zendframework1/library:.:/usr/share/pear:/usr/share/php') in /var/www/html/vendor/composer/autoload_real.php on line 75

Fatal error: require(): Failed opening required '/var/www/html/vendor/composer/../namespace/module/registration.php' (include_path='/var/www/html/vendor/magento/zendframework1/library:.:/usr/share/pear:/usr/share/php') in /var/www/html/vendor/composer/autoload_real.php on line 75

It breaks exactly at the line require CAPTAINHOOK_COMPOSER_AUTOLOAD; of bin/captainhook. I tried dumping the autoloader via composer dump-autoload before the hook execution, but even this does not work. Only a composer install before the hook execution fixes the issue.

Do you see any way to fix this, @sebastianfeldmann? My current idea would be to wrap the require call in a try-catch-block and if an exception occurs, run composer install automagically and try to require the autoload file again. I think this should work, but not sure if you find this workaround acceptable…?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Ah good to know. I will setup a demo project with some local packages and do some experiments 😃

Just wanted to give you an update that the issue does not occur with the PHAR version 👌 Thanks!

@sebastianfeldmann, we ran into an interesting issue with your new code to catch autoloader errors introduced in https://github.com/captainhookphp/captainhook/commit/2382e6de3a22420b5ea313d09e728f67e5308c1d. This actually breaks “everything” with the following process:

  • have captainhook/captainhook and captainhook/plugin-composer installed
  • given a broken / outdated Composer autoloader
  • try to run composer install to fix the autoloader
  • captainhook/plugin-composer detects a composer install and asks captainhook/captainhook to please install the git hooks
  • captainhook/captainhook checks the Composer autoloader, detects that it is broken, outputs a message and exits
  • due to the exit, the autoloader is not fixed and we would need to run composer install to fix it (which leads to the very same issue again)

IMHO, this can easily be fixed by removing the exit here:

https://github.com/captainhookphp/captainhook/blob/df81c361849ece7670c5f9bd41e2e6df2e369ec2/bin/captainhook#L76

Any good reason to keep the exit, @sebastianfeldmann?