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
source to share
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.
source to share