Error on Artisan commands when updating Composer dependencies - php

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/"
}
}
}

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

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

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.

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/"
}
}
}

Run This
composer install --ignore-platform-reqs

Related

How to fix "Script #php artisan package:discover returned with error code 1" + "Class not found" without internet connection?

I am working on a legacy Laravel 6 app which is isolated from the rest of the system without internet connection, and when I try to run composer dump-autoload I get:
In ProviderRepository.php line 208: Class
'Facade\Ignition\IgnitionServiceProvider' not found
Script #php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1
So I can't do what's described in this post:
Laravel with App Engine Standard Class 'Facade\Ignition\IgnitionServiceProvider' not found
Update #1: I added the missing class to the dont-discover array in composer.json, then it showed another class missing, so I started adding them one-by-one. Apparently the following 3 packages are "missing" (even though their files are there):
"facade/ignition", "laravel/ui", "nunomaduro/collision".
When added all these 3 to the dont-discover array, I was successfully able to run composer dump-autoload:
"extra": {
"laravel": {
"dont-discover": ["facade/ignition", "laravel/ui", "nunomaduro/collision"]
}
}
But still, I want to know if I can fix the issue with these 3 packages
Can I fix it without internet connection? Anything I can try to do manually?
Update #2:
I saw a comment on another post here suggesting moving the packages from require-dev to require. I did it, and it worked!
https://stackoverflow.com/a/59369455/18178584
In the same post, someone suggested it might be related to a bug when updating from composer 1.x to 2.x:
https://stackoverflow.com/a/67847239/18178584
But since I don't know exactly what happened here, which one of the above can be the cause? And, since the first solution solved it for me, is it safe to leave these 3 packages in require instead of require-dev?
Try to refresh your Laravel project, like:
composer run refresh
But for that to work, you first need to implement refresh script in composer.json file, like:
{
// ...
"scripts": {
"refresh": [
"#composer dump-autoload --no-scripts",
"#php artisan config:clear",
"#composer run post-autoload-dump --verbose",
"#php artisan cache:clear",
"#php artisan clear-compiled",
"#php artisan view:clear",
"#php artisan route:clear"
],
// ...
}
}
Also, as mentioned in comments, ensure important packages are in require section of composer.json (instead of require-dev).
Only unit-test and/or lint purpose packages should be in require-dev.
Details
Normally composer dump-autoload is enough, but sometimes post-autoload-dump uses cached class, hence php artisan config:clear needs to run first, but "config:clear" may crash if dump-autoload is not done yet.
Solution? Like above, use --no-scripts and trigger post-autoload-dump later manually ;-)
(Well not "manually", I do it all automatically, but you get the idea.)

Class 'Predis\Client' not found loop

I tried all the answers here, but no luck.
The weird part is that if I simply run the command composer update I get this:
forge#development:~/default$ composer update
Cannot create cache directory /home/forge/.composer/cache/repo/https---packagist.org/, or directory is not writable. Proceeding without cache
Cannot create cache directory /home/forge/.composer/cache/files/, or directory is not writable. Proceeding without cache
> php artisan clear-compiled
The compiled class file has been removed.
> php artisan ide-helper:generate
[Symfony\Component\Debug\Exception\FatalThrowableError]
Class 'Predis\Client' not found
Running just php artisan ide-helper:generate gives me
[Symfony\Component\Debug\Exception\FatalThrowableError]
Class 'Predis\Client' not found
Deleting the entire vendor directory then running composer install gives me this output.
This is my composer.lock and my composer.json files.
Running the command composer require predis/predis also returns the same error:
> php artisan clear-compiled
The compiled class file has been removed.
> php artisan ide-helper:generate
[Symfony\Component\Debug\Exception\FatalThrowableError]
Class 'Predis\Client' not found
Do you have any ideas?
Update
This is a work around, but not a root solution. Running:
composer update --no-scripts
that will skip the
"scripts": {
"post-install-cmd": [
..
],
"pre-update-cmd": [
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan ide-helper:models -N",
"php artisan optimize"
],
part, which is good enough for now. This indeed seems like a bug with laravel-ide-helper, reporting bug soon.
From the laravel-ide-helper readme:
When you receive a FatalException about a class that is not found, check your config (for example .... remove Redis ServiceProvider when you don't use it)
So, remove RedisServiceProvider and Redis alias from config/app.php if you don't use Redis. Then clear config cache with php artisan config:clear.

Laravel 5: Installing ide helper for Netbeans

Im trying to implement Laravel ide helper: barryvdh/laravel-ide-helper .
Tried downloading gist, putting it in root folder of my project but it did not work.
Also tried installing it with composer and adding Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class in the config/app.php file.
Both methods didnt work even when I restarted netbeans.
Using Ubuntu and Laravel 5.1.20
Anyone have idea what im doing wrong?
Installing it with composer isn't enough, you still have to generate it with this command:
php artisan ide-helper:generate
Better yet add it as a post-update-cmd to composer.json:
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
]
(the other 2 should already be there)
Then whenever you run composer update it will automatically generate a new IDE helper file. Finally, don't forget to add _ide_helper.php to your .gitignore file

Why is Composer unable to locate artisan when running the "composer install" command?

I am using windows 7 and trying to install laravel 4.2 using composer. My development environment is EasyPHP, but based on the research I have done, that is not the problem.
Every time I try to create a new laravel project, called "testapp", by running this command in my projects directory:
composer create-project laravel/laravel testapp --prefer-dist
.., the installation is successful up until the point where composer tries to generate the "autoload" files, outputting these lines:
Generating autoload files
Could not open input file: artisan
Script php artisan clear-compiled handling the post-install-cmd event returned with an error
[RuntimeException]
Error Output:
If I then navigate to the new folder called testapp created in my projects directory, and run
composer update
or
composer install
I get the same error at the end.
Although composer doesn't seem to be able to run any php artisan command, by navigating to my testapp folder and running:
php artisan {any command here}
I can accomplish any artisan command I want.
After doing some research, I found that the problem is with composer itself. Composer does not know how to find the artisan file.
One suggestion was that I edit the composer.json file so that artisan would be defined by an absolute path rather than a relative path. So I changed this:
"scripts": {
"post-install-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-create-project-cmd": [
"php artisan key:generate"
]
},
to this:
"scripts": {
"post-install-cmd": [
"php C:\\Program Files (x86)\\EasyPHP-DevServer-14.1VC11\\data\\localweb\\projects\\testapp\\artisan clear-compiled",
"php C:\\Program Files (x86)\\EasyPHP-DevServer-14.1VC11\\data\\localweb\\projects\\testapp\\artisan optimize"
],
"post-update-cmd": [
"php C:\\Program Files (x86)\\EasyPHP-DevServer-14.1VC11\\data\\localweb\\projects\\testapp\\artisan clear-compiled",
"php C:\\Program Files (x86)\\EasyPHP-DevServer-14.1VC11\\data\\localweb\\projects\\testapp\\artisan optimize"
],
"post-create-project-cmd": [
"php C:\\Program Files (x86)\\EasyPHP-DevServer-14.1VC11\\data\\localweb\\projects\\testapp\\artisan key:generate"
]
},
within the composer.json file in my testapp folder. Now, when running
composer install
I got this output in the command prompt:
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json.
You may be getting outdated dependencies. Run update to update them.
Nothing to install or update
Generating autoload files
Script php C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\proje
cts\testapp\artisan clear-compiled handling the post-install-cmd event returned
with an error
[RuntimeException]
Error Output:
install [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--no-p
lugins] [--no-custom-installers] [--no-scripts] [--no-progress] [-v|vv|vvv|--ver
bose] [-o|--optimize-autoloader] [packages1] ... [packagesN]
Although I first thought that this output meant that changing the composer.json would not solve the problem, I was amazed to find that changing the composer.json worked when the absolute path contained no spaces.
For example. I went to C:\Users\AlexLeung\Desktop, ran
composer create-project laravel/laravel desktestapp --prefer-dist
got the initial error, then updated the composer.json in the new desktestapp folder to look like
"scripts": {
"post-install-cmd": [
"php C:\\Users\\AlexLeung\\Desktop\\desktestapp\\artisan clear-compiled",
"php C:\\Users\\AlexLeung\\Desktop\\desktestapp\\artisan optimize"
],
"post-update-cmd": [
"php C:\\Users\\AlexLeung\\Desktop\\desktestapp\\artisan clear-compiled",
"php C:\\Users\\AlexLeung\\Desktop\\desktestapp\\artisan optimize"
],
"post-create-project-cmd": [
"php C:\\Users\\AlexLeung\\Desktop\\desktestapp\\artisan key:generate"
]
},
, and running
composer install
was then successful. Although this shows I can install laravel if I just install it on a path with no spaces, I need to be able to install it in places under the "Program Files (x86)" directory since that is where EasyPHP, and its Apache web server root, are located. In trying to get the absolute path to work with spaces, I have tried using underscores, which ends up pointing to the wrong path, and \u0020, which generates the same error.
So the question remains:
How can I get composer to recognize the artisan file within the newly created testapp folder?
A set of resulting questions if the first can't be answered:
1. Is there a way to get composer to recognize the artisan file without me needing to change the composer.json to iunclude an absolute path for artisan?
2. Should I even be concerned about having the autoload files generated? (is it even necessary)
3. Would it be okay if I just moved my projects to the desktop (or any other path without spaces) anytime I needed to run composer update or install?
Overall I would like to have a complete installation of laravel and be able to use the convenient composer commands whenever I need to.
Maybe your issue has to do with some kind of permissions because you are trying to run commands inside "C:\Program Files (x86)". Try to deactivate UAC and see if that works.
Also try to run php artisan clear-compiled from the command line. It may not even be an issue with composer but with the PHP path. Verify that your Windows PATH variable knows where your php.exe is located.
I've just tested a clean install in a folder called "C:\MyPrograms\Some kind of folder\" and composer runs as expected, so it's may have nothing to do with spaces.
You can get composer to recognize php artisan, one way or another. My personal experience tells me that having developer tools installed in C:\Program Files is not a good idea because you will keep getting unexpected behaviors. I advice you to instal PHP, Apache, EasyPHP & whatever you need in a new folder (like "C:\MyPrograms").
Anyhow, even if you have PHP and Apache installed in the default program files folder, you can always set your Document Root of Apache to another location and this may also solve your issue.
As for your other questions:
2) Yes, it really is necessary. The autoload files (will be located in vendor/composer/) enable you to work with namespaces and to work with your own classes and never to include() or require() because it will be done by Laravel automatically.
3) I guess you could do that and it will work. But the hassle of moving your entire project every time you need a composer update seems to much trouble and wasted time.
I think you found a bug in Composer.
This line probably is supposed to make the commands used in the hooks executable:
https://github.com/composer/composer/blob/a8adbfeb9fc7861deade782938222714168a22a8/src/Composer/Command/RunScriptCommand.php#L89
I suspect that the result of realpath() with the binary directory will return the correct path, but including spaces. putenv() looks like operating directly on the shell, with it's parameter being "PATH=C:\Path with spaces\somewhere;C:\PreviousPaths\" - this might not be working on Windows.
You should add an issue on Github to get this fixed.
From experience, lots of software is not well prepared to deal with spaces in paths. I recently had to rename all my Jenkins job names because "job name === workspace directory name", and the backup module was acting up on the spaces.

Laravel "Class not found..." when running artisan commands (but not composer)

I have an app I've been working on for a few weeks; I'm using Vagrant+Homestead for local development, and Forge+Linode for a staging environment; until a few days ago, my workflow was working fine, however now when the deployment script runs in Forge (in particular composer install), it gets an error:
[RuntimeException]
Error Output: PHP Fatal error: Class 'Reputationhub\ReputationhubServiceProvider' not found in /home/vagrant/Sites/reputationhu
b/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php on line 157
PHP Stack trace:
PHP 1. {main}() /home/vagrant/Sites/reputationhub/artisan:0
PHP 2. require_once() /home/vagrant/Sites/reputationhub/artisan:30
PHP 3. require() /home/vagrant/Sites/reputationhub/bootstrap/start.php:60
PHP 4. Illuminate\Foundation\ProviderRepository->load() /home/vagrant/Sites/reputationhub/vendor/laravel/framework/src/Illumin
ate/Foundation/start.php:210
PHP 5. Illuminate\Foundation\ProviderRepository->compileManifest() /home/vagrant/Sites/reputationhub/vendor/laravel/framework/
src/Illuminate/Foundation/ProviderRepository.php:57
PHP 6. Illuminate\Foundation\ProviderRepository->createProvider() /home/vagrant/Sites/reputationhub/vendor/laravel/framework/s
rc/Illuminate/Foundation/ProviderRepository.php:121
It is actually the subcommand php artisan clear-compiled that composer runs afterward that is failing. If I run that on it's own, same problem. Running composer install --no-script runs ok.
When I look at vendor/composer/autoload_classmap.php, it's missing all sorts of things, and is only a few lines long (it's normally much larger), so whatever Laravel is doing is not properly finding the correct classes.
The odd thing is that running composer dump-autoload -o seems to fix it; the autoload_classmap.php file finds everything, and the app runs fine, until php artisan ... tries to do anything, then it breaks the app.
The end result is that the Forge deployment is broken; I can manually jump onto the server and run composer dump-autoload -o to fix it, but that seems wrong.
I think I've been rather thorough about researching solutions, but so far I can't find anything, so any help would be appreciated.
UPDATE: further clarification
This is Laravel 4.2.
My composer.json autoload section looks like this:
...
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4": {
"Reputationhub\\": "app/"
},
"files": []
},
...
The provider has been added to the "providers" array in app.php like this:
...
'Reputationhub\ReputationhubServiceProvider',
...
And my provider file (at app/Reputationhub/ReputationhubServiceProvider.php) looks like this:
<?php namespace Reputationhub;
use Reputationhub\EventSubscribers\MetricsEventSubscriber;
use Illuminate\Support\ServiceProvider;
class ReputationhubServiceProvider extends ServiceProvider {
...
}
Update 2: more testing
Not sure what it does, but composer install seems to do something bad that breaks the app. To fix it, rather than using composer install in the deployment script (which will subsequently call php artisan clear-compiled and php artisan optimize, both of which will throw errors), if I use this it will repair itself:
...
composer install --no-scripts
composer dump-autoload -o
php artisan dump-autoload
...

Categories