DEV Community

Cover image for Como criar um README dinâmico usando Javascript
Nícolas Gabriel
Nícolas Gabriel

Posted on

Como criar um README dinâmico usando Javascript

Olá! Você já pensou como seria poder gerar um README dinamicamente para aquele seu projeto do GitHub?
Eu já, mas nunca pensei em como funcionaria... até eu pesquisar se era possível e acabar me surpreendendo.

Depois de algumas pesquisas descobri uma feature do GitHub chamada "GitHub Actions", e ela consegue executar um código que você especificar, em diversas situações como: após um push, pull-request, e até mesmo em um intervalo especificado. Isso era justamente o que eu precisava, e com essa feature em mãos comecei a escrever meu Javascri- calma...

...Como isso é um guia, melhor eu documentar como fiz e como você também pode fazer e utilizar de diversas maneiras como quiser. Então vamos começar pelo começo:

1. Criando uma base

Gerar um markdown direto do Javascript não é tão prático assim, pois para visualizar você precisaria executar o Javascript, e repetir isso para cada mudança definitivamente não é viável a longo prazo (vamos ignorar o nodemon). Por isso eu recomendo criar um arquivo base em markdown, e modificá-lo usando Javascript, ao invés de gerá-lo por completo.

Como exemplo, vou criar um novo repositório no GitHub e disponibilizarei ao final do blog. Então vamos começar por essa base em markdown (que nomeei como "readme_base"), definindo nela as informações que serão fixas, e quais serão geradas:

# %{titulo}
Eu coloquei o titulo dentro de `%{}` apenas para evitar que
haja alguma ambiguidade com textos comuns.

Todas as partes desta base podem ser manipuladas e modificadas,
por exemplo aqui eu irei inserir uma lista de nomes:
%{listaDeNomes}}
Enter fullscreen mode Exit fullscreen mode

2. Modificando a base

Para testamos se está tudo funcionando, vamos criar um arquivo em Javascript, no qual nomearei como "index.js", para modificar a base:

/* o fs é quem irá ler o arquivo e gerar um novo,
ele vem por padrão no node, então não se preocupe */
const fs = require('fs')

// esta parte lê o arquivo "README_BASE"
fs.readFile('README_BASE.md', 'utf-8', (err, data) => {
    if (err) {
        throw err;
    }

/* aqui é onde acontecem as substituições, por exemplo
substituindo %{titulo} por "Dynamic Readme" */
    const substituicoes = {
        titulo: 'Dynamic Readme',
        listaDeNomes: `- Carlos\n- Ana\n- Sérgio`
    }

/* aqui é o que verifica e executa as substituições, um
regex bem simples com object literals, não precisa mexer aqui */
    const modificado = data
        .replace(
            /%{.*}/gm,
            e => substituicoes?.[e.slice(2, -1)] || e
        )

/* após ter feito as mudanças ele cria um arquivo
chamado "README.md" com a nova versão */
    fs.writeFile('README.md', modificado, 'utf-8', (err) => {
        if (err) {
            throw err;
        }
        console.log('✔ Processo finalizado!');
    });
});
Enter fullscreen mode Exit fullscreen mode

Este código será executado via node, então sinta-se livre para adicionar o que quiser, sejam pacotes, requisições em apis, gerar imagens, está em suas mãos.

3. Automatizando o processo

"Mas isso apenas gerou o arquivo pois fui eu quem iniciou o javascript, então para executar esse processo automaticamente eu precisaria de um host?"

Felizmente não, pois no caso do GitHub ele disponibiliza o github actions no qual eu havia falado. Ela permite que o processo rode em diversas circunstâncias, e no caso deste exemplo usarei o schedule que permite que o código seja executado a cada intervalo especificado.

Para isso iremos criar uma pasta chamada .github, e dentro dela uma outra chamada workflows, com um arquivo main.yaml.
Resumindo: .github/workflows/main.yaml.

No arquivo main.yaml é onde diremos ao github quando, como e o quê rodar.

# Nome do processo
name: Update automático

on:
  schedule:
    # cron é o "intervalo" de execução, recomendo usar
    # o site crontab.guru para lhe ajudar a definir.
    # nesse caso aqui, ele irá rodar a cada 10 minutos.
    - cron: '*/10 * * * *'

# Aqui vem os passos que a ação segue
jobs:
  build:
    # Inicia uma máquina virtual ubuntu
    runs-on: ubuntu-latest

    # Checa o código atual do repositório
    steps:
    - name: Checkout repo
      uses: actions/checkout@v2

    # Instala o node na versão 16.10
    - name: Use Node.js
      uses: actions/setup-node@v1
      with:
        node-version: 16.10
    - run: npm install
    - run: npm run build --if-present
      env:
        CI: true

    # Aqui em index.js você insere
    # o nome do seu arquivo javascript
    - name: Roda o arquivo
      run: |-
        node index.js
        cat README.md

    # E no final commita e faz um push caso haja alguma diferença
    # comparada ao código atual do repositório
    - name: Commit e push
      run: |-
        git diff
        git config --global user.email "bot-readme@example.com"
        git config --global user.name "bot automático"
        git add -A
        git commit -m "Arquivo atualizado!" || exit 0
        git push
Enter fullscreen mode Exit fullscreen mode

Com isso feito, sua pasta/repositório deve estar mais ou menos assim:

> .github
  > workflows
    > main.yaml
> index.js
> readme_base.md
> README.md (gerado)
Enter fullscreen mode Exit fullscreen mode

Se estiver assim, perfeito, tá tudo certo. Casos os nomes estejam diferentes ou não tenha gerado o README ainda, tá tudo bem também.

Mas só avisando que caso você mande tudo pro GitHub, e em 10 minutos seu repositório não atualize, calma. O GitHub Actions nem sempre é imediato, algumas vezes leva mais tempo do que o especificado. Por exemplo no meu teste desse repositório, apesar de eu especificar 10 minutos levou 25 😅.

Você pode acompanhar as actions por aqui, sempre que uma for executada ela irá aparecer:
Actions page

E falando no repositório, aqui está o link pra ele: Dynamic Readme. Se quiser pode fazer um fork e modificar ou seguir este tutorial, como preferir.

4. O final

Opa! Gostou do blog? É o meu primeiro, mas tentei deixar ele completo e simples de se entender, espero ter conseguido ^^.

E não pensa que dá pra fazer só essas coisinhas de trocar texto por texto não! No meu readme eu fiz uma seção que atualiza mostrando minhas atividades mais recentes, e até gera uma imagem utilizando a api do github para pegar um seguidor aleatório meu!
Sample

Tô ansioso pra ver o que vocês também conseguem criar.
Me marca no Twitter caso faça algo bacana com isso. 'Inté!

Top comments (0)