Argumentos da linha de comando com docopt

docopt-1_abertura

No que diz respeito aos argumentos passados via linha de comando, você pode interpretá-los de forma manual, ou seja, pegando a lista enviada pelo sistema operacional e identificar cada elemento, ou utilizar alguma biblioteca específica para tal função — E, felizmente, há diversas delas e disponíveis para várias linguagens de programação.

Especificamente em Python¹ há uma bastante interessante chamada docopt, que interpreta automaticamente a sintaxe dos argumentos da linha de comando a partir da forma como se convencionou descrever (há tempos) no próprio texto de ajuda —  “- -help” — e nas páginas de manual dos programas.

(¹) Ele foi originalmente escrito para ser usado em Python porém está disponível também para outras linguagens de programação.

Instalação

A instalação é razoavelmente simples, podendo ser feita através do PIP:

$ pip install docpopt

Podendo estar, ou não, dentro de um ambiente criado pelo virtualenv.

Ou então com a versão já empacotada pela sua distribuição:

$ sudo apt install python3-docopt

Neste caso, o pacote específico para a versão 3.x do Python em distribuições Debian ou Ubuntu.

Modo de usar

Tudo de que o docopt precisa está na docstring do próprio programa e que será usada como parâmetro para executar a função docopt(). Havendo erro na validação dos parâmetros a execução será interrompida e o trecho contendo a forma de uso exibida para o usuário.

Programa de exemplo

Fica bem mais fácil de explicar com um programa de exemplo, então…

Isto é um pretenso programa de desenho que opera a partir da linha de comando, claro que é apenas um esqueleto e a única coisa que realmente faz é formatar em JSON e escrever em STDOUT o conteúdo do dicionário gerado pela chamada da função docopt (linhas 27 e 30).

Descrição da sintaxe

O que é essencial ao docopt é o trecho da docstring iniciado por “Usage:”² (linha 5) e terminado com uma linha em branco (linha 15) contendo as sintaxes possíveis do programa e os argumentos a serem utilizados. Além do comando propriamente dito (“draw”) há subcomandos e outros elementos (na nomenclatura do próprio docopt):

  • Argumentos : Definidos entre os caracteres de menor que e maior que — “< … >” — e atribuídos de acordo com sua posição na linha de comando. Ao todos existem quatro argumentos (“color”, “pattern_name”, “x” e “y”) e que não estão disponíveis para todos os subcomandos.
    • O comando draw cursor 10 15 indicará o subcomando “cursor” e que os valores para X e Y serão 10 e 15, respectivamente.
  • Opções : Definidos com um hífen (“- h”) ou dois hifens (“- -help”) e funcionado para ligar ou desligar determinada opção (“- -json” ou “- -step”) ou informar um valor específico (“- -color=” e “- -pattern=”).
    • O comando draw cursor --json para exibir as mesmas coordenadas X e Y porém formatadas em JSON.
  • Opcionais : Marcado entre colchetes — “[ … ]” — para indicar o seu uso é opcional.
    • O comando draw cursor exibirá na tela que as coordenadas X e Y atuais.
  • Condicionais : Colocado entre parênteses — “( … )” — definindo uma lista de alternativas de sintaxe com o caractere de barra vertical — “|” — funcionando como um separador.
    • O comando draw cursor 10 15 --json é inválido pois sua sintaxe é com dois argumentos ou nenhum, sendo que na ausência de argumentos é possível usar a opção “- -json”.
    • Repare que os comandos draw line... e draw box... partilham a mesma sintaxe, daí a condição fica no subcomando.

O interessante é que todo este tratamento e validação de argumentos se fazem sem a necessidade de nenhuma linha extra de código e, o mais importante, eventuais alterações na sintaxe só precisarão ser realizadas na docstring para fazer efeito.

Aliás, a opção “- -help” é automaticamente implementada pelo docopt!

(²) Ele procura por “Usage:” ou então “usage:”.

Interpretando

O retorno da função docopt() é um dicionário já devidamente tratado e validado:

docopt-1_draw-cursor-10-15

Daí é utilizar o conteúdo de args no programa como, por exemplo, implementar a rotina de tratamento do subcomando “cursor”:

E mais uma vez lembrando que este programa é só uma demonstração, claro que agora o draw cursor... funciona (quase) como deveria! 🙂

Finalizando

É possível testar o docopt diretamente no navegador web, algo bastante interessante para se fazer experiências com a sintaxe dos parâmetros sem necessariamente escrever um programa para isto. E para terminar, o docopt não é perfeito e não faz a validação do conteúdo dos dados, porém isto é facilmente resolvido com ajuda de uma outra biblioteca, a schema, para validação de dicionários de dados.

Anúncios