coenjacobs / mozart

Developers tool for WordPress plugins: Wraps all your projects dependencies in your own namespace, in order to prevent conflicts with other plugins loading the same dependencies in different versions.
https://coenjacobs.me/projects/mozart/
MIT License
434 stars 55 forks source link

Doesn't seem to namespace Mustache #99

Open Screenfeed opened 3 years ago

Screenfeed commented 3 years ago

Hello, I'm trying to use Mozart 0.6.0-beta-3 with Mustache and other packages, but Mustache is the only one that doesn't seem to be namespaced. Fair warning, it's the first time I use Mozart so it can be a misconfiguration/misunderstanding on my side.

composer.json

{
    //...
    "require": {
        "php": ">=5.6.0",
        "league/container": "^2.4",
        "mustache/mustache": "^2.13",
        "composer/installers": "~1.0"
    },
    "require-dev": {
        "php": "^7.1",
        "automattic/phpcs-neutron-standard": "*",
        "coenjacobs/mozart": "0.6.0-beta-3",
        "dangoodman/composer-for-wordpress": "^2.0",
        "dealerdirect/phpcodesniffer-composer-installer": "*",
        "phpcompatibility/phpcompatibility-wp": "*",
        "phpmetrics/phpmetrics": "*",
        "roave/security-advisories": "dev-master",
        "squizlabs/php_codesniffer": "*",
        "szepeviktor/phpstan-wordpress": "*",
        "wp-coding-standards/wpcs": "*"
    },
    "autoload": {
        "psr-4": {
            "Screenfeed\\AdminbarTools\\": "src/classes/"
        },
        "classmap": [
            "src/classmap"
        ]
    },
    "extra": {
        "mozart": {
            "dep_namespace": "Screenfeed\\AdminbarTools\\Dependencies\\",
            "dep_directory": "/src/classes/Dependencies/",
            "classmap_directory": "/src/classmap/dependencies/",
            "classmap_prefix": "ScreenfeedAdminbarTools_"
        }
    },
    "scripts": {
        "post-install-cmd": [
            "\"vendor/bin/mozart\" compose",
            "composer dump-autoload"
        ],
        "post-update-cmd": [
            "\"vendor/bin/mozart\" compose",
            "composer dump-autoload"
        ]
    }
}

composer.lock

        {
            "name": "mustache/mustache",
            "version": "v2.13.0",
            //...
            "require": {
                "php": ">=5.2.4"
            },
            "require-dev": {
                "friendsofphp/php-cs-fixer": "~1.11",
                "phpunit/phpunit": "~3.7|~4.0|~5.0"
            },
            "type": "library",
            "autoload": {
                "psr-0": {
                    "Mustache": "src/"
                }
            },
            /...
        },

Taking a look at my code the following classes are not found:

use Screenfeed\AdminbarTools\Dependencies\Mustache_Engine;
use Screenfeed\AdminbarTools\Dependencies\Mustache_Loader_FilesystemLoader;

While this one is:

use Screenfeed\AdminbarTools\Dependencies\League\Container\Container;

Then if I look at Mustache's files, they are moved to the right folder but no namespaces: src/classes/Dependencies/Mustache/Engine.php

<?php

/*
 * This file is part of Mustache.php.
 *
 * ...
 */

/**
 * A Mustache implementation in PHP.
 *
 * ...
 */
class Mustache_Engine
{

src/classes/Dependencies/Mustache/Loader/FilesystemLoader.php

<?php

/*
 * This file is part of Mustache.php.
 *
 * ...
 */

/**
 * Mustache Template filesystem Loader implementation.
 *
 * ...
 */
class Mustache_Loader_FilesystemLoader implements Mustache_Loader
{

Finally, I managed to prefix the classes by using a classmap:

"override_autoload": {
    "mustache/mustache": {
        "classmap": [
            "src/"
        ]
    }
}

Did I miss something? Thanks.

BrianHenryIE commented 3 years ago

I found a tool to convert from PSR-0 to PSR-4: sdrobov/autopsr4.

It's definitely beta software but interesting – in the same arena as Mozart.

I played around with it and the following composer.json should work for you:

{
  "repositories": [
    {
      "url": "https://github.com/sdrobov/autopsr4",
      "type": "git"
    }
  ],
  "require": {
    "php": ">=5.6.0",
    "league/container": "^2.4",
    "mustache/mustache": "^2.13",
    "composer/installers": "~1.0"
  },
  "require-dev": {
    "coenjacobs/mozart": "0.6.0-beta-3",
    "sdrobov/autopsr4": "dev-master"
  },
  "extra": {
    "mozart": {
      "dep_namespace": "Screenfeed\\AdminbarTools\\Dependencies\\",
      "dep_directory": "/src/classes/Dependencies/",
      "classmap_directory": "/src/classmap/dependencies/",
      "classmap_prefix": "ScreenfeedAdminbarTools_"
    }
  },
  "scripts": {
    "convert-mustache-to-psr4": [
      "php -r 'require_once  __DIR__  .  \"/vendor/autoload.php\";  chdir(\"vendor/mustache/mustache/src/\");  use  AutoPsr4\\Parser;  use  AutoPsr4\\Replacer;  use  AutoPsr4\\UsageFinder;  class  Mustache_Replacer  extends  AutoPsr4\\App  {  public  function  run($argv)  {  $parser  =  new  Parser(\"Mustache\",  \"Mustache\");  $parser->parse();  $usageFinder  =  new  UsageFinder($parser->getFiles(),  $parser->getClasses());  $usageFinder->findUsages();  $replacer  =  new  Replacer($usageFinder->getFiles());  $replacer->replace();  }  };  (new  Mustache_Replacer())->run(array());' "
    ],
    "post-install-cmd": [
      "@convert-mustache-to-psr4",
      "\"vendor/bin/mozart\" compose",
      "composer dump-autoload"
    ],
    "post-update-cmd": [
      "@convert-mustache-to-psr4",
      "\"vendor/bin/mozart\" compose",
      "composer dump-autoload"
    ]
  }
}

The php code in there is because running autopsr4 required being in the correct working directory and having the correct arguments passed via the command line. A little refactoring, some error handling and a vendor/bin script could have it running nicely in Composer scripts.

<?php
require_once __DIR__ . "/vendor/autoload.php";
chdir("vendor/mustache/mustache/src/");

use AutoPsr4\Parser;
use AutoPsr4\Replacer;
use AutoPsr4\UsageFinder;

class Mustache_Replacer extends AutoPsr4\App {
    public function run($argv) {

        $parser = new Parser("Mustache", "Mustache");
        $parser->parse();

        $usageFinder = new UsageFinder($parser->getFiles(), $parser->getClasses());
        $usageFinder->findUsages();

        $replacer = new Replacer($usageFinder->getFiles());
        $replacer->replace();
    }
};
(new Mustache_Replacer())->run(array());
Screenfeed commented 3 years ago

Thank you @BrianHenryIE, and sorry for the late answer.

I tried to use AutoPsr4 and it almost worked. The main issue comes from Mustach's Exception classes, like this one:

class Mustache_Exception_InvalidArgumentException extends InvalidArgumentException implements Mustache_Exception
{

Once all the prefixes removed and namespaces added, it becomes:

namespace Screenfeed\AdminbarTools\Dependencies\Mustache\Exception;

use Screenfeed\AdminbarTools\Dependencies\Mustache\Exception;

class InvalidArgumentException extends InvalidArgumentException implements Exception
{

This obviously leads to a fatal error.

Even after manually editing the 3 classes that have this issue, then:

PHP Fatal error:  Uncaught Error: Class '__Mustache_a43d8d63357a090f4d90df06cc37cec7' not found in /sf-adminbar-tools/src/classes/Dependencies/Mustache/Engine.php:764

That's too much things to fix imho, so I guess I'll stick with the classmap. Anyway, thanks for your help :)