[Artigo] Analisando o código fonte do TabNews usando Python

Nesse exemplo vamos analisar qual foi a pasta do Tabnews sofreu mais alterações e quem foi o autor que mais contribuiu, tudo isso localmente, colhendo dados do repositório e gerando uns graficos maneiros!

tl;dr

Se você for aquele tipo de pessoa ansiosa, já segue o link com os gráficos: https://gcamargosilva.github.io/examples/code-insights/tabnews/

Você pode dar zoom ou se movimentar neles usando os controladores que ficam no canto inferior esquerdo.

Abaixo mostro qual foi a lógica e linha de raciocinio que eu usei para montar esses gráficos além do código fonte e o resultado da execução para projetos grandes como o React!

Introdução

Existe uma aba no GitHub chamada insights, nela é possível visualizar dados de alterações no projetos ao longo do tempo, mas você já parou pra pensar em como ela foi construída? Nesse artigo vamos entender uma das formas de coletar dados de um repositório local e construir gráficos sobre qualquer coisa que aconteceu, como o numero de vezes que uma pasta foi alterada ou quem foi autor que mais contribuiu.

Entendendo o GIT por trás dos panos

Tem uma coisa que provavelmente você já sabe mas eu preciso reforçar, o GIT é diferente do GitHub e do Bitbucket, ele é um software feito para versionar o seu código fonte independente do provedor remoto ou local de onde você armazena ele, por isso para esse projetinho não usaremos nenhuma API com esses provedores, apenas o repositório local.

Além disso preparei essa imagem bem resumida, bem resumida mesmo, sobre o funcionamento do GIT - Sério isso é muito superficial se aprofundem mais em GIT! Git overview

Escolha das ferramentas

Escolhi o Python para construir esse script pois gosto muito da Syntactic sugar que ele oferece, facilitando a escrita de coisas complexas em apenas uma linha, esse é um exemplo de como podemos extrair dados de uma lista para um array:

a = [item.name if item is not None else "" for item in items]

Nesse exemplo estou estou pegando o nome de todos os itens do meu array e se esse nome for vazio eu retorno uma string vazia, e como vamos manipular muitos dados, isso se torna uma mão na roda. Embora eu não tenha me preocupado com isso nesse script precisamos tomar cuidado com a complexidade do algoritmo pois o loop e a condicional ainda estão sendo executados.

Para interagir com o repositório, vou usar um pacote do Python chamado gitpython além das bibliotecas: matplotlib e mpld3 para geração dos gráficos.

O algoritmo

Antes de falar sobre a lógica utilizada, gostaria de ressaltar que algoritmos podem ser otimizados sempre! Essa foi a forma que encontrei para coletar esses dados, mas certamente existem outras formas.

Como eu mostrei na figura, um commit sempre está relacionado ao seu anterior, isso significa que o projeto atual é uma composição de todos os commits até aquele momento, o que me levou ao seguintes insights:

  1. Se eu recuperar uma lista de commit de um repositório e ordenar ela do primeiro para o ultimo, eu terei toda a timeline da criação de um projeto desde o seu inicio até o projeto atual.

  2. Se eu tenho toda a timeline de um projeto em commits, posso percorrer todos esses commits “reconstruindo” o projeto e coletando os dados de cada commit

  3. Como o dado de um commit carrega o autor, as linhas alteradas e os arquivos adicionados, posso construir um dataset da seguinte forma: cada vez que eu passar por um commit eu comparo ele com o seu anterior e analiso o que foi alterado realizando updates no dataset como a imagem de exemplo:

O algoritmo que gerou os gráficos abaixo coleta mais dados para plotar no grafico e tem algumas outras lógicas para evitar colisões de pontos e etc, mas a ideia inicial é essa da imagem!

Algoritmo

Show me the code!

Não queria colocar código aqui para não poluir o artigo, por isso coloquei todo o script comentado linha a linha no meu github e você pode baixar e executar em seus projetos Clicando Aqui!

O Resultado

Eu quis fazer um gráfico com vários círculos como se fosse um céu estrelado aonde o tamanho de cada circulo representa a quantidade de alterações de cada pasta.

Eu rodei esse script com muitos projetos, ele tem uma complexidade grande e sua execução é um pouco lenta para projetos grandes devido a quantidade de alterações e autores.

Mas o resultado é esse: Tabnews folder insights

Cada vez que você passa o mouse em cima ele mostra a quantidade de alterações que essa pasta ja sofreu desde o inicio do projeto.

O segundo gráfico trabalha com a mesma premissa, porem os círculos representam os autores e ao passar o mouse em cima é possível ver o numero de alterações realizadas em arquivos:

Tabnews folder insights

Executei o script tambem para o projeto o repositório do React e o Svelte você pode ver o resultado eles acessando um dos links abaixo:

Svelte - Esse eu gostei do resultado!!

React - Esse aqui levou um tempinho, foram mais de 15 mil commits e talvez precise de graficos melhores para esse volume de dados

O Script foi mais aquele “projetinho de fim de semana”, ainda é possível deixa-lo mais performático, talvez paralelizando a execução delegando o trabalho para GPU e claro gerar mais gráficos com mais insights.

Mas me diz ai, você sabia que tinha um dataset tão incrivel pra ser analisado localmente na sua máquina?

Muito legal essa análise e também impressionante os gráficos do Svelte e React, obrigado por trazer esse tipo de conteúdo para cá 🤝

No caso do TabNews notei que um dos maiores contribuidores é o GitHub, será que é por conta dos commits de merge?

Valeeu pelo feedback! Isso! Exatamente, na verdade isso ocorre porque estou usando o commiter e não o autor para esse gráfico (Não há nenhum motivo especifico, isso até é um erro no meu script kk) e eles possuem [diferenças para o GIT](https://stackoverflow.com/questions/18750808/difference-between-author-and-committer-in-git).