Error on Artisan commands when updating Composer d

2020-06-09 05:02发布

问题:

I am developing a library for Laravel which contains a service provider. I have added this library to another project's composer.json file.

The composer.json file for the "main project" contains the following scripts.

"scripts": {
    "post-root-package-install": [
        "php -r \"copy('.env.example', '.env');\""
    ],
    "post-create-project-cmd": [
        "php artisan key:generate"
    ],
    "post-install-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize"
    ],
    "pre-update-cmd": [
        "php artisan clear-compiled"
    ],
    "post-update-cmd": [
        "php artisan optimize"
    ]
},

I can include the library dependency just fine, except for one thing; the pre-update-cmd and post-update-cmd scripts throw an error and cause me a lot of headaches. When running sudo composer update to update the dependencies, I get the following error.

$ sudo composer update
> php artisan clear-compiled
PHP Fatal error:  Class 'MyName\MyProject\MyAwesomeServiceProvider' not found in /Users/Me/dev/MyProject/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php on line 146


  [Symfony\Component\Debug\Exception\FatalErrorException]                                              
  Class 'MyName\MyProject\MyAwesomeServiceProvider' not found  


Script php artisan clear-compiled handling the pre-update-cmd event returned with an error


  [RuntimeException]                                                                                         
  Error Output: PHP Fatal error:  Class 'MyName\MyProject\MyAwesomeServiceProvider' 
  not found in /Users/Me/dev/MyProject/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php on line 146

I have Googled around quite a bit before asking this question and read through pretty much everything related that I could find. Apparently this is a known issue that has been discussed in multiple GitHub issues within the Laravel repository. However, I have yet to find a workaround, even after having tried multiple ones.

It appears that the issue is that the Artisan commands bootstrap Laravel, which leads to an error because the service provider is not available at this point - or something like that. Moving the clear-compiled command to post-update-cmd causes the same error, which surprises me a bit because I thought the service provider would be available at this point.

The only thing that works for me is to manually comment out the line that includes the service provider in config/app.php before running composer update and then adding it again afterwards. I have been doing this for a few hours, and it is already bothering the heck out of me, and I really cannot believe that this issue is around.

Does anyone know how to work around this error so that I don't get the error that my service provider is not found when updating the Composer dependencies for my project?

EDIT: Here is the composer.json file for the library.

{
    "name": "my-name/my-project",
    "type": "library",
    "authors": [
        {
            "name": "My Name",
            "email": "test@example.com"
        }
    ],
    "require": {
        "php": ">=5.5.0",
        "laravel/framework": "~5.2"
    },
    "autoload": {
        "classmap": [],
        "psr-4": {
            "MyName\\MyProject\\": "src/"
        }
    }
}

回答1:

Edit

This issue has finally been resolved as of laravel/framework:v5.2.25 and laravel/laravel:v5.2.27, and backported to laravel/framework:v5.1.33 and laravel/laravel:v5.1.33.

This fix includes a change to the Laravel application (laravel/laravel), in addition to the Laravel Framework (laravel/framework). To implement, you will need to:

1) Update the scripts section of your composer.json file to match that in the laravel/laravel package. Specifically:

  • remove the pre-update-cmd section
  • in the post-install-cmd section, replace "php artisan clear-compiled" with "Illuminate\\Foundation\\ComposerScripts::postInstall"
  • in the post-update-cmd section, replace "php artisan clear-compiled" with "Illuminate\\Foundation\\ComposerScripts::postUpdate"

2) Once you have updated your composer.json, run a composer update. If you only want to update the framework, you can run composer update laravel/framework.


Original

After looking over the Github issue you posted in the comments, as well as the related issues, you may be in for a bit of a wait. Taylor would like to put a script in vendor/bin and change composer.json to run that, but it looks like they are waiting for a PR from the community, and won't actually implement this themselves.

You haven't done anything wrong; your autoloading is setup correctly. The issue is with Laravel right now.

Moving the command to the post-update-cmd script doesn't work because artisan will always try to load the cache files when they exist. When running the clear-compiled command, artisan loads the cache files (part of startup) before it ever tries to delete them.

Your best bet is to manually delete the cache files before artisan gets run. And, you need to do it outside of Laravel/Artisan. So, you can manually delete the files, or you can create a little script to do it and add that to your composer.json file (for your main project, not your package).

Files to delete:

  • Laravel 5.2:
    bootstrap/cache/compiled.php
    bootstrap/cache/services.php
  • Laravel 5.1:
    bootstrap/cache/compiled.php
    bootstrap/cache/services.json
  • Laravel 5.0:
    vendor/compiled.php
    storage/framework/compiled.php
    vendor/services.json
    storage/framework/services.json


回答2:

When using composer install or composer update you can use --no-scripts option to skips execution of scripts defined in composer.json.

e. g.: composer update --no-scripts.

Source: https://getcomposer.org/doc/03-cli.md#install



回答3:

It looks like you're simply not including your ServiceProvider. Put this in your root project's composer.json:

{
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "MyName\\MyProject\\": "../relative/path/to/serviceprovider/"
        }
    }
}


回答4:

composer update --no-scripts

this command will ignore command defined in composer.json,otherwise it will excute laravel command which will check if serviceProvider is loaded.



回答5:

Run This

composer install --ignore-platform-reqs