E aí moçada bonita! Tudo tranquilo?
Há um tempinho atrás escrevi sobre como fazer um CLI com Node.js, lembra? Se você não se lembra pode ver o post aqui! E hoje vamos deixar esse cara um pouco mais dinâmico e atrativo, com o uso de outras ferramentas e abordagens! Bora lá!
O que vamos fazer?
Para demonstrar a criação de nosso CLI interativo, vamos realizar uma busca de repositórios no Bitbucket. Como vamos precisar de fazer autenticação para buscar repositórios privados, precisamos de mais parâmetros do que no post passado, então vai ser um ótimo exemplo para o uso dessa nova ferramenta.
Como vamos fazer?
Para fazer isso, vamos utilizar alguns pacotes do npm, são eles:
- commander.js – É a ferramenta que vamos utilizar para realizar os comandos com Node.js;
- request-promise – Vamos utilizar esse cara para fazer requisições HTTP para o github.
- inquirer – O requirer é quem vai deixar o nosso CLI dinâmico e com vários argumentos.
Bora codar!
Para começar, vamos criar o projeto e instalar as duas dependências; depois de criado o projeto, o nosso package.json vai ficar mais ou menos assim:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "command-line-bitbucket-repos", | |
"version": "1.0.0", | |
"description": "Buscar repositorios do bitbucket via command line", | |
"dependencies": { | |
"commander": "^2.14.1", | |
"request": "^2.83.0", | |
"request-promise": "^4.2.2", | |
"inquirer": "^5.1.0" | |
} | |
} |
Belezura! Com o projeto criado, vamos fazer primeiramente a parte de requisição para a API do Bitbucket! Em um arquivo chamado request.js temos o código que vai fazer isso, vejam o código abaixo:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
buscarRepositorios | |
} | |
const request = require('request-promise'); | |
async function buscarRepositorios(respostas) { | |
let token = await buscarToken(respostas.username, respostas.password); | |
let options = { | |
uri: `https://api.bitbucket.org/2.0/repositories/?role=${respostas.role}&pagelen=${respostas.pagelen}`, | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
}, | |
json: true | |
}; | |
let repositories = await request(options); | |
if(respostas.somenteNome) | |
{ | |
let repoName = []; | |
repositories.values.map((repo) => { | |
repoName.push(repo['full_name']) | |
}); | |
return repoName; | |
} | |
return repositories.values; | |
} | |
async function buscarToken(username, password) { | |
//aqui retornamos o token, acreditem! 🙂 | |
} |
Notem que para realizar a chamada da API, precisamos antes buscar um Token do usuário para nos autenticarmos em uma conta. Não vou explicar como fazer isso e nem como criar as credenciais no portal do Bitbucket pois não é o objetivo desse post. Notem também a quantidade de parâmetros que vamos precisar para realizar todo o processo, tais como:
- username: será utilizado para identificar o usuário que vamos buscar os repositórios;
- password: será utilizado para autenticar tal usuário
- role: será utilizado para identificarmos o tipo de repositórios do usuário vamos buscar, nesse caso: dono ou membro;
- pagelen: será utilizado para identificar a quantidade de repositórios vamos buscar;
-
somenteNome: será utilizado apenas para o usuário escolher se quer ver todos os dados do repositório ou somente o nome.
Agora imaginem como ficaria isso com o nosso CLI do post anterior? Uma aberração parecida com isso:
repositorios do mussak@smn.com.br minhasenha owner 10 true
Claro que funciona, mas vamos ver como fica da outra maneira…
O nosso próximo passo, é construir o CLI (que é o que nos interessa hoje), então vamos lá! Criei um arquivo chamado bitbuckethelper.js e é lá que a mágica acontece, princípio é o mesmo, utilizando o commander. Se não entender direito, sugiro que leia o post anterior.
A diferença é que agora vamos o utilizar o prompt, da biblioteca do inquirer, vejam:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const request = require('./request'); | |
const comandos = require('commander'); | |
const { prompt } = require('inquirer'); | |
comandos | |
.version('1.0.0') | |
.description('Buscar repositorios do Bitbucket'); | |
let questoes = '???' //Vou explicar isso direitinho daqui a pouco… | |
comandos | |
.command('repositorios') | |
.alias('u') | |
.description('Buscar repositórios de um usuário') | |
.action(async () => { | |
let respostas = await prompt(questoes); | |
let repos = await request.buscarRepositorios(respostas); | |
console.info(repos); | |
}); | |
comandos.parse(process.argv); |
Como na versão anterior, temos um comando e uma ação para esse comando, e dentro da ação, chamamos o nosso método de buscar repositórios com os parâmetros informados. E Depois de tudo, para pegarmos as respostas do usuário, utilizamos o método prompt(questoes). É ele que vai fazer toda a mágica!
A diferença mesmo, é naquela variável questoes, pois é lá que informamos todas as perguntas que queremos fazer ao usuário, e lá nós definimos o tipo da resposta e várias outras coisas legais! Vou dar um exemplo aqui, mas na documentação do inquirer tem muita coisa pra gente aproveitar. Vejam como ficaram as minhas questões para esse caso:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const questoes = [ | |
{ | |
type: 'input', | |
name: 'username', | |
message: 'Insira o login do usuário:' | |
}, | |
{ | |
type: 'password', | |
name: 'password', | |
message: 'Insira a senha do usuário:' | |
}, | |
{ | |
type: 'list', | |
name: 'role', | |
message: 'Escolha o tipo dos repositórios:', | |
choices: [ | |
{name: "Dono", value: 'owner'}, | |
{name: "Membro", value: 'member'} | |
] | |
}, | |
{ | |
type: 'list', | |
name: 'pagelen', | |
message: 'Quantos repositórios quer ver?', | |
choices: [ | |
{name: 5, checked: true}, | |
{name: 10}, | |
{name: 15} | |
] | |
}, | |
{ | |
type: 'confirm', | |
name: 'somenteNome', | |
message: 'Quer ver somente o nome do repositório?' | |
} | |
]; |
E quando executamos o arquivo, com a ação “repositorios” vemos essas perguntas bonitinhas uma de cada vez:
E a variável “respostas” é preenchida da seguinte maneira:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"username": "mussak@smn.com.br", | |
"password": "minhasenha", | |
"role": "owner", | |
"pagelen": 10, | |
"somenteNome": true | |
} |
Quando fazemos a requisição, temos os repositórios dessa maneira:
Lindo né? :’)
Para esse código Node rodar como linha de comando do Shell, basta seguir os mesmos passos do post anterior (não vou colocar aqui novamente). Quando seguirmos aquele passo-a-passo, basta executarmos o seguinte comando no bash:
bitbucket-helper repositorios
Que tudo vai funcionar perfeitamente!
Os exemplos de código estão disponíveis no GitHub: https://github.com/vmussak/command-line-bitbucket-repos
Por hoje é só, qualquer dúvida ou sugestão, estou à disposição! Até mais 😀