-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Symfony version(s) affected: All
Description
I get the following error when running bin/phpunit
:
[LogicException]
No lockfile found. Unable to read locked packages
The full output of the command is as follows:
vagrant@<REDACTED>:~/project$ bin/phpunit
#!/usr/bin/env php
Installing phpunit/phpunit (7.0.3)
Plugins have been disabled.
- Installing phpunit/phpunit (7.0.3): Loading from cache
Created project in phpunit-7.0
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies
Package operations: 23 installs, 0 updates, 95 removals
- Removing zendframework/zend-code (3.3.1)
[LogicException]
No lockfile found. Unable to read locked packages
install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [--no-suggest] [-v|vv|vvv|--verbose
] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--ignore-platform-reqs] [--] [<packages>]...
I have a custom solution for allowing a dynamic vendor directory location so that I can keep my vendor directory outside of the NFS folder of the project inside my Vagrant virtual machine for performance reasons. The solution involves setting the COMPOSER_VENDOR_DIR environment variable to the desired vendor location, which is supported by composer itself for the installation location. I manually added in support for checking this environment variable into my Symfony project. However, the simple-phpunit
script in the phpunit-bridge
package does not allow me any way to support this without modifying the dependency itself.
I disabled my custom vendor location to use the normal path, and this resolved the problem and I can run bin/phpunit
without errors. I'm not sure exactly where the problem is in the simple-phpunit
that causes this to happen, because I would think my COMPOSER_VENDOR_DIR envvar gets passed through to the internal composer runs.
I also externally set the SYMFONY_PHPUNIT_DIR to a custom location of my liking outside the NFS directory, which worked in installing the phpunit dependency where I wanted, but it did not prevent the above error.
How to reproduce
I have 3 relevant environment variables:
export COMPOSER_VENDOR_DIR=/var/symfony/vendor
export SYMFONY_VAR_DIR=/var/symfony
export SYMFONY_PHPUNIT_DIR=/var/symfony/.phpunit
Custom Symfony code relevant to my case:
// bin/console
...
// For requiring autoload whose location may be dynamic
$vendorDirectory = getenv('COMPOSER_VENDOR_DIR');
if ($vendorDirectory === false) {
$vendorDirectory = dirname(__DIR__).'/vendor';
}
require $vendorDirectory.'/autoload.php';
unset($vendorDirectory);
...
// config/bootstrap.php
...
// For requiring autoload whose location may be dynamic
$vendorDirectory = getenv('COMPOSER_VENDOR_DIR');
if ($vendorDirectory === false) {
$vendorDirectory = dirname(__DIR__).'/vendor';
}
require $vendorDirectory.'/autoload.php';
unset($vendorDirectory);
...
// src/Kernel.php
... // Following are changes for setting custom var directory location
/**
* @var string
*
* Custom added. At construct time, checks for SYMFONY_VAR_DIR environment variable. If defined, that directory
* is used. Otherwise the default location is used.
*
* Environment variable is expected to have no trailing slash and be an absolute path to a directory.
*/
private $varDirectory;
public function __construct(string $environment, bool $debug)
{
parent::__construct($environment, $debug);
$this->varDirectory = getenv('SYMFONY_VAR_DIR');
if ($this->varDirectory === false) {
$this->varDirectory = $this->getProjectDir().'/var';
}
}
public function getCacheDir()
{
// Custom modified to use varDirectory
return $this->varDirectory.'/cache/'.$this->environment;
}
public function getLogDir()
{
// Custom modified to use varDirectory
return $this->varDirectory.'/logs';
}
...
My attempted changes to bin/phpunit to fix the problem
// bin/phpunit
#!/usr/bin/env php
<?php
$vendorDirectory = getenv('COMPOSER_VENDOR_DIR');
if ($vendorDirectory === false) {
$vendorDirectory = dirname(__DIR__).'/vendor';
}
if (!file_exists($vendorDirectory.'/symfony/phpunit-bridge/bin/simple-phpunit')) {
echo "Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
exit(1);
}
if (false === getenv('SYMFONY_PHPUNIT_VERSION')) {
putenv('SYMFONY_PHPUNIT_VERSION=7.0');
}
if (false === getenv('SYMFONY_PHPUNIT_REMOVE')) {
putenv('SYMFONY_PHPUNIT_REMOVE=');
}
if (false === getenv('SYMFONY_PHPUNIT_DIR')) {
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
}
// Use custom vendor path
require $vendorDirectory.'/symfony/phpunit-bridge/bin/simple-phpunit';
Possible Solution
I'm not sure exactly what needs to be changed because I don't understand the entirety of the simple-phpunit
script, but my COMPOSER_VENDOR_DIR needs to be respected for the location of the vendor directory, and passed into any internal composer runs where that is important.
If I can at least prevent the errors that keep me from using phpunit-bridge I would be satisfied, but I feel like it should be a supported feature to have a non-standard vendor directory location and customize it somehow.
If anyone can suggest a temporary solution I would greatly appreciate it.