psysh 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/env php
  2. <?php
  3. /*
  4. * This file is part of Psy Shell.
  5. *
  6. * (c) 2012-2017 Justin Hileman
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. // Try to find an autoloader for a local psysh version.
  12. // We'll wrap this whole mess in a Closure so it doesn't leak any globals.
  13. call_user_func(function () {
  14. $cwd = null;
  15. // Find the cwd arg (if present)
  16. $argv = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
  17. foreach ($argv as $i => $arg) {
  18. if ($arg === '--cwd') {
  19. if ($i >= count($argv) - 1) {
  20. fwrite(STDERR, 'Missing --cwd argument.' . PHP_EOL);
  21. exit(1);
  22. }
  23. $cwd = $argv[$i + 1];
  24. break;
  25. }
  26. if (preg_match('/^--cwd=/', $arg)) {
  27. $cwd = substr($arg, 6);
  28. break;
  29. }
  30. }
  31. // Or fall back to the actual cwd
  32. if (!isset($cwd)) {
  33. $cwd = getcwd();
  34. }
  35. $cwd = str_replace('\\', '/', $cwd);
  36. $chunks = explode('/', $cwd);
  37. while (!empty($chunks)) {
  38. $path = implode('/', $chunks);
  39. $prettyPath = $path;
  40. if (isset($_SERVER['HOME']) && $_SERVER['HOME']) {
  41. $prettyPath = preg_replace('/^' . preg_quote($_SERVER['HOME'], '/') . '/', '~', $path);
  42. }
  43. // Find composer.json
  44. if (is_file($path . '/composer.json')) {
  45. if ($cfg = json_decode(file_get_contents($path . '/composer.json'), true)) {
  46. if (isset($cfg['name']) && $cfg['name'] === 'psy/psysh') {
  47. // We're inside the psysh project. Let's use the local Composer autoload.
  48. if (is_file($path . '/vendor/autoload.php')) {
  49. if (realpath($path) !== realpath(__DIR__ . '/..')) {
  50. fwrite(STDERR, 'Using local PsySH version at ' . $prettyPath . PHP_EOL);
  51. }
  52. require $path . '/vendor/autoload.php';
  53. }
  54. return;
  55. }
  56. }
  57. }
  58. // Or a composer.lock
  59. if (is_file($path . '/composer.lock')) {
  60. if ($cfg = json_decode(file_get_contents($path . '/composer.lock'), true)) {
  61. foreach (array_merge($cfg['packages'], $cfg['packages-dev']) as $pkg) {
  62. if (isset($pkg['name']) && $pkg['name'] === 'psy/psysh') {
  63. // We're inside a project which requires psysh. We'll use the local Composer autoload.
  64. if (is_file($path . '/vendor/autoload.php')) {
  65. if (realpath($path . '/vendor') !== realpath(__DIR__ . '/../../..')) {
  66. fwrite(STDERR, 'Using local PsySH version at ' . $prettyPath . PHP_EOL);
  67. }
  68. require $path . '/vendor/autoload.php';
  69. }
  70. return;
  71. }
  72. }
  73. }
  74. }
  75. array_pop($chunks);
  76. }
  77. });
  78. // We didn't find an autoloader for a local version, so use the autoloader that
  79. // came with this script.
  80. if (!class_exists('Psy\Shell')) {
  81. /* <<< */
  82. if (is_file(__DIR__ . '/../vendor/autoload.php')) {
  83. require __DIR__ . '/../vendor/autoload.php';
  84. } elseif (is_file(__DIR__ . '/../../../autoload.php')) {
  85. require __DIR__ . '/../../../autoload.php';
  86. } else {
  87. fwrite(STDERR, 'PsySH dependencies not found, be sure to run `composer install`.' . PHP_EOL);
  88. fwrite(STDERR, 'See https://getcomposer.org to get Composer.' . PHP_EOL);
  89. exit(1);
  90. }
  91. /* >>> */
  92. }
  93. // If the psysh binary was included directly, assume they just wanted an
  94. // autoloader and bail early.
  95. //
  96. // Keep this PHP 5.3 and 5.4 code around for a while in case someone is using a
  97. // globally installed psysh as a bin launcher for older local versions.
  98. if (version_compare(PHP_VERSION, '5.3.6', '<')) {
  99. $trace = debug_backtrace();
  100. } elseif (version_compare(PHP_VERSION, '5.4.0', '<')) {
  101. $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
  102. } else {
  103. $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
  104. }
  105. if (Psy\Shell::isIncluded($trace)) {
  106. unset($trace);
  107. return;
  108. }
  109. // Clean up after ourselves.
  110. unset($trace);
  111. // If the local version is too old, we can't do this
  112. if (!function_exists('Psy\bin')) {
  113. $argv = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
  114. $first = array_shift($argv);
  115. if (preg_match('/php(\.exe)?$/', $first)) {
  116. array_shift($argv);
  117. }
  118. array_unshift($argv, 'vendor/bin/psysh');
  119. fwrite(STDERR, 'A local PsySH dependency was found, but it cannot be loaded. Please update to' . PHP_EOL);
  120. fwrite(STDERR, 'the latest version, or run the local copy directly, e.g.:' . PHP_EOL);
  121. fwrite(STDERR, PHP_EOL);
  122. fwrite(STDERR, ' ' . implode(' ', $argv) . PHP_EOL);
  123. exit(1);
  124. }
  125. // And go!
  126. call_user_func(Psy\bin());