Reply to thread

WSL2's 9p filesystem driver is faulty: http://github.com/microsoft/WSL/issues/5074


This can cause problems with cross-platform Docker-based devkits.  While this is ultimately a problem that Microsoft needs to fix, there's a quick workaround that XenForo can implement to mitigate issues with cmd.php.  Microsoft hasn't shown any sign of fixing the issue, so it would be helpful to have a workaround for now.


When invoking cmd.php while src is on a bridged volume using p9fs, inodes aren't fully enumerated.  Repros can be a bit finicky, but the file for xf-dev:import has a tendency to be skipped, resulting in xf-dev:import being treated as a nonexistent command.


This is specific to development on Windows; I haven't run into this issue on macOS.


Workaround for XF\Cli\Runner#getValidCommandClasses:

[php]protected function getValidCommandClasses(array $directoryMap)

{

    $classes = [];


    foreach ($directoryMap AS $dir => $baseClass)

    {

        $fullPath = \XF\Util\File::canonicalizePath($dir);

        if (!file_exists($fullPath) || !is_dir($fullPath))

        {

            continue;

        }


        $files = [];

        $dirStack = [];


        for ($currentDir = $fullPath; $currentDir !== null; $currentDir = array_pop($dirStack))

        {

            foreach (scandir($currentDir) AS $baseName)

            {

                if ($baseName === '.' || $baseName === '..')

                {

                    continue;

                }


                $path = $currentDir . \XF::$DS . $baseName;


                if (0 === substr_compare($baseName, '.php', -4, 4))

                {

                    $files[] = $path;

                }

                else if (is_dir($path))

                {

                    $dirStack[] = $path;

                }

            }

        }


        foreach ($files AS $file)

        {

            $localPath = substr($file, strlen($fullPath));

            $localPath = trim(strtr($localPath, '\\', '/'), '/');


            $className = $baseClass . '\\' . strtr($localPath, '/', '\\');

            $className = substr($className, 0, -4);


            if ($this->isValidCommandClass($className))

            {

                $classes[] = $className;

            }

        }

    }


    return $classes;

}[/php]


Back
Top Bottom