PearBinaryInstaller.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Installer;
  12. use Composer\IO\IOInterface;
  13. use Composer\Package\PackageInterface;
  14. use Composer\Util\Filesystem;
  15. use Composer\Util\ProcessExecutor;
  16. /**
  17. * Utility to handle installation of package "bin"/binaries for PEAR packages
  18. *
  19. * @author Jordi Boggiano <j.boggiano@seld.be>
  20. */
  21. class PearBinaryInstaller extends BinaryInstaller
  22. {
  23. private $installer;
  24. private $vendorDir;
  25. /**
  26. * @param IOInterface $io
  27. * @param string $binDir
  28. * @param string $vendorDir
  29. * @param string $binCompat
  30. * @param Filesystem $filesystem
  31. * @param PearInstaller $installer
  32. */
  33. public function __construct(IOInterface $io, $binDir, $vendorDir, $binCompat, Filesystem $filesystem, PearInstaller $installer)
  34. {
  35. parent::__construct($io, $binDir, $binCompat, $filesystem);
  36. $this->installer = $installer;
  37. $this->vendorDir = $vendorDir;
  38. }
  39. protected function getBinaries(PackageInterface $package)
  40. {
  41. $binariesPath = $this->installer->getInstallPath($package) . '/bin/';
  42. $binaries = array();
  43. if (file_exists($binariesPath)) {
  44. foreach (new \FilesystemIterator($binariesPath, \FilesystemIterator::KEY_AS_FILENAME | \FilesystemIterator::CURRENT_AS_FILEINFO) as $fileName => $value) {
  45. if (!$value->isDir()) {
  46. $binaries[] = 'bin/'.$fileName;
  47. }
  48. }
  49. }
  50. return $binaries;
  51. }
  52. protected function initializeBinDir()
  53. {
  54. parent::initializeBinDir();
  55. file_put_contents($this->binDir.'/composer-php', $this->generateUnixyPhpProxyCode());
  56. @chmod($this->binDir.'/composer-php', 0777);
  57. file_put_contents($this->binDir.'/composer-php.bat', $this->generateWindowsPhpProxyCode());
  58. @chmod($this->binDir.'/composer-php.bat', 0777);
  59. }
  60. protected function generateWindowsProxyCode($bin, $link)
  61. {
  62. $binPath = $this->filesystem->findShortestPath($link, $bin);
  63. if ('.bat' === substr($bin, -4)) {
  64. $caller = 'call';
  65. } else {
  66. $handle = fopen($bin, 'r');
  67. $line = fgets($handle);
  68. fclose($handle);
  69. if (preg_match('{^#!/(?:usr/bin/env )?(?:[^/]+/)*(.+)$}m', $line, $match)) {
  70. $caller = trim($match[1]);
  71. } else {
  72. $caller = 'php';
  73. }
  74. if ($caller === 'php') {
  75. return "@echo off\r\n".
  76. "pushd .\r\n".
  77. "cd %~dp0\r\n".
  78. "set PHP_PROXY=%CD%\\composer-php.bat\r\n".
  79. "cd ".ProcessExecutor::escape(dirname($binPath))."\r\n".
  80. "set BIN_TARGET=%CD%\\".basename($binPath)."\r\n".
  81. "popd\r\n".
  82. "%PHP_PROXY% \"%BIN_TARGET%\" %*\r\n";
  83. }
  84. }
  85. return "@echo off\r\n".
  86. "pushd .\r\n".
  87. "cd %~dp0\r\n".
  88. "cd ".ProcessExecutor::escape(dirname($binPath))."\r\n".
  89. "set BIN_TARGET=%CD%\\".basename($binPath)."\r\n".
  90. "popd\r\n".
  91. $caller." \"%BIN_TARGET%\" %*\r\n";
  92. }
  93. private function generateWindowsPhpProxyCode()
  94. {
  95. $binToVendor = $this->filesystem->findShortestPath($this->binDir, $this->vendorDir, true);
  96. return
  97. "@echo off\r\n" .
  98. "setlocal enabledelayedexpansion\r\n" .
  99. "set BIN_DIR=%~dp0\r\n" .
  100. "set VENDOR_DIR=%BIN_DIR%\\".$binToVendor."\r\n" .
  101. "set DIRS=.\r\n" .
  102. "FOR /D %%V IN (%VENDOR_DIR%\\*) DO (\r\n" .
  103. " FOR /D %%P IN (%%V\\*) DO (\r\n" .
  104. " set DIRS=!DIRS!;%%~fP\r\n" .
  105. " )\r\n" .
  106. ")\r\n" .
  107. "php.exe -d include_path=!DIRS! %*\r\n";
  108. }
  109. private function generateUnixyPhpProxyCode()
  110. {
  111. $binToVendor = $this->filesystem->findShortestPath($this->binDir, $this->vendorDir, true);
  112. return
  113. "#!/usr/bin/env sh\n".
  114. "SRC_DIR=`pwd`\n".
  115. "BIN_DIR=`dirname $0`\n".
  116. "VENDOR_DIR=\$BIN_DIR/".escapeshellarg($binToVendor)."\n".
  117. "DIRS=\"\"\n".
  118. "for vendor in \$VENDOR_DIR/*; do\n".
  119. " if [ -d \"\$vendor\" ]; then\n".
  120. " for package in \$vendor/*; do\n".
  121. " if [ -d \"\$package\" ]; then\n".
  122. " DIRS=\"\${DIRS}:\${package}\"\n".
  123. " fi\n".
  124. " done\n".
  125. " fi\n".
  126. "done\n".
  127. "php -d include_path=\".\$DIRS\" $@\n";
  128. }
  129. }