Игнорировать пользовательскую команду Laravel Artisan на производстве - PullRequest
0 голосов
/ 25 января 2019

Я написал собственную команду Artisan (назовем ее MyDusk.php), которая расширяет / абстрагирует некоторые функциональные возможности основной команды Dusk.

Эта пользовательская команда расширяет Laravel\Dusk\Console\DuskCommand из пакета Dusk.

Проблема в том, что на производстве не установлен пакет Dusk (он находится под require-dev в composer.json)

Таким образом, когда composer генерирует свои файлы автозагрузки на производстве, он выдает ошибку при достижении MyDusk.php, потому что не может найти Laravel\Dusk\Console\DuskCommand.

PHP Fatal error:  Class 'Laravel\Dusk\Console\DuskCommand' not found in app/Console/Commands/Dusk.php on line 10

In Dusk.php line 10:

  Class 'Laravel\Dusk\Console\DuskCommand' not found  

Я попытался переместить пакет Dusk на require, чтобы он был доступен на производстве (не знаю, насколько я знаю), но в основном поставщике услуг Dusk есть строка, которая выдает исключение при запуске на производстве, предотвращая это:

# From: vendor/laravel/dusk/src/DuskServiceProvider.php
if ($this->app->environment('production')) {
    throw new Exception('It is unsafe to run Dusk in production.');
}

Я пытаюсь найти наиболее элегантное решение, позволяющее моей настраиваемой команде Dusk быть частью приложения и доступной локально, не создавая ошибок при работе.

Одна идея: написать мою команду Dusk как ее собственный пакет, это также только в require-dev.

Есть еще идеи?

1 Ответ

0 голосов
/ 25 января 2019

Я только что посмотрел на API, вы могли бы сделать это:

Вы можете переместить вашу команду на App\Console\Commmands\Local\DuskCommand.php.

По умолчанию, если вы проверяете метод commands() в Ядре, он загружает только команды, найденные в App\Console\Commands.Это не будет включать подкаталоги.

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $this->load(__DIR__.'/Commands');

    require base_path('routes/console.php');
}

Это метод по умолчанию commands().Вы можете переключить эту реализацию на следующую:

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
    $paths = [
        __DIR__ . '/Commands'
    ]; 

    if(app()->environment('local')) {
        $paths[] = __DIR__ . '/Commands/Local';
    }

    $this->load($paths);

    require base_path('routes/console.php');
}

Итак, локально мы также будем загружать команды, основанные на App\Console\Commands\Local.

По общему признанию, я не пробовал это сам, но я предполагаю, что это должно работать.

Редактировать: я попробовал, и, кажется, работает нормально.Я думал, я постараюсь объяснить это немного больше.По сути, после выполнения composer dump-autoload Laravel прослушивает это событие и выполняет две вещи:

"post-autoload-dump": [
    "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
    "@php artisan package:discover --ansi"
]

Вторая попытка выполнить команду автоматического обнаружения пакетов, и именно здесь она не будет выполнена.Исполняемый файл Artisan фактически загружает приложение с помощью Console Kernel.

$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);

$status = $kernel->handle(
    $input = new Symfony\Component\Console\Input\ArgvInput,
    new Symfony\Component\Console\Output\ConsoleOutput
);

При разрешении Ядра он также попытается загрузить необходимые Команды, чтобы они были доступны Artisan, и именно здесь он терпит неудачу.

Однако, например,Я упоминал выше, что если вы загружаете только те команды, которые вам нужны, вы не столкнетесь с этой проблемой.

...