Laravel-Lang / common

Easily connect the necessary language packs to the application
https://laravel-lang.com/packages-common.html
MIT License
103 stars 10 forks source link

[Bug]: Package Discover: Argument #1 ($directory) must be of type string, null given #194

Closed werksarztzentrum closed 5 months ago

werksarztzentrum commented 5 months ago

Lang Package Name

laravel-lang/config

Lang Package Version

1.4.0

Laravel Framework Version

11.10

PHP Version

8.2

Dependencies

"require-dev": { "laravel-lang/attributes": "^2.10.7", "laravel-lang/lang": "^15.5.1", "laravel-lang/publisher": "^16.4.0", ... }

Issue description

After upgrading to laravel-lang/config 1.4.0 we will get following error in all projects:

In ModelsData.php line 9:

  LaravelLang\Config\Data\Hidden\ModelsData::__construct(): Argument #1 ($directory) must be of type string, null given, called in /home/just/projects/dev-server/manager/vendor/laravel-lang/config/src/Services/Config.php on line 51  

Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

Steps to reproduce

Steps to reproduce

Upgrading laravel-lang/config (1.2.0 => 1.4.0) with composer update

enrymari commented 5 months ago

Maybe the problem comes from updating laravel-lang/config to 1.4.0? Downgrading laravel-lang/config to 1.3.0 there are no issue.

werksarztzentrum commented 5 months ago

Maybe the problem comes from updating laravel-lang/config to 1.4.0? Downgrading laravel-lang/config to 1.3.0 there are no issue.

I think so, because in the latest release is more included than only a base application path (e.g. hidden models):

https://github.com/Laravel-Lang/config/pull/14/commits/ee262857e480466b67b7edd26421388fa1a76b7c

stephanus-tantiono commented 5 months ago

how to do the downgrade ?

werksarztzentrum commented 5 months ago

how to do the downgrade ?

You can just pin the dependency in your require-dev, e.g:

"require-dev": { "laravel-lang/config": "1.3.0", ... }

andrey-helldar commented 5 months ago

I apologize. I will release a hotfix in the near future.

andrey-helldar commented 5 months ago

The bug has been fixed in version 1.4.1 of laravel-lang/config package.

Once again I apologize for the inconvenience. This was a bug that could not be detected during preliminary testing.

Thank you for your report!

andrey-helldar commented 5 months ago

Maybe the problem comes from updating laravel-lang/config to 1.4.0? Downgrading laravel-lang/config to 1.3.0 there are no issue.

I think so, because in the latest release is more included than only a base application path (e.g. hidden models):

Laravel-Lang/config@ee26285

Configurations have two scopes - shared and hidden.

The shared file can be published to the application for changes while the hidden file contains conditionally technical information that we can override to properly test the package during its development.

The problem was that the composer dumpauto command was trying to build a DTO object before Laravel initialized this configuration file. This is impossible to detect on tests, as they pre-load the information.

gigerIT commented 5 months ago

The bug has been fixed in version 1.4.1 of laravel-lang/config package.

Once again I apologize for the inconvenience. This was a bug that could not be detected during preliminary testing.

Thank you for your report!

I can confirm that running composer update again downloaded laravel-lang/config 1.4.1, which did not throw an error while generating autoload files.

Thank you very much for the quick reaction.

andrey-helldar commented 5 months ago

Information for the future, in case it helps someone.

When installing packages, Laravel calls the Illuminate\Foundation\ComposerScripts::postAutoloadDump service provider registration mechanism.

It in turn registers all dependencies in the map preparation application in alphabetical order.

The error was caused by the fact that the laravel-lang/actions package is alphabetized first and only then the laravel-lang/config package.

The following dependency chain follows:

  1. At initialization Actions requests Publisher;
  2. Publisher accesses the hidden configuration Config;
  3. Config was not initialized at that moment and gave this error.

Since Laravel does not allow to set the priority of service providers during registration, I had to set the default value to avoid this error.

It would seem that what prevents us from adding the LaravelLang\\Config\ServiceProvider call to the composer.json file? But the registration mechanism works strangely. After adding initialization to both Publisher and Actions, the error remains in place.

Backtrace:

Illuminate\Support\Collection {#221
  #items: array:16 [
    0 => "D:\domains\test2.test\vendor\laravel-lang\config\src\Services\Config.php:45"
    1 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:357"
    2 => "D:\domains\test2.test\vendor\laravel-lang\publisher\src\Helpers\Config.php:41"
    3 => "D:\domains\test2.test\vendor\laravel-lang\publisher\src\Plugins\Provider.php:53"
    4 => "D:\domains\test2.test\vendor\laravel-lang\publisher\src\Plugins\Provider.php:42"
    5 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:868"
    6 => "D:\domains\test2.test\vendor\laravel-lang\actions\src\ServiceProvider.php:15"
    7 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:868"
    8 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\ProviderRepository.php:75"
    9 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:843"
    10 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\RegisterProviders.php:36"
    11 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:316"
    12 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:470"
    13 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:194"
    14 => "D:\domains\test2.test\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:1198"
    15 => "D:\domains\test2.test\artisan:13"
  ]
  #escapeWhenCastingToString: false
}
"extra": {
    "laravel": {
        "providers": [
            "LaravelLang\\Config\\ServiceProvider",
            "LaravelLang\\Actions\\ServiceProvider"
        ]
    }
}

Since in applications using this path, the variable cannot be null, so as not to get code double-checking the value, the only working solution was to pass a fallback value.

But there is another way - add a call $this->app->register(\LaravelLang\Config\ServiceProvider::class); to the Actions, Attributes, ..., Publisher,... packages.

But this is already a utopia.