Licença de software

Hoje irei falar de uma coisa muito importante referente a software, a licença. Não quero entrar no mérito de qual é a melhor ou se existe uma que é correta. A ideia é apresentar a importância que a mesma tem quando você publica um software.

Quando você publica algum código, por exemplo no GitHub, esse código está sujeito as leis de direitos autorais, da mesma forma como se você publicasse alguma música ou vídeo. Ou seja, caso alguém utilize o seu código, você poderia processar essa pessoa ou empresa, não sei quem ganharia, porém como você não deixou explicito o quem tem tiver acesso ao código pode fazer com o mesmo, isso está no seu direito.

Por este motivo é de extrema importância definir uma licença, permitindo à quem tiver acesso ao seu código, os direitos que você desejar. Um código sem licença pode ser lido, uma vez que foi publicado, porém para poder utilizá-lo em outros programas, ou até mesmo fazer alterações teria que entrar em contato com o autor para conseguir este direito. No caso do GitHub o código fica sujeito aos termos de uso do site, porém se ele estiver em outro lugar, um fork poderia não ser permitido.

Outra diferença menos sutil e que muitas pessoas confundem é software livre com open source. Open source são programas que tem seu código fonte abertos, ou seja, você pode ver o código do programa, praticamente tudo que está hospedado publicamente no GitHub é open source (a menos que tenha um arquivo binário sem seu código fonte). Para ser software livre é necessário que a licença permita as quatro liberdades. Não é apenas a GPL que é compatível com essas quatro liberdades, um exemplo é a licença MIT, porém ainda permite fechar o código em alguma versão futura. Caso queira uma lista de licenças compatíveis, no site do projeto GNU existe uma lista em português e indica quais as incompatibilidades da licença quando existem.

Como todo software livre tem como requisito acesso ao código fonte, além de serrem livres, também são open source, porém nem todo open source é livre. Um código open source poderia estar disponível, porém não permitir sua alteração, ou redistribuição, tornando-o assim não livre. Mesmo com acesso ao código a licença poderia impedir até a recompilação do mesmo, tornando impossível saber se o binário distribuído é realmente do código publicado e que não teve nenhuma alteração, como uma vulnerabilidade implantada.

Publicar um código sem licença pode gerar resultados totalmente opostos ao objetivo do quando foi publicado, por isso preste atenção neste detalhe. Caso não tem certeza de qual licença utilizar, de uma olhada nesse site, que mostra algumas alternativas e compara licenças, então você pode focar nos pontos que deseja e procurar uma que se adéque melhor ao seu caso.

Anúncios

Microframework contra “Baterias Incluídas”

Python é uma linguagem de programação que tem a fama existir mais frameworks web que palavras reservadas, isso se reflete em uma diversidade de opções para os mais diversos gostos. Talvez isso seja um reflexo da diversidade de pessoas que utilizam o Python para as mais diversas finalidades.

Quando iniciei no desenvolvimento web, comecei com PHP, da forma mais simples possível, montando cada página em arquivos separados com alguns includes para não repetir muito o código. Quando migrei para Python, o primeiro impacto foi ter que utilizar algum framework e não seguir a forma de cada página num arquivo, até poderia manter os arquivos utilizando CGI, mas não teria desempenho, ou escrever o WSGI diretamente, mas acabaria criando outro framework para facilitar o processo.

Comecei a aprender o Django, achei legal, porém foi complicado por ser muito diferente do que eu estava acostumado e passava mais tempo consultando a documentação que programando efetivamente. Com a filosofia de “baterias incluídas”, o Django tem incorporado bibliotecas para as funcionalidades mais comuns de uma página ou aplicação web pode precisar, como formulário, acesso a banco de dados relacionais, paginação, internacionalização…

Outra opção que temos é utilizar um microframework, que auxilie apenas no WSGI e utilizar outras bibliotecas para montar a base da aplicação, como no caso do Flask. Ele vem por padrão com outras bibliotecas, como o Jinja 2 para auxiliar a escrever o html das páginas e caso precise de banco de dados ou formulários, basta instalar alguma biblioteca como o SQLAlchemy e o WTForms.

A primeira coisa que pode ser notada ao comparar esses dois modelos é a complexidade, com certeza um microframework é mais simples e fácil de aprender, uma vez que você está focado apenas em como interagir com o servidor ou protocolo HTTP, não tem que se preocupar com banco de dados por exemplo.

O primeiro ponto contra o microframework é a necessidade do programador conheçer ou procurar outras bibliotecas para partes específicas da aplicação, como persistência de dados. Muitas vezes isso pode levar ao desenvolvimento de algo que já está pronto e disponível por desconhecimento. Porém o programador não fica restrito ao que o framework suporta, podendo adotar qualquer tipo de biblioteca, diferente do Django que por exemplo não suporta oficialmente nenhum banco NoSQL, é possível utilizá-los, porém você não conseguirá integrá-los nativamente com os models e forms. Além de que utilizar algum framework específico pode aproveitar melhor as funcionalidades de um banco de dados, em vez de funções genéricas suportada por todos.

Por outro lado, uma vantagem de você ter um framework que define as bibliotecas é a possibilidade de integração das mesmas, como no caso do Django, com um model escrito, é extremamente fácil criar um form baseado no mesmo, com validação, ou fazer a migração do esquema da tabela no banco sem precisar escrever tudo na mão ou duplicar o código e lógicas. Também não é necessário sair procurando bibliotecas na internet, e você terá tudo em apenas uma documentação, que na hora de buscar ajuda evita respostas do tipo com a biblioteca tal funciona ou ter que conhecer mais de uma biblioteca que fazem a mesma tarefa para decidir qual das duas utilizar.

Microframeworks e “baterias incluídas” são abordagens opostas, cada uma pode se sair melhor que a outra de acordo com o caso. Se você tiver que desenvolver um sistema que necessite de bibliotecas que o Django oferece e se encaixe na forma dele de resolver os problemas, com certeza é uma ótima opção, uma vez que você terá as bibliotecas integradas e tudo pronto para utilizar. Caso o sistema seja mais simples, não necessitando de todas as bibliotecas oferecidas pelo Django, ou tenha necessidades mais específicas, o Flask começa a ganhar vantagens, uma vez que o fato de ser reduzido pode deixá-lo mais leve ou até ter uma configuração inicial mais rápida.

Com certeza tem o conhecimento das duas abordagens é importante na hora da decisão do framework, nada pior que durante o desenvolvimento o framework ficar atrapalhando, por ele não ter foco para um determinado fim, ou ser tornar burocrático demais para coisas simples. Para quem estiver conhecendo um framework como o Django e acha que algumas coisas seriam mais práticas fazer na mão, tente visualizar todo o processo, que em algum ponto será facilitado por ser desta forma ou mais prático, porém vai necessitar de algum tempo para acostumar.

Strife, jogo moba para GNU/Linux e como corrigir problemas de bibliotecas em programas compilados

Recentemente comecei a testar um moba chamado Strife, que ainda está em beta, porém além das partidas típicas de moba, existem tutoriais e aventuras para um jogador bem interessantes. Os principais pontos que chamaram minha atenção é o jogo ser mais leve que o Dota 2, além de ocupar menor espaço (2 GB contra os 12 GB do Dota 2) e ser mais amigável com jogadores casuais, que eu apesar de conhecer esse estilo de jogo, nunca decorei habilidade de personagens ou itens, então posso ativar e seguir as sugestões de habilidades e itens com apenas um clique na tela, porém ainda tem o potencial de hardcore para os mais avançados.

Para quem estiver iniciando no jogo, recomendo fortemente fazer o tutorial, principalmente o da partida, até para conhecer as diferenças de outros mobas. Uma vez por dia rode a roda para ganhar alguns itens que servem como dinheiro no jogo para compra de pets e fabricação de itens. Antes de jogar online, crie uma partida de treino com bots, será mais fácil e você não corre o risco de um participante desconectar da partida e desbalancear o jogo, principalmente quando estiver conhecendo o personagem.

Para quem se interessou, basta fazer o cadastro aqui (usem esse link para me ajudar), e o download do jogo. Porém o mesmo não funcionou corretamente no Debian Jessie e por este motivo estou deixando algumas dicas aqui.

Primeiro achei estranho não ter um shell script no diretório principal para iniciar o jogo, mas pode ser iniciado executando diretamente o bin/strife. A questão principal é que as bibliotecas do Debian Jessie conflitaram com as do jogo e não foi possível iniciar o mesmo, mostrando no terminal a seguinte mensagem:

Inconsistency detected by ld.so: dl-open.c: 689: _dl_open: Assertion `_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT' failed!

Primeira coisa que verifico nos jogos é se não existe alguma biblioteca faltando com o comando ldd, outro ponto importante é verificar se o jogo é 32 ou 64 bits com o comando file, se o jogo for 32 bits a biblioteca também tem que ser 32 bits. No Debian o próprio site do repositório ajuda e muito nessa etapa, basta procurar por http://packages.debian.org/file:arquivo, exemplo http://packages.debian.org/file:libstdc++.so.6 e instalá-la com apt-get install libstdc++6 para a mesma arquitetura do seu sistema ou apt-get install libstdc++6:i386 para forçar a versão 32 bits, por exemplo.

Eu já tinha todas as bibliotecas instaladas, como no diretório bin existiam algumas bibliotecas também (arquivos .so), resolvi forçar o sistema a utilizá-las, setando a variável de ambiente LD_LIBRARY_PATH, no meu caso o comando ficou export LD_LIBRARY_PATH=/opt/Strife/bin, tive algumas mensagens diferentes, porém ainda não abria o jogo.

Pesquisando mais na internet descobri que existia essa incompatibilidade das bibliotecas do jogo com as do Debian, e num site francês (http://tuxicoman.jesuislibre.net/2015/01/strife-un-equivalent-de-league-of-legends-pour-linux.html) achei a solução apagando algumas bibliotecas do jogo para forçar a utilização das bibliotecas do sistema. Os únicos arquivos .so que devem ficar no diretório bin são:

  • cgame.so
  • game.so
  • libcef.so
  • libfmodex64.so
  • libgame_shared.so
  • libgcrypt.so.11
  • libjpeg.so.8
  • libk2.so
  • libpng15.so.15
  • physx.so
  • vid_gl.so

Após a atualização (bin/update), o jogo rodou muito bem e sem nenhum problema. Obviamente como ainda é um beta existem problemas do jogo em si, como sincronização com a dublagem em português, mas nada que interfira no gameplay e todos terão esses problemas, independente da plataforma.

Essa dica não é válida apenas para jogos. Vários programas quando não estão empacotados podem precisar de alguma biblioteca não instalada, como o programa do Bitcoin que usa o Qt e como meu ambiente é o Xfce (GTK), faltava algumas bibliotecas, ou jogos do Steam que são 32 bits e precisa de mais alguma biblioteca.

Reduzir o tamanho de sites

Além de poder deixar seu site pré-gerado (texto aqui), existem outras formas de melhorar o tempo de resposta na hora de acessar algum site. Podemos configurar o servidor HTTP para compactar tudo o trafego em gzip, porém podemos reduzir o site ainda mais antes de compactá-lo. Quando acessamos um site, normalmente temos um arquivo HTML, alguns CSS e JavaScript e várias imagens, cada um desses tipos de arquivos pode ser otimizado.

As imagens irão compor a maio parte do tráfego normalmente, como dizem que uma imagem vale mais que mil palavras, também pode refletir no tamanho da mesma. Existem algoritmos que tentam gerar a mesma imagem de várias formas para buscar uma onde o arquivo final seja o menor possível, podendo ter uma perca normalmente imperceptível ao olho humano ou com a qualidade exatamente igual ao original. Esses algoritmos serão diferentes para cada tipo de imagem, para PNG temos o OptiPNG, que pode ser instalado com apt-get install optipng no Debian. Um exemplo que posso contar aqui, tinha cerca de 400 imagens PNG, totalizando 699 MB no diretório, depois de utilizar o OptiPNG, o diretório ficou com 286 MB, aproximadamente 41% do tamanho inicial e mantendo a mesma qualidade.

Para JPEG além de buscar uma forma de reduzir as imagens, existe o modo progressivo, que quando a conexão é mais lenta, permite exibir uma imagem inicialmente em baixa qualidade e ir melhorando conforme o arquivo é recebido. Para isto utilizei o jpegtran, que pode ser instalado com apt-get install libjpeg-progs no Debian.

Algumas vezes pego pacotes de imagens na internet compactadas em algum formato, após descompactá-las e otimizá-las, tenho um tamanho menor no diretório sem compactar que no arquivo compactado, e recompactando fica menor ainda. Recomendo utilizar esses programas mesmo no computador local para economizar espaço. Para facilitar ainda mais fiz um script para GNU/Linux que identifica o tipo de imagem e executa o programa correto com os parâmetros necessários, quem quiser pode dar uma olhada no meu GitHub. Também configurei como uma ação personalizada no Thunar, então basta um click com o botão direito, selecionar a ação e já tenho o arquivo ou arquivos selecionados otimizado.

Para otimizar o CSS e JavaScript, primeiro é bom reduzir o número de arquivos visando reduzir o número de requisições HTTP. Outro ponto importante é que para executar o JavaScript no navegador é necessário parar todos os demais processos do navegador, ou seja, dois códigos JavaScript não são executados em paralelo, nem um código JavaScript e renderizar o HTML, por este motivo existe a prática de colocar as tags script antes de fechar o body, para termos a página renderizada primeiro.

Agora para reduzir o tamanho do CSS e JavaScript existe uma técnica chamada minify, que consistem em reduzir espaços em branco, quebra de linhas e utilizar nome de variáveis menores em JavaScript. Uma ferramenta que conheço para esta tarefa é o YUI Compressor, escrito em Java, então funciona em qualquer plataforma. Porém se forem editar os arquivos posteriormente recomendo manter uma cópia do original.

O HTML segue os mesmos princípios do CSS e JavaScript de reduzir espaços em branco, que são colocados principalmente quando a página é gerada dinamicamente ou indentada, que faz sentido para quem está vendo o código, porém não faz diferença para o navegador. Quando é aplicado em cima de páginas dinâmicas, esse processo, diferente dos descritos anteriormente, precisa ser refeito para cada página, aumentando o processamento necessário para gerar a página e por isso muitas vezes é deixado de lado. Para páginas estáticas, como pode ser aplicado apenas uma vez, volta a ser interessante. Para fazer essa otimização, ela segue as mesmas regras de arquivos XML, ou seja, também pode ser aplicada em feeds RSS.

Também para reduzir o processamento, podemos deixar os arquivos já compactados no servidor, não necessitando recompactá-los a cada requisição. Um exemplo desta configuração para NGIX pode ser vista no texto do Magnum quando ele estava configurando o servidor para o seu site feito no Pelican (http://mindbending.org/pt/servindo-sites-estaticos-com-o-nginx#configurando-um-site).

Blog em páginas estáticas

Quem já desenvolveu alguma coisa para web percebeu que algumas coisas são feitas dinamicamente por praticidade, porém que não mudam muito, como barras laterais do WordPress, que são geradas dinamicamente para permitir a customização de forma simples, porém apenas quando se ter uma nova postagem que existe uma real mudança.

Ter partes dinâmicas na página é muito bom, porém aumenta a carga do servidor que deve sempre regerar cada uma dessas partes a cada requisição, a menos que seja utilizado algum sistema de cache. Como em blogs, páginas de empresas ou produtos tem uma baixa taxa de atualização por exemplo, é possível gerar essas páginas previamente e deixá-las como arquivos estáticos no servidor, economizando assim o custo de geração das páginas. Se tiver uma mudança basta gerá-las novamente e atualizar no servidor.

Para facilitar a geração das páginas, existem ferramentas para essa tarefa, como o Pelican escrito em Python e o Jekyll em Ruby. Além de permitir escrever as páginas em HTML, podemos ter outras opções como Markdown e reStructuredText. Para dar alguns exemplos, além dos sites dos próprios projetos, temos o PythonClub, Hack ‘n’ Cast e Castálio Podcast usam o Pelican e o Grok Podcast usa o Jekyll, além de todos aceitarem contribuições via GitHub.

Uma observação é que todos esses sites possuem campo de comentários, ou seja, algo carregado dinamicamente, porém se olhar para o código isso é feito via JavaScript dentro do navegador, não no servidor. A mágica está em colocar os comentários em outro servidor (podendo ser até o mesmo) e utilizar o JavaScript para carregar, exibir e até enviar os comentários via requisições Ajax. Um serviço gratuito para os comentários em blogs é o Disqus, que hospedará apenas os comentários para você.

Infelizmente ainda não converti meu blog do WordPress para o Pelican, porém assim que encontrar uma solução para acompanhar os acessos o farei, mas o fato de não querer depender do Google, não ter um servidor próprio e sem cartão de crédito internacional, dificultam as coisas. Porém teria várias vantagens. O servidor HTTP poder ser qualquer um, já que não dependeria do suporte a alguma linguagem ou banco de dados. Como são apenas páginas estáticas, o site não corre o risco de SQL Injection e outras falhas decorrentes das páginas dinâmicas. Como é uma página estática, é muito mais rápido para o servidor responder a solicitação, podendo assim atender mais acessos com o mesmo servidor. Arquivos estáticos são mais fáceis de fazer cache, podendo reduzir até o número de requisições do servidor.

Isso obviamente não é a solução para tudo, montar um sistema inteiro desta forma não é tão prático, porém montar um site estático e fazer todas as ações com JavaScript via uma API pode ser uma opção interessante, tendo as vantagens já descritas e já ter uma API pronta para integrações. Sempre tendo que avaliar se os benefícios superam as dificuldades.

2014

Trago o que provavelmente será a última postagem do ano. Como esse foi o primeiro ano do Blog, que ainda está começando, não tenho muita coisa para falar ou comparar, porém apesar dos textos não ficarem exatamente da forma que gostaria, acredito que possam ser úteis para outras pessoas, pelo menos como um pontapé inicial.

Referente aos acessos, o podcast foi muito melhor, com episódios passando dos 1000 downloads, enquanto todos os acessos do blog ainda não chegaram a 2000 visualizações. Os textos mais acessados foram Editor de Texto: VIM, Backup HD Externo e MX Reverse e escolhas de frameworks com 114 visualizações cada, seguidos de Docker com 100. Fiquei surpreso com a quantidade de acesso do texto de backup, já tenho um assunto para ano que vem, seguindo a ideia de scripts/ferramentas para pequenas tarefas, spoilers no meu GitHub.

No próximo ano iniciarei um segundo curso superior, o que consumirá boa parte do tempo livre que tive neste ano. Não sei qual a regularidade que conseguirei manter aqui, mas com certeza surgirão assuntos diversos, então fiquem atentos. Justamente por ser o meu segundo curso tentarei validar algumas matérias também, porém ainda não sei quanto tempo isso me renderá.

Agradeço a todas as quatro pessoas que comentaram aqui e aos dois que zoaram dando first depois do podcast.

Até mais.

Deploy do MX Reverse no Heroku

No texto anterior, comentei sobre minhas escolhas para montar um site para verificar o DNS reverso (https://eduardoklosowski.wordpress.com/2014/12/08/mx-reverse-e-escolhas-de-frameworks/). Agora comentarei sobre a hospedagem do mesmo no Heroku.

Primeiro fiz a aplicação funcionar localmente, que bastava juntar a página escrita no AngularJS para ficar disponível no WSGI. Não é uma boa prática servir arquivos estáticos pelo WSGI, porém é fica mais simples para o desenvolvimento ter apenas um servidor HTTP e é desta forma que o Heroku trabalha. Para isto reutilizei o virtualenv do Python que havia criado para fazer o desenvolvimento, com a biblioteca do DNS e o Gunicorn (servidor WSGI) já instalado, adicionei o pacote static3 e alterei no código.

Com tudo devidamente testado no Gunicorn, criei o arquivo requirements.txt que é um padrão de projetos Python para dizer as dependências, no meu caso eram todos os pacotes instalados via pip, então foi só executar pip freeze > requirements.txt, porém o mesmo pode ser editado para remover alguma coisa ou ajustes de verão dos pacotes sem problemas.

Bastava ainda dizer como iniciar a aplicação, já que o Gunicorn tem vários parâmetros e é necessário informar onde está a função WSGI dentro do código Python. No Heroku esses parâmetros ficam dentro de um arquivo chamado Procfile, que consiste em um nome mais a linha de comando, podendo ter vários processos em diferentes linhas, no meu caso fiz apenas web: gunicorn wsgi:application --access-logfile - --error-logfile -. É possível utilizar esse arquivo localmente como o Heroku faz utilizando um programa escrito em Ruby chamado Foreman, porém optei pela versão escrita em Python chamada Honcho, com ele devidamente instalado bastou um honcho start e minha aplicação estava funcionando localmente já na forma necessária para subir no Heroku.

Criei uma conta, sem mistérios. Como o Heroku trabalha com o deploy baseado em Git, é necessário cadastrar uma Chave SSH, da mesma forma que ocorre no GitHub e outros serviços que utilizam o protocolo do SSH. Como já tenho a minha chave, não precisei criar uma nova, porém quem precisar pode utilizar o comando ssh-keygen no GNU/Linux. Copiei o conteúdo do arquivo id_rsa.pub e adicionei em SSH Keys dentro do Manage Account.

Próximo passo é criar o aplicativo, que pode ser feito dentro de Personal Apps, clicando no ícone de mais. Incrivelmente esse cadastro é bem simples, o nome do aplicativo, que caso não seja especificado será gerado automaticamente e em qual região você deseja que o seu aplicativo fique rodando.

Agora a parte mais importante, enviar seu código para o servidor. Existe a opção tradicional via Git ou via Dropbox (em beta neste momento). Na opção via Dropbox, basta copiar seu código para o diretório criado, ir no Heroku e mandar ele buscar a nova versão. Como eu tenho experiência com o Git, já tinha meu código nele, achei muito mais simples adicionar um repositório remoto e fazer o push. Vendo as configurações do aplicativo, achei a URL em Settings (git@heroku.com:mxreverse.git), adicionei no repositório (git add remote heroku git@heroku.com:mxreverse.git) e enviei o código (git push heroku master).

Depois desses simples passos já tinha a minha aplicação rodando em https://mxreverse.herokuapp.com/. Obviamente por ser uma aplicação simples, sem banco de dados, não precisei fazer uma série de configurações, bem como o uso da ferramenta de linha de comando do Heroku.

Uma das vantagens do Heroku sobre outras soluções como OpenShift é a possibilidade de criar vários aplicativos de graça, uma ótima opção para quem esta desenvolvendo e quer deixar sua aplicação rodando ou um demo, depois se a quantidade de acessos crescer, você pode escalar sua aplicação lá mesmo ou mudá-la para outro lugar. Porém já ter sua aplicação disponível na internet logo no início pode motivá-lo a continuar o desenvolvimento ou trazer mais pessoas para o projeto, já que ela não terá o trabalho de fazer o deploy para ver seu projeto e a facilidade para apresentar a outras pessoas.

MX Reverse e escolhas de frameworks

Se alguém deu uma olhada recentemente no meu GitHub, pode ter visto um repositório chamado mxreverse, que é um site que desenvolvi para validar o DNS reverso de servidores de e-mail. Apesar do código ser simples, tomei algumas decisões que gostaria de compartilhar.

Primeiramente a linguagem escolhida foi Python principalmente por ser a qual tenho mais domínio e facilidade, também achei uma biblioteca para fazer as pesquisas do DNS, possibilitando o desenvolvimento. Inicialmente pensei em criar uma função para fazer a validação com algumas funções auxiliares, que depois de alguns testes e tempo de desenvolvimento estava pronta.

Agora até aqui foi algo bem normal do qualquer projeto. Porém como disponibilizar esta função? Como utilizei uma biblioteca externa, além do meu código seria necessário também instalá-la para executar local, ou poderia disponibilizar um webservice, que possibilitaria reutilizá-lo com linguagens também. Como o código é Python, a forma mais simples, e provavelmente a mais recomendada é usar a especificação do WSGI, sendo uma única página, com apenas um parâmetro (o domínio a ser verificado), retornando um JSON, não tive necessidade de utilizar outros frameworks. Apesar de conhecer e gostar de Django e Bottle, o projeto não teria vantagens ao utilizar qualquer um dos dois, além de possibilitar fazer algo mais otimizado e simples sem um framework no caminho.

Com a API definida e funcional, era necessário um cliente que consuma a API e mostre as informações, caso contrário perderia a praticidade que gostaria, exigindo que cada um desenvolvesse seu código. Com as atuais aplicações em JavaScript no navegador, interessei me pela ideia de fazer uma página estática, utilizar AJAX para comunicar com a API e JavaScript para mostrar a resposta. Um framework JavaScript que tinha vontade de testar a algum tempo e aproveitei para fazê-lo neste projeto é o AngularJS. A principal ideia é atualizar um template HTML a partir de variáveis do JavaScript, ou seja, bastava ler o JSON e guardá-lo numa variável que o resultado seria mostrado na página.

O mais importante deste projeto é que mesmo que você conheça e goste de algum framework, ele pode não ser o melhor para a aplicação que está sendo desenvolvida. Abandonei a montagem do HTML em Python, passando para o JavaScript, deixei o código no servidor muito mais simples e aproveitei para conhecer outra forma de desenvolver aplicações, que poderei reutilizar em outros projetos onde ela se adapte melhor.

Resumo saia de sua zona de conforto, conhecer outros frameworks, por mais que superficialmente, pode ajudar na hora de montar uma aplicação, escolhendo uma arquitetura mais adequada.

Aprendendo JavaScript com exercícios TDD e críticas a esse modelo

Com as novas tecnologias, principalmente cloud e busca por sistemas que consumam menos recursos, estou interessado em tecnologias de API REST e consumi-la no navegador. Quando se fala em navegador sempre temos o JavaScript, no MongoDB temos documentos JSON e um terminal, que se não for JavaScript, tem várias semelhanças, além do Node.js no lado do servidor. Com todas essas tecnologias a única que não tenho conhecimento para identificar se ela pode ser aplicada com vantagens e quais seriam é o Node.js, então andei pesquisando para aprender.

Achei um link no site oficial muito bom do nodeschool.io. O tutorial presente no site segue um esquema TDD, ou seja, você tem um exercício para fazer e para validar o mesmo, basta rodar o teste, isso tudo via Node.js e npm. Pode ser um pouco complicado para quem não tem contato nenhum, porém não é muito complicado instalar essas duas dependências e para iniciar o tutorial basta seguir os comandos do site.

Como eu já conheço programação em JavaScript no navegador, esse tutorial a primeira vista pareceu muito interessante, e bem legal a forma de aprender. Porém eu já sabia JavaScript e conheço algumas de suas características, como uso de callbacks e prototype. Também temos um curso específico de JavaScript, infelizmente ainda não tive tempo para dar uma conferida no mesmo para falar sobre o mesmo.

Olhando esse modelo de aprendizado, com textos curtos e um exercício estilo TDD para resolver, lembrei do Codeacademy e que outros sites oferecem conteúdo desta forma. As vantagens são obviamente a rapidez para quem inicia, todo seu aprendizado já vai ser em cima da linguagem, já é possível iniciar uma filosofia de TDD, além da resposta muito mais rápida se o código funciona ou não. Porém não sei se quem tem um mínimo conhecimento de JavaScript, com pouco ou nenhum domínio de callbacks e outras características da linguagem teria o mesmo aproveitamento do material.

Com certeza “cursos TDDs” não irão substituir o material escrito, ainda prefiro um texto explicativo que um exercício para aprender novos conceitos, pelo menos acho que o conhecimento que consigo obter seria maior. Recentemente li o livro Padrões JavaScript e mesmo sem ter feito nenhum exercício aprendi várias boas práticas e formas de escrever um código melhor, obviamente apliquei depois nos códigos para fixar o aprendizado. Só lembrando que essa foi minha forma de aprender.

Recentemente também estive querendo dar uma olhada em Ruby, porém não achei um bom material, que com certeza existem, porém não quero algo que me ensine a fazer uma condição, laço de repetição simples ou o básico de orientação a objetos, tenho esse conhecimento de outras linguagens, gostaria de algo que me ensinasse Ruby e sua forma de resolver os problemas (filosofia), provavelmente o ideal seria algo mostrando um projeto ou parte dele, que possa utilizar como referência. Porém após o fim do mesmo ficaria perdido novamente, somado aos açucares sintéticos que levam a várias formas de escrever exatamente o mesmo código.

Achei no site do Ruby um link de Ruby a partir de outras linguagens (https://www.ruby-lang.org/pt/documentation/ruby-from-other-languages/), li o de Python, aprendi algumas diferenças, porém não sabia fazer uma linha sequer e não consegui ler nenhum código mais específico de Ruby, que simplesmente não entendia a sintaxe do que eram certas partes.

Não tive esse problema com Python, pois quando aprendi fazia algum tempo que não programava, servindo como revisão, além do tutorial presente na documentação ser bem objetivo. Porém acredito que isso irá acontecer com qualquer linguagem, e principalmente a dificuldade de perder o “sotaque”. Gostaria de saber se mais alguém passou por isso e o que fizeram, também seriam interessantes links de material classificados para os diferentes níveis de conhecimento para se aprender alguma linguagem. Deixem nos comentários, depois posso organizar em uma página separada, ou se souberem algum lugar que já tenha isso, melhor ainda.

Estrutura interna do Git – Parte 2

Não exatamente uma sequencia, porém ainda ficaram alguns pontos que eu acho muito interessante do Git que levarei em conta quando precisar desenvolver algo.

Além dos comandos normalmente utilizados, que para quem utiliza o bash completion possui autocompletamento, existem vários comandos “ocultos”, porém documentados. O comando git cat-file do texto anterior é um exemplo. Isso ocorre pela forma que os comandos do Git foram feitos, existe um conjunto de comandos básicos para executar pequenas tarefas, assim como a filosofia UNIX (uma única coisa, porém bem feita). Ou seja, comandos para adicionar arquivos na estrutura do Git, recuperá-los, calcular diferenças, aplicá-las, lidar com braches e outros.

No capítulo 9 do Pro Git temos um exemplo melhor desses comandos, e até como fazer um commit sem utilizar o git commit. Isso mostra que até mesmos comandos internos são implementados utilizando outros comandos, dividindo o problema em partes menores.

Agora imagina que você está desenvolvendo um sistema que utiliza alguma parte do Git, como o GitHub para visualizar o código, ou o OpenShift para receber o código e fazer deploy da aplicação. Como existem várias operações você não precisa desenvolver algo para ler a estrutura do Git, pode simplesmente reutilizar esses comandos, ou seja, a API já está pronta, basta adaptá-la para a sua linguagem.

Porém não precisamos ir muito longe para tirarmos proveito disso. No meu texto Verificador de estilo de código no VIM, comentei sobre os verificadores de estilo e podemos utilizá-las em conjunto com o Git. Imagine que seu projeto tem um estilo que todo o código deve ser seguido, porém as vezes alguém acaba deixando passar um espaço a mais, troca espaço por tab. No Git podemos fazer a validação do código é permitir o commit apenas caso ele esteja de acordo com o estilo.

Para fazer essa verificação precisamos utilizar outro recurso chamado de Hook, que são scripts executados em determinados momentos (consulte o capítulo 7.3 do Pro Git). Inicialmente fiz a verificação apenas local para lembrar caso tenha alguma coisa fora do padrão, mas ainda possível forçar o commit se assim for desejado. Como os projetos tinham vários arquivos fora do estilo, queria verificar apenas os alertas referentes as minhas mudanças, até por questão de performance, se eu não alterei o arquivo não preciso ser lembrado que ele tem algum erro, deixando a saída até menos poluída e posso verificar todos os arquivos caso esteja atrás de erros.

Primeira coisa, preciso saber quais os arquivos que foram alterados no commit, para tanto utilizei o comando git diff –raw –cached, uma informação um pouco mais bruta dos arquivos selecionados com git add. Porém eu posso ter executado o git add e alterar o arquivo novamente antes de fazer o commit, então não posso simplesmente fazer a validação do código do arquivo no diretório, para isso utilizei a hash do git diff para pegar o arquivo que será commitado com git show e fazer a validação em cima dele.

Quem quiser ver como tudo ficou, tenho esse código no meu GitHub (https://github.com/eduardoklosowski/codelint), está escrito em Python, porém tenho que trabalhar melhor a documentação e ter decidido fazer tudo em inglês não ajudou, porém assim que estudar melhor as formas de documentação e opções que tenho para compartilhá-la irei fazer isso, mas se alguém for usar e tiver alguma dúvida deixe nos comentários, até ficarei feliz em saber que alguém está utilizando (testando). Report de bugs, melhorias no código ou funcionalidades novas são bem vindas. Pode ser utilizado com outras ferramentas de controle de versão, só não tenho conhecimento e necessidade para isso agora, mas pode ser facilmente desenvolvido já que o Git foi feito a parte também.

Depois de criar os arquivos de configuração em ~/.config/codelint, preparo tudo para o commit e executo git codelint, isso iniciará os validadores. Um detalhe que todos os comandos no PATH que começam com git-, exemplo git-codelint podem ser executados como comandos do git dessa forma e com autocompletamento.

Agora só falta colocar no Hook executado antes do commit, o pre-commit, seu conteúdo é simples.

#!/usr/bin/env bash
git-codelint

Caso queira verificar os arquivos antes de commitar posso executar git codelint e quando der o git commit será verificado, se tiver algum erro o commit será interrompido para correção, ou posso forçar com git commit -n.