diff --git a/doc/03-cli.md b/doc/03-cli.md index 99d4272b8..63e565d57 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -998,6 +998,15 @@ cannot be guessed from VCS info and is not present in `composer.json`. By setting this var you can make Composer install the dependencies into a directory other than `vendor`. +### COMPOSER_RUNTIME_ENV + +This lets you hint under which environment Composer is running, which can help Composer +work around some environment specific issues. The only value currently supported is +`virtualbox`, which then enables some short `sleep()` calls to wait for the filesystem +to have written files properly before we attempt reading them. You can set the +environment variable if you use Vagrant or VirtualBox and experience issues with files not +being found during installation even though they should be present. + ### http_proxy or HTTP_PROXY If you are using Composer from behind an HTTP proxy, you can use the standard diff --git a/src/Composer/Util/Platform.php b/src/Composer/Util/Platform.php index a18af5356..6293ce80c 100644 --- a/src/Composer/Util/Platform.php +++ b/src/Composer/Util/Platform.php @@ -20,7 +20,7 @@ namespace Composer\Util; class Platform { /** @var ?bool */ - private static $isVagrantGuest = null; + private static $isVirtualBoxGuest = null; /** * Parses tildes and environment variables in paths. @@ -123,34 +123,49 @@ class Platform public static function workaroundFilesystemIssues() { - if (self::isVagrantGuest()) { + if (self::isVirtualBoxGuest()) { usleep(200000); } } /** - * Attempts detection of vagrant guest VMs + * Attempts detection of VirtualBox guest VMs * - * This works based on the process' user being "vagrant", or the COMPOSER_RUNTIME_ENV env var being set to "vagrant" + * This works based on the process' user being "vagrant", the COMPOSER_RUNTIME_ENV env var being set to "virtualbox", or lsmod showing the virtualbox guest additions are loaded * * @return bool */ - private static function isVagrantGuest() + private static function isVirtualBoxGuest() { - if (null === self::$isVagrantGuest) { - self::$isVagrantGuest = false; - if (!self::isWindows() && function_exists('posix_getpwuid') && function_exists('posix_geteuid')) { + if (null === self::$isVirtualBoxGuest) { + self::$isVirtualBoxGuest = false; + if (self::isWindows()) { + return self::$isVirtualBoxGuest; + } + + if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) { $processUser = posix_getpwuid(posix_geteuid()); if ($processUser && $processUser['name'] === 'vagrant') { - return self::$isVagrantGuest = true; + return self::$isVirtualBoxGuest = true; } } - if (getenv('COMPOSER_RUNTIME_ENV') === 'vagrant') { - return self::$isVagrantGuest = true; + if (getenv('COMPOSER_RUNTIME_ENV') === 'virtualbox') { + return self::$isVirtualBoxGuest = true; + } + + if (defined('PHP_OS_FAMILY') && PHP_OS_FAMILY === 'Linux') { + $process = new ProcessExecutor(); + try { + if (0 === $process->execute('lsmod | grep vboxguest', $ignoredOutput)) { + return self::$isVirtualBoxGuest = true; + } + } catch (\Exception $e) { + // noop + } } } - return self::$isVagrantGuest; + return self::$isVirtualBoxGuest; } }