captainhookphp / captainhook

CaptainHook is a very flexible git hook manager for software developers that makes sharing git hooks with your team a breeze.
http://captainhook.info
MIT License
1.01k stars 87 forks source link

Path to the composer autoload bootstrap file is not using a "realpath" #213

Closed balatD closed 1 year ago

balatD commented 1 year ago

My captainhook configuration JSON is inside the vendor folder (here a example: vendor/bejlat/src/config/captainhook/captainhook.json). The problem is telling captainhook where to find the composer bootstrap as I cannot simply use captainhook install --boostrap=../../../../autoload.php

Is there a way to do this right now with the current codebase or does it need to be modified?

Thanks! :)

sebastianfeldmann commented 1 year ago

Are you using the PHAR version or do you have a composer installation in vendor/captainhook/capainhook with a vendor/bin/captainhook executable?

If you are using the Composer package bootstrapping should not be necessary or to be precise it will be skipped since the Cap'n will look for the autoload.php by itself. It will check the following locations.

   __DIR__ . '/../autoload.php',        // installed at vendor/bin/captainhook
   __DIR__ . '/../vendor/autoload.php', // installed at bin/captainhook
   __DIR__ . '/../../../autoload.php'   // installed at vendor/captainhook/captainhook/bin/captainhook

If you are using the PHAR version it will use the directory of your configuration file as base and append your path provided via the bootstrap option.

If your config is located in

vendor/bejlat/src/config/captainhook/captainhook.json

and your autoload.php is located in

vendor/autoload.php

Then you should run the Cap'n like this

captainhook --install --configuration=vendor/bejlat/src/config/captainhook/captainhook.json --bootstrap=../../../../autoload.php

You can avoid the hassle by adding a captainhook.json in your project root and include your bejlat one.

  "config": {
    "includes": [
      "vendor/bejlat/src/config/captainhook/captainhook.json"
    ]
}

But this has some caveats. All relative path in your sub config will be interpreted relative to your project root. And some configuration settings can not be overwritten.

balatD commented 1 year ago

Thank you for your quick reply! I am using the composer version and CaptainHook is installed in vendor/captainhook. Without any configuration on the bootstrap side, I am getting the following error:

In Builder.php line 55:
  bootstrap file not found: '/var/www/html/vendor/bejlat/src/config/captainhook/vendor/autoload.php'  

Adding a --bootstrap parameter yields this error message:

In Builder.php line 55:
  bootstrap file not found: '/var/www/html/vendor/bejlat/src/config/captainhook/../../../../autoload.php'  

I am using a Docker container managed by DDEV.

sebastianfeldmann commented 1 year ago

So a couple of questions :)

1.) Where is your .git directory located?

/var/www/html/.git ?

2.) Where is your Cap'n binary located?

/var/www/html/vendor/bin/captainhook ?

3.) Why do you have two vendor directories? Just a naming coincidence?

4.) Where is the autoloader you want to use

/var/www/html/vendor/autoload.php ?
balatD commented 1 year ago

1.) Yes my .git folder is under /var/www/html/.git

2.) Thats also correct /var/www/html/vendor/bin/captainhook

3.) I don't have two vendor folders, just the one thats generated from composer inside project root /var/www/html/vendor

4.) Yes, the autoloader ist located per default in vendor.

My guess is that the logic behind resolving a path like this /var/www/html/vendor/bejlat/src/config/captainhook/../../../../autoload.php just isn't working as intended or it's something on my side.

sebastianfeldmann commented 1 year ago

I tried to reconstruct your environment.

When I executed the Cap'n from the repository root /var/www/html like this

vendor/bin/captainhook install --configuration vendor/bejlat/src/config/captainhook/captainhook.json

I got the following error

Invalid git repository: /var/www/html/vendor/bejlat/src/config/captainhook 

Because the captain tries to find the repository right next to the configuration file. Then I provided the --git-directory option.

vendor/bin/captainhook install --configuration vendor/bejlat/src/config/captainhook/captainhook.json --git-directory ../../../../../.git

This led to the same error you are experiencing

bootstrap file not found: '/var/www/html/vendor/bejlat/src/config/captainhook/vendor/autoload.php'

I fixed it with the --bootstrap option like this

vendor/bin/captainhook install --configuration vendor/bejlat/src/config/captainhook/captainhook.json --git-directory ../../../../../.git --bootstrap ../../../../autoload.php

This worked and installed the hooks.

balatD commented 1 year ago

Sorry for the late reply! I've managed to fix my issue. The problem was that I was using a local repository of the package in my composer configuration. Captainhook resolved the path not in the vendor folder but in my "packages" folder that was a repository for composer.

Thank you for your help!