Interface de linha de comando


1Apresentação

Muitas vezes é útil escrever scripts para serem executados na linha de comando. Isso é bem fácil de fazer em PHP puro, mas aí você precisa inicializar manualmente o log, as fontes de dados, o autoloader, a injeção de dependências...

Por isso, o Temma oferece o recurso Comma (COMmand-line MAnager), que realiza todas as inicializações necessárias antes de executar o código solicitado.

Um script é executado chamando o programa bin/comma, passando como parâmetros o nome do objeto e do método a serem executados, além dos eventuais parâmetros adicionais esperados por esse método.
O código executado pode ser completamente autônomo (realizando sua tarefa a partir das opções fornecidas), ou entrar em comunicação interativa com o usuário.

Alguns exemplos imaginários:

$ bin/comma CrmManager pushData
Novos dados enviados para o CRM
$ bin/comma Data import --app=main
Informe o caminho do arquivo a ser importado: /tmp/import.json
Importação concluída

Por padrão, os comandos executáveis ficam armazenados no diretório cli/ do projeto. No entanto, você pode colocá-los onde quiser nos caminhos de inclusão, eventualmente usando um namespace.

Ao usar um namespace, o nome do objeto deve ser colocado entre aspas ou apóstrofos.
Por exemplo:

$ bin/comma "\MyApp\Cli\CrmManager" pushData
Novos dados enviados para o CRM
$ bin/comma '\Cli\Managers\Data' import --app=main
Informe o caminho do arquivo a ser importado: /tmp/import.json
Importação concluída

Comandos fornecidos pelo Temma

O Temma fornece diversos comandos, cuja documentação pode ser encontrada na seção "Helpers":


2Documentação

Ao digitar bin/comma ou bin/comma help, você pode ver a documentação geral do Comma:

Se você digitar bin/comma help seguido do nome de um controlador, verá uma lista das ações do controlador, com a documentação associada:

Se você acrescentar o nome de uma ação, verá apenas a documentação dela:


3Controladores

Os objetos executados pelo Comma são controladores idênticos aos usados pelo Temma em resposta a requisições HTTP, exceto que devem ser armazenados no diretório cli/ (e não controllers/).

Há muitas semelhanças:

  • As ações podem receber um número variável de parâmetros, com parâmetros opcionais (que possuem um valor padrão).
  • Os métodos de inicialização __wakeup() e de finalização __sleep() são executados, respectivamente, antes e depois da execução da ação.
  • Se nenhum nome de método for fornecido na linha de comando, a ação raiz __invoke() é chamada. Essa ação não pode receber parâmetros.
  • Se uma ação padrão __call() estiver definida no controlador, ela será executada para todas as ações solicitadas que não tiverem um método equivalente.
  • Se uma ação proxy __proxy() estiver definida no controlador, ela sempre será executada, independentemente da ação chamada.
  • Os atributos definidos nos controladores e nas ações são executados (desde que possam funcionar em um ambiente de linha de comando, e não em um ambiente web).
  • O arquivo de configuração etc/temma.php é lido e seu conteúdo fica disponível por meio do objeto $this->_config.
  • O componente de injeção de dependências é gerado, e fica disponível da mesma forma (escrevendo $this->_loader).
  • As fontes de dados são geradas e ficam disponíveis por escrita direta (por exemplo, $this->db), ou passando pelo componente de injeção de dependências (por exemplo, $this->_loader->dataSources->db ou $this->_loader->dataSources['db-read']).
  • Também é possível usar DAOs.

Mas também há várias diferenças:

  • Não há sistema de roteamento, nem mesmo simplificado (não é possível chamar um controlador por um nome diferente do seu próprio).
  • Não há execução de plugins.
  • Não há visões.
  • O objeto $this->_request contém apenas os parâmetros fornecidos na linha de comando.

4Parâmetros

Os parâmetros esperados pelas ações são passados na linha de comando adicionando o prefixo --, seguido do sinal de igual (=) e do valor associado.

Se o valor contiver espaços, ele pode ser colocado entre aspas (") ou apóstrofos (').

Se um parâmetro for passado sem valor, ele será tratado como um booleano com valor true.


5Exemplo

Por exemplo, você poderia criar um script para adicionar um usuário ao banco de dados.

Esse script poderia ser chamado da seguinte forma:

$ bin/comma User add --name="Luke Skywalker" --email=luke@rebellion.org

Poderíamos imaginar um parâmetro opcional, para indicar que o usuário é um administrador:

$ bin/comma User add --name=Yoda --email=yoda@rebellion.org --admin=1

Na prática, o Comma vai instanciar o objeto User, e depois chamar seu método add(), passando os parâmetros.

O objeto User deve ser armazenado em um arquivo chamado User.php, localizado no diretório cli/ do projeto.
Esse objeto deve herdar do objeto \Temma\Web\Controller.

O código desse objeto poderia ser:

class User extends \Temma\Web\Controller {
    /** Criação de um Data Access Object automático. */
    protected $_temmaAutoDao = true;

    /**
     * Adiciona um usuário.
     * @param  string  $name   Nome do usuário.
     * @param  string  $email  Endereço de e-mail do usuário.
     * @param  bool    $admin  (opcional) Direitos de administrador. Falso por padrão.
     */
    public function add(string $name, string $email, bool $admin=false) {
        // adiciona o usuário ao banco de dados
        $id = $this->_dao->create([
            'name'  => $name,
            'email' => $email,
            'roles' => $admin ? 'admin' : '',
        ]);
        // mensagem
        print("Usuário criado com o identificador '$id'.\n");
    }
}

6Configuração

Por padrão, os scripts de linha de comando carregam a configuração presente no arquivo etc/temma.php. É possível fornecer o caminho para outro arquivo usando o parâmetro conf.

Esse parâmetro deve ser colocado antes do nome do controlador.

Por exemplo:

$ bin/comma conf=etc/temma-test.php User add --name=Yoda --email=yoda@rebellion.org

Observe que é possível fornecer um arquivo fora da árvore do projeto, mas isso não muda os caminhos usados para os diversos diretórios. Por exemplo, o plugin Language continuará procurando seus arquivos em etc/lang/.


7Caminhos de inclusão

Os scripts executados com o Comma têm o diretório lib/ do projeto adicionado aos seus caminhos de inclusão. Caminhos adicionais podem ser incluídos com o parâmetro inc.

Assim como o parâmetro conf, esse parâmetro deve ser colocado antes do nome do controlador.

Por exemplo:

$ bin/comma inc=/other/project/src Deploy start

8Log

Por padrão, os scripts de linha de comando escrevem seus logs na saída de erro.

Se estiver previsto no arquivo etc/temma.php, os logs também podem ser gravados no arquivo log/temma.log.

Para desativar a escrita na saída de erro, use o parâmetro nostderr.

Assim como os parâmetros conf e inc, esse parâmetro deve ser colocado antes do nome do controlador.

Exemplo:

$ bin/comma nostderr User list

9Interface

A interface do usuário é completamente diferente da dos controladores web. Os scripts de linha de comando interagem escrevendo em sua saída padrão e obtêm o que o usuário digita lendo sua entrada padrão.

O Temma fornece dois helpers úteis nessas condições:

  • \Temma\Utils\Ansi: fornece métodos para melhorar a exibição das informações escritas pelo seu código.
  • \Temma\Utils\Term: oferece funcionalidades para interagir mais facilmente com o terminal.