Skip to content

kernel.project_dir incorrectly resolved in Nix #3908

@mridang

Description

@mridang

Expected behavior

When phpDocumentor is installed as a Composer dependency, it should correctly determine the main project's root directory (e.g., /Users/mridang/Code/zitadel/client-php/) as the value for the %kernel.project_dir% parameter in its dependency injection container.

This would allow its internal configuration files (like reflection.yaml) to correctly resolve paths to other packages located in the project's main vendor directory. For example, a resource path like '%kernel.project_dir%/vendor/phpdocumentor/reflection/...' should correctly resolve to /Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/reflection/....

Ultimately, documentation should generate successfully without path errors for internal or sub-dependencies.

Actual behavior

In phpDocumentor v3.7.1 (when installed as a Composer dependency via composer require --dev phpdocumentor/phpdocumentor:"^3.7"), the %kernel.project_dir% parameter is incorrectly set. Instead of pointing to the actual project root, it points to the root directory of the phpdocumentor/phpdocumentor package itself within the main project's vendor directory (e.g., /Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/phpdocumentor/).

This misconfiguration causes issues when phpDocumentor's services, defined in files like config/reflection.yaml, try to locate resources. For instance, a path defined as '%kernel.project_dir%/vendor/phpdocumentor/reflection/...' resolves to an incorrect, nested path like /Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/phpdocumentor/vendor/phpdocumentor/reflection/....

Because the phpdocumentor/reflection package (and others) are actually located at /Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/reflection/, this leads to a Symfony\Component\Config\Exception\FileLocatorFileNotFoundException. The error messages typically state that the target file/directory does not exist, referencing the incorrect nested path, and originate from Symfony\Component\Config\Loader\FileLoader (e.g., line 182) and Symfony\Component\Config\FileLocator (e.g., line 46).

The root cause appears to be the method used to set the %kernel.project_dir% parameter. The following line of code was identified in vendor/phpdocumentor/phpdocumentor/src/phpDocumentor/Console/ContainerFactory.php:
$this->container->setParameter('kernel.project_dir', dirname(__DIR__, 3));

In the context of a Composer installation where this file is located at [PROJECT_ROOT]/vendor/phpdocumentor/phpdocumentor/src/phpDocumentor/Console/ContainerFactory.php, dirname(__DIR__, 3) resolves to [PROJECT_ROOT]/vendor/phpdocumentor/phpdocumentor/, not the actual project root.

For my specific project structure, temporarily changing dirname(__DIR__, 3) to dirname(__DIR__, 6) in this line of code correctly sets %kernel.project_dir% to my actual project root (/Users/mridang/Code/zitadel/client-php/) and resolves the issue, allowing documentation to be generated. This confirms the file ContainerFactory.php (and specifically its directory __DIR__) is effectively 6 levels deep from my project root.

Steps to reproduce the problem

  1. Initialize a PHP project using Composer (e.g., ensure you have a composer.json).
  2. Add phpdocumentor/phpdocumentor as a development dependency, specifically a version that resolves to v3.7.1:
    composer require --dev phpdocumentor/phpdocumentor:"^3.7"
    (This installed phpdocumentor/phpdocumentor v3.7.1 and phpdocumentor/reflection v6.1.0 in my environment).
  3. Ensure you have some PHP source code that phpDocumentor can try to parse (e.g., in a src/ directory).
  4. Attempt to generate documentation using the CLI:
    vendor/bin/phpdoc -d ./src -t ./docs/api
    (Adjust -d and -t paths as needed for your project structure).
  5. Observe the Symfony\Component\Config\Exception\FileLocatorFileNotFoundException error. The error message will indicate that a path like [YourProjectRoot]/vendor/phpdocumentor/phpdocumentor/vendor/phpdocumentor/reflection/src/phpDocumentor/Reflection/Php does not exist, and that this path issue originates from [YourProjectRoot]/vendor/phpdocumentor/phpdocumentor/config/reflection.yaml.

Your environment

  • Version used: phpdocumentor/phpdocumentor v3.7.1 (with phpdocumentor/reflection v6.1.0).
  • Install method: Composer, as a project dependency.
  • PHP version: PHP 8.1.24 (cli) (built: Oct 19 2023 17:55:31) (NTS)
  • Operating system and version: macOS (Darwin) - problem observed within a Devbox/Nix environment.
  • Link to your project (where the issue was observed): https://github.com/zitadel/client-php
  • Code/Files involved:
    • Identified problematic line in phpDocumentor:
      • File: vendor/phpdocumentor/phpdocumentor/src/phpDocumentor/Console/ContainerFactory.php (in phpDocumentor v3.7.1)
      • Line: $this->container->setParameter('kernel.project_dir', dirname(__DIR__, 3));
    • Configuration file in phpDocumentor using the incorrect path:
      • Path: vendor/phpdocumentor/phpdocumentor/config/reflection.yaml
      • Content snippet:
        services:
          _defaults:
            autowire: true
            autoconfigure: true
            # ...
          phpDocumentor\Reflection\Php\:
            resource: '%kernel.project_dir%/vendor/phpdocumentor/reflection/src/phpDocumentor/Reflection/Php'
          # ...
    • Error Message Snippet:
      In FileLoader.php line 182:
      The file "/Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/phpdocumentor/vendor/phpdocumentor/reflection/src/phpDocumentor/Reflection/Php" does not exist in /Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/phpdocumentor/config/reflection.yaml (which is being imported from "/Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/phpdocumentor/config/services.yaml").
      
      In FileLocator.php line 46:
      The file "/Users/mridang/Code/zitadel/client-php/vendor/phpdocumentor/phpdocumentor/vendor/phpdocumentor/reflection/src/phpDocumentor/Reflection/Php" does not exist.
      

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions