Get package install path from composer script / composer API

I would like to copy some file located inside a package after I installed this package from Composer.

In fact, after installing or updating a package from Composer, I would like to copy the file that might be inside the downloaded package to a different directory. I am using scripts with post-package-install and post-package-update command, but I cannot find how to get the install path.

This is my current script:

use Composer\Script\PackageEvent;

class MyScript {

public static function copyFiles(PackageEvent $event)
{
    $package = $event->getOperation()->getPackage();

    $originDir = $package->someFunctionToFind(); #Here, I should retrieve the install dir

    if (file_exists($originDir) && is_dir($originDir)) {
        //copy files from $originDir to a new location
    } 

}
}

      

Does anyone know how to get the installation directory of an installed / updated package from the PackageEvent class (which is specified in the parameter)?

NOTE.

I tried $event->getOperation()->getPackage->targetDir()

, but this does not indicate the installation path, but the targetDir of the package defined in composer.json

+3


source to share


1 answer


I could get the install path using Composer \ Installation \ InstallationManager :: getInstallPath method .

Theoretical answer:

use Composer\Script\PackageEvent;

class MyScript {

public static function copyFiles(PackageEvent $event)
{
    $package = $event->getOperation()->getPackage();
    $installationManager = $event->getComposer()->getInstallationManager();

    $originDir = $installationManager->getInstallPath($package);

    if (file_exists($originDir) && is_dir($originDir)) {
        //copy files from $originDir to a new location
    } 

}
}

      

But this answer is theoretical because I couldn't find a match to debug my code without actually installing the package (which was painful: I had to uninstall the package and reinstall it to test my code).

So, I switch to post-install-cmd and post-update-cmd and my arrival became:



use Composer\Script\CommandEvent; #the event is different !

class MyScript {

public static function copyFiles(CommandEvent $event)
{
    // wet get ALL installed packages
    $packages = $event->getComposer()->getRepositoryManager()
          ->getLocalRepository()->getPackages();
    $installationManager = $event->getComposer()->getInstallationManager();

    foreach ($packages as $package) {
         $installPath = $installationManager->getInstallPath($package);
         //do my process here
    }
}
}

      

Don't forget to add the command to composer .json:

"scripts": {

        "post-install-cmd": [
            "MyScript::copyFiles"
        ],
        "post-update-cmd": [
            "MyScript::copyFiles"
        ]
}

      

To debug the code I had to run composer .phar run-script post-install-cmd.

NOTE. this code should work with psr4. For psr0, you may need to add $ package-> targetDir () to get the correct installation path. Feel free to comment or improve your answer.

+3


source







All Articles