Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[phpunit-bridge] bin/phpunit will not play well with a custom vendor directory location #30467

Closed
brooksvb opened this issue Mar 6, 2019 · 2 comments

Comments

@brooksvb
Copy link

brooksvb commented Mar 6, 2019

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.

@brooksvb brooksvb changed the title [phpunit-bridge] Running bin/phpunit will not play well with a dynamic vendor directory location [phpunit-bridge] bin/phpunit will not play well with a dynamic vendor directory location Mar 6, 2019
@brooksvb brooksvb changed the title [phpunit-bridge] bin/phpunit will not play well with a dynamic vendor directory location [phpunit-bridge] bin/phpunit will not play well with a custom vendor directory location Mar 6, 2019
@brooksvb
Copy link
Author

brooksvb commented Mar 6, 2019

As a temporary solution I have manually installed phpunit and am not using Symfony's phpunit-bridge. However, I still think this issue should be addressed.

@nicoweb
Copy link
Contributor

nicoweb commented Mar 8, 2019

@woofiewilly can you try something?
put this code on your simple-phpunit /vendor/symfony/phpunit-bridge/bin/simple-phpunit (line around 83) just after $COMPOSER variable definition

$COMPOSER = "COMPOSER_VENDOR_DIR=$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/vendor && " . $COMPOSER;

nicolas-grekas added a commit that referenced this issue Mar 10, 2019
…les (nicoweb)

This PR was merged into the 3.4 branch.

Discussion
----------

[PHPUnit-Bridge] override some Composer environment variables

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #30467
| License       | MIT
| Doc PR        | -

Override `COMPOSER_VENDOR_DIR` and `COMPOSER_BIN_DIR` with their default values in PHPUnit Bridge: #30467

Commits
-------

6285026 [PHPUnit-Bridge] override some environment variables
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants