Que tal automatizar tarefas com Artisan? #1
Tags: laravel, php, beginners
Published: 2022-08-26 15:59:00

Um dos melhores recursos que o framework Laravel nos proporciona é o **Artisan**.

**Artisan** é uma interface de linha de comando disponível a partir do diretório raiz da aplicação, nos auxiliando a realizar diversas tarefas dentro do projeto.

Para obter uma lista dos comandos disponíveis, basta acessar o terminal e digitar o seguinte:


```php
php artisan list
```

A grande maioria dos desenvolvedores habituados com o framework Laravel, alguns comandos são bem comuns. Por exemplo, criar uma migração:

```php
php artisan make:migration <nome_da_migracao>
```

Ou talvez uma controller:

```php
php artisan make:controller <nome_da_controller>
```

Alguns desses comandos trazem opções que agilizam a criação de outras classes de uma única vez. :open_mouth:

Quer criar um modelo e ao mesmo tempo a migração:question:

```php
php artisan make:model <nome_do_modelo> -m
```

Perceba que ao adicionar o parâmetro opcional '-m' o artisan é instruído a criar também um arquivo de migração para o modelo.

Para obter a lista de todas as opções para o comando `make:model` informamos o seguinte:

```php
php artisan help make:model
```

Todos os comandos disponíveis no projeto, incluindo descrições, argumentos e opções, podem ser exportados para `txt`, `xml`, `json `ou `md`. Basta adicionar a opção `--format=<formato>`. Por exemplo, se quiséssemos mostrar a ajuda em formato json para o comando citado logo acima, seria esta a instrução a ser informada no terminal:

```php
php artisan help make:model --format=json
```
E esta, a saída: :point_down:

```json
{"name":"make:model","description":"Create a new Eloquent model class","usage":["make:model [-a|--all] [-c|--controller] [-f|--factory] [--force] [-m|--migration] [--morph-pivot] [--policy] [-s|--seed] [-p|--pivot] [-r|--resource] [--api] [-R|--requests] [--test] [--pest] [--] <name>"],"help":"Create a new Eloquent model class","definition":{"arguments":{"name":{"name":"name","is_required":true,"is_array":false,"description":"The name of the class","default":null}},"options":{"all":{"name":"--all","shortcut":"-a","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Generate a migration, seeder, factory, policy, resource controller, and form request classes for the model","default":false},"controller":{"name":"--controller","shortcut":"-c","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create a new controller for the model","default":false},"factory":{"name":"--factory","shortcut":"-f","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create a new factory for the model","default":false},"force":{"name":"--force","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create the class even if the model already exists","default":false},"migration":{"name":"--migration","shortcut":"-m","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create a new migration file for the model","default":false},"morph-pivot":{"name":"--morph-pivot","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Indicates if the generated model should be a custom polymorphic intermediate table model","default":false},"policy":{"name":"--policy","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create a new policy for the model","default":false},"seed":{"name":"--seed","shortcut":"-s","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create a new seeder for the model","default":false},"pivot":{"name":"--pivot","shortcut":"-p","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Indicates if the generated model should be a custom intermediate table model","default":false},"resource":{"name":"--resource","shortcut":"-r","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Indicates if the generated controller should be a resource controller","default":false},"api":{"name":"--api","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Indicates if the generated controller should be an API resource controller","default":false},"requests":{"name":"--requests","shortcut":"-R","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Create new form request classes and use them in the resource controller","default":false},"test":{"name":"--test","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Generate an accompanying PHPUnit test for the Model","default":false},"pest":{"name":"--pest","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Generate an accompanying Pest test for the Model","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display help for the given command. When no command is given display help for the <info>list<\/info> command","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force (or disable --no-ansi) ANSI output","default":null},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Negate the \"--ansi\" option","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false},"env":{"name":"--env","shortcut":"","accept_value":true,"is_value_required":false,"is_multiple":false,"description":"The environment the command should run under","default":null}}},"hidden":false}
```


:warning: Alguns comandos exigirão que determinadas bibliotecas estejam instaladas na aplicação, como [Laravel Breeze](https://laravel.com/docs/9.x/starter-kits#laravel-breeze) por exemplo.

---

### Criar comandos personalizados

Durante o processo de desenvolvimento é comum repetirmos diversas ações, principalmente no início em que muitas configurações precisam ser feitas.:sob:

Para tentar amenizar em partes esse sofrimento o framework Laravel possibilita criarmos nossos próprios comandos afim de aumentarmos a produtividade através da redução de tarefas repetitivas. :clap:

Mas antes de começar, que tal dar uma olhada na lista de opções para criação de comandos personalizados:question:

Para isso vamos novamente acessar o terminal no diretório raiz da aplicação e digitar o seguinte:

```php
php artisan help make:command
```

:point_down:

![Make commands help](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jz39p0rkzzono85rej9o.jpg)

Perceba que todos os comandos possuem uma estrutura comum: 

* **description**: descrição do que o comando faz
* **usage**: como o comando deve ser executado
* **arguments**: argumentos para executar o comando
* **options**: opções deste comando

---

Chega de teoria e vamos para a parte prática. :+1:

Acessando novamente o terminal no diretório raiz da aplicação, digite o seguinte:

```php
php artisan make:command MyCommand
```

Com o editor de código de sua preferência, abra a pasta do projeto Laravel para termos acesso a toda sua estrutura.

Repare que uma nova classe foi criada no diretório _\app\Console\Commands\_ e ela extende de _\Illuminate\Console\Command.php_.

:point_down:

```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class MyCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        return 0;
    }
}
```

---

### Explicando o código

> `protected $signature`

Esta propriedade protegida diz ao Artisan como executar o comando que criamos. Veja que está com o valor `'command:name'`. Então para executar este comando no terminal precisaremos digitar o seguinte:

```php
php artisan command:name
```

Se fizermos isto neste momento nada será retornado porque devemos codificar o método `handle()`. Mas já já chegamos nele.:smiley:

---

> `protected $description`

O conteúdo desta propriedade será mostrado quando buscarmos informações sobre os comandos. Por exemplo, se digitarmos no termimal a seguinte instrução:

```php
php artisan help command:name
```

Este será o resultado (em destaque):

:point_down:

![Highlighted, command description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndjdta0p2g3wvcv8v3o6.jpg)

---

> `public function handle()`

É aqui que a mágica acontece. E para começar com um exemplo bem simples, vamos editá-lo para ficar igual ao mostrado a seguir:

```php
public function handle()
{
    $this->info("Hi, I'm here to help you ;)");
    return 0;
}
```

Agora quando executarmos o comando `php artisan command:name` no terminal veremos o seguinte retorno:

:point_down:

![Calling the new command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/so8pvc8uivl4qots48np.jpg)

---

Na segunda [parte](https://dev.to/marciopolicarpo/que-tal-automatizar-tarefas-com-artisan-2-4j35) deste artigo veremos:
* como executar outros comandos do artisan
* receber e tratar inputs do terminal
* criar e persistir um usuário através do modelo


Até breve. :sunglasses: