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

Troubles namespacing nesbot/carbon #70

Closed
TussendoorHQ opened this issue Jun 23, 2023 · 2 comments
Closed

Troubles namespacing nesbot/carbon #70

TussendoorHQ opened this issue Jun 23, 2023 · 2 comments

Comments

@TussendoorHQ
Copy link

When running the strauss.phar command after composer install all my dependencies get prefixed correctly except nesbot/carbon.

In short:
All classes in the vendor/nesbot/carbon/src directory get prefixed correctly. But the classes in the root vendor/nesbot/carbon directory doesnt and the classes inside vendor/nesbot/carbon/lazy does not get prefixed either.

My composer.json:

{
    "name": "custom/plugin",
    "license": "GPL-2.0-or-later",
    "description": "WordPress plugin developed by Tussendoor.",
    "type": "wordpress-plugin",
    "require": {
        "php": "^8.0",
        "nesbot/carbon": "^2.66.0",
        "illuminate/database": "^8.0.0",
        "twbs/bootstrap": "^5.2.3",
        "fortawesome/font-awesome": "^6.4.0",
        "adbario/php-dot-notation": "^3.3.0",
        "woocommerce/action-scheduler": "^3.4.0",
        "yahnis-elsts/plugin-update-checker": "^4.13"
    },
    "autoload": {
        "psr-4": {
            "Custom\\Namespace\\": "app/"
        },
        "files": [
            "vendor/woocommerce/action-scheduler/action-scheduler.php"
        ],
        "classmap": [
            "vendor"
        ]
    },
    "config": {
        "optimize-autoloader": true,
        "sort-packages": true,
        "platform": {
            "php": "8.0.3"
        }
    },
    "scripts": {
        "post-install-cmd": [
            "sh prefixer.sh"
        ],
        "post-update-cmd": [
            "sh prefixer.sh"
        ]
    },
    "extra": {
        "strauss": {
            "target_directory": "vendor",
            "namespace_prefix": "Custom\\Namespace\\Vendor\\",
            "constant_prefix": "TSD_CUSTOM_VENDOR_",
            "include_modified_date": false,
            "include_author": false,
            "delete_vendor_packages": true,
            "exclude_from_prefix": {
                "packages": [
                    "yahnis-elsts/plugin-update-checker",
                    "woocommerce/action-scheduler"
                ]
            }
        }
    }
}

As you can see I am running a custom shell script after the regular composer commands like install and update. The shell script is looking like this:

#!/bin/bash

printf "\n"
printf "Composer action is completed! Wait for the new actions. \n"
printf "\n"
printf "Starting Strauss to prefix all dependencies \n"

php strauss.phar

printf "\n"
printf "Strauss action is completed! \n"
printf "Dumping the composer autoload to prevent errors. \n"

composer dump-autoload

printf "\n"
printf "Autoload has been dumped. \n"
printf "Cleaning the empty folders in the vendor directory. \n"

find vendor -type d -empty -delete

printf "\n"
printf "All done! \n"

So everything works fine after running the script. The plugin gets loaded correctly and thus I thought everything worked fine :) Except I encountered the following error on a specifc page where I use the Carbon class. This fatal error is showing:

Fatal error:
Uncaught Error: Class "Carbon\AbstractTranslator" not found in /vendor/nesbot/carbon/lazy/Carbon/TranslatorStrongType.php:17

Upon investigation I found that not all classes from vendor/nesbot/carbon are getting prefixed. All classes in the vendor/nesbot/carbon/src directory get prefixed correctly. But the classes in the root vendor/nesbot/carbon directory doesnt and the classes inside vendor/nesbot/carbon/lazy does not get prefixed either. The error is originated from the lazy directory.

Its not a very big directory so I tried prefixing them manually and running composer dump-autoload afterwards. This fixes the issue.

I am wondering if this is a bug or due to misconfiguration on my end.

Thanks again for this project!

@BrianHenryIE
Copy link
Owner

Looks like it doesn't use autoloading for all its classes:

Warning: Ambiguous class resolution, "Carbon\PHPStan\AbstractReflectionMacro" was found in both "/path/to/vendor/nesbot/carbon/lazy/Carbon/PHPStan/AbstractMacroBuiltin.php" and "/path/to/vendor/nesbot/carbon/lazy/Carbon/PHPStan/AbstractMacroStatic.php", the first will be used.
Warning: Ambiguous class resolution, "Carbon\PHPStan\LazyMacro" was found in both "/path/to/vendor/nesbot/carbon/lazy/Carbon/PHPStan/MacroStrongType.php" and "/path/to/vendor/nesbot/carbon/lazy/Carbon/PHPStan/MacroWeakType.php", the first will be used.
Warning: Ambiguous class resolution, "Carbon\MessageFormatter\LazyMessageFormatter" was found in both "/path/to/vendor/nesbot/carbon/lazy/Carbon/MessageFormatter/MessageFormatterMapperStrongType.php" and "/path/to/vendor/nesbot/carbon/lazy/Carbon/MessageFormatter/MessageFormatterMapperWeakType.php", the first will be used.
Warning: Ambiguous class resolution, "Carbon\LazyTranslator" was found in both "/path/to/vendor/nesbot/carbon/lazy/Carbon/TranslatorWeakType.php" and "/path/to/vendor/nesbot/carbon/lazy/Carbon/TranslatorStrongType.php", the first will be used.

briannesbitt/Carbon#2512

Strauss determines which files to copy and prefix by reading the packages' composer.json autoload keys. So since Carbon has omitted those files, Strauss doesn't pick them up. Strauss has an override_autoload setting that allows redefining packages' autoload keys.

Using this as your extra key seems to work:

"extra": {
  "strauss": {
    "target_directory": "vendor",
    "constant_prefix": "TSD_CUSTOM_VENDOR_",
    "include_modified_date": false,
    "include_author": false,
    "exclude_from_prefix": {
      "packages": [
        "yahnis-elsts/plugin-update-checker",
        "woocommerce/action-scheduler"
      ]
    },
    "override_autoload": {
      "nesbot/carbon": {
        "autoload": {
          "psr-4": {
            "Carbon\\": "src/Carbon/"
          }
        },
        "classmap": [
          "lazy"
        ]
      }
    }
  }
}

There is an issue with double-prefixing when using strauss.phar repeatedly. I haven't been using the phar myself (although long term I think it's the better way) but I will fix that sooner or later. Just FYI to expect that!

@TussendoorHQ
Copy link
Author

Thanks @BrianHenryIE this resolved the issue!

I understand that the double-prefixing issue is not present when we use strauss as a dependency. Is there a way to use strauss a a dependency without the issues I experienced with the composer requirement as mentioned in:
#69

If there is a sollution for that then I could prevent deleting the prefixed vendor directory everytime I have to do composer update. I tried a new script on pre-update-cmd where the vendor and composer.lock would get deleted before updating and then triggering composer install. But this pre-update-cmd script gets triggered before composer install as well so that ended up in an infinite loop.

If not then I will delete the vendor directory manually for now.

By the way; using the strauss.phar is a lot faster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants