💧🐘🐋 Instalação das ferramentas de uma pessoa desenvolvedora Elixir
Tags: elixir, phoenix, postgres, braziliandevs
Published: 2021-05-27 04:16:59

Este é um guia de instalação de muitas ferramentas necessárias para você poder desenvolver na Linguagem de Programação Elixir. Para evitar alguns problemas, recomendo fortemente o uso de Linux ou WSL2 para quem tiver Windows 10, que é o meu caso.

Estou usando a distro `Ubuntu 20.04 LTS` com o WSL2, que até o momento, não tem apresentando problemas para mim. Para este guia, baixei novamente o `Linux Ubuntu 20.04 LTS` para instalar tudo do zero. Então se você estiver usando outra distribuição e enfrentar problemas, por favor compartilhe conosco sua dúvida ou solução para o problema, assim estaremos ajudando mais devs :)

* [Instalando o Elixir](#instalando-o-elixir)
 - [Instalando o asdf](#instalando-o-asdf)
 - [Instalando Pacotes do Ubuntu](#instalando-pacotes-do-ubuntu)
 - [Instalando o Elixir com asdf](#instalando-o-elixir-com-asdf)
 - [Instalando o Erlang com asdf](#instalando-o-erlang-com-asdf)
* [Instalando o Phoenix](#instalando-o-phoenix)
 - [Instalando o Node.js com asdf](#instalando-o-nodejs-com-asdf)
 - [Instalando o PostgreSQL e o pgAdmin com Docker](#instalando-o-postgresql)
* [Verificando se Tudo Está Funcionando](#verificando-se-tudo-esta-funcionando)
 - [Alterando configurações do PostgreSQL](#alterando-configuracoes-do-postgresql)
 - [Verificando se o banco foi iniciado (pra quem instalou __sem__ docker)](#verificando-se-o-banco-foi-iniciado-sem-docker)
 - [Verificando se o banco foi iniciado (pra quem instalou __com__ docker)](#verificando-se-o-banco-foi-iniciado-docker)
 - [Rodando o servidor do Phoenix](#rodando-o-servidor-do-phoenix)
* [Extenções para o Visual Studio Code](#extensoes-para-o-visual-studio-code)
 - [ElixirLS](#elixirls)
 - [Elixir Theme](#elixir-theme)
* [Instalando Bibliotecas Externas no Projeto](#instalando-bibliotecas-externas-no-projeto)
 - [Credo](#credo)
 - [Argon2](#argon2)
 - [ExCoveralls](#excoveralls)
 - [ExMachina](#exmachina)
* [Conclusão](#conclusao)

[![A Jornada do Autodidata em Inglês](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkoqkmh9hic17tnddjf6.png)](https://go.hotmart.com/R93865620U)

## Instalando o Elixir <a name="instalando-o-elixir"></a>

Primeiramente, vamos pensar agora na instalação do Elixir. Neste guia vamos instalar o Elixir usando o __asdf__, que é um `gerenciador de versões` que pode ser usado para várias linguagens de programação como Node.js, Ruby, Python, inclusive o Elixir e o Erlang.

### Instalando o asdf <a name="instalando-o-asdf"></a>

Para instalar o asdf, certifique-se que você tem o git instalado:
```elixir
$ sudo apt install curl git
```

Você pode copiar todo o código abaixo de uma vez só e colar ele no seu terminal se você estiver usando o terminal padrão __BASH__. Caso você alterou para o terminal __ZSH__, abaixo deixei o código pronto pra colar no terminal também :)

```bash
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
cd ~/.asdf
git checkout "$(git describe --abbrev=0 --tags)"

echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
source ~/.bashrc
asdf --version
```

Você pode copiar todo o código abaixo de uma vez só e colar ele no seu terminal se você estiver usando o terminal __ZSH__.
```bash
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
cd ~/.asdf
git checkout "$(git describe --abbrev=0 --tags)"

echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.zshrc
source ~/.zshrc
asdf --version
```


### Instalando Pacotes do Ubuntu <a name="instalando-pacotes-do-ubuntu"></a>

Para o Elixir funcionar, precisamos ter o Erlang também. E para podermos instalar esses dois, precisamos ter instalado na nossa máquina alguns pacotes do Ubuntu.

Atualizando o sistema:
`Se você acabou de instalar o Ubuntu, isso vai demorar, então você pode ir pegar um café :)`
```bash
$ sudo apt update && sudo apt upgrade -y
```
Instalando os pacotes:
`Isso vai demorar muito, mas muito mesmo, bem mais que o comando de atualização do Ubuntu, então você pode ir pegar outro café, ou melhor, uma jarra de café, ou ir fazer outra coisa mesmo e voltar daqui uma hora :)`
```bash
$ sudo apt-get -y install build-essential autoconf m4 libncurses5-dev libwxgtk3.0-gtk3-dev libwxgtk-webview3.0-gtk3-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libssh-dev unixodbc-dev xsltproc fop libxml2-utils libncurses-dev openjdk-11-jdk
```

### Instalando o Elixir com asdf <a name="instalando-o-elixir-com-asdf"></a>

Começamos adicionando o plugin do Elixir:
```bash
$ asdf plugin-add elixir
```
Agora podemos verificar todas as versões disponíveis do Elixir
```bash
$ asdf list-all elixir
...
1.12.0
1.12.0-otp-22
1.12.0-otp-23
1.12.0-otp-24
1.12.0-rc.0
1.12.0-rc.0-otp-21
1.12.0-rc.0-otp-22
1.12.0-rc.0-otp-23
1.12.0-rc.0-otp-24
1.12.0-rc.1
1.12.0-rc.1-otp-22
1.12.0-rc.1-otp-23
1.12.0-rc.1-otp-24
master
master-otp-21
master-otp-22
master-otp-23
master-otp-24
```
Vamos instalar a mais recente, que no momento é a `1.12.0`
```elixir
$ asdf install elixir 1.12.0-otp-24
```
Por fim, precisamos informar ao asdf qual versão do Elixir deve ser usada pela máquina:
```elixir
$ asdf global elixir 1.12.0-otp-24
```
Podemos verificar a versão do Elixir usando `elixir -v`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k6146xwy7cohva1g5r24.png) Na imagem acima, visualizamos que não temos o `Erlang` ainda.  


### Instalando o Erlang com asdf <a name="instalando-o-erlang-com-asdf"></a>

Adicionando o plugin do Erlang:
```bash
$ asdf plugin-add erlang
```
Agora podemos verificar todas as versões disponíveis dele
```bash
$ asdf list-all erlang
...
23.3.4.1
24.0-rc1
24.0-rc2
24.0-rc3
24.0
24.0.1
```
Podemos instalar a mais recente, que no momento é a `24.0.1`
```elixir
$ asdf install erlang 24.0.1
```
E precisamos informar ao asdf qual versão do Erlang deve ser usada pela máquina:
```bash
$ asdf global erlang 24.0.1
```

## Instalando o Phoenix <a name="instalando-o-phoenix"></a>

Comando para instalar o Phoenix:
```bash
$ mix archive.install hex phx_new 1.5.9
```
### Instalando o Node.js com asdf <a name="instalando-o-nodejs-com-asdf"></a>

O Phoenix usará webpack para compilar ativos estáticos (JavaScript, CSS, etc), por padrão. O Webpack usa o gerenciador de pacotes `node package manager (npm)` para instalar suas dependências e o `npm` requer o `Node.js`.

Podemos instalar o Node.js também com o `asdf`.

Adicionando o plugin do Node:
```bash
asdf plugin-add nodejs
bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring
```
Verificando todas as versões:
```bash
$ asdf list-all nodejs
...
16.0.0
16.1.0
16.2.0
```
Podemos instalar a versão mais recente:
```bash
$ asdf install nodejs 16.2.0
```
Precisamos informar ao asdf qual versão do Node deve ser usada pela máquina:
```bash
$ asdf global nodejs 16.2.0
```
Verificando a versão:
```bash
$ node -v
```

### Instalando o PostgreSQL e o pgAdmin com Docker <a name="instalando-o-postgresql"></a>

O PostgreSQL é um servidor de banco de dados relacional. O Phoenix configura os aplicativos para usá-lo por padrão, mas podemos mudar para MySQL ou MSSQL passando a flag `--database` ao criar um aplicativo.

Se você não entende muito bem sobre o PostgreSQL, recomendo assistir essa série no youtube: [aqui você vai aprender a mudar a senha e o usuário do Postgres](https://www.youtube.com/watch?v=Z_SPrzlT4Fc&list=PLucm8g_ezqNoAkYKXN_zWupyH6hQCAwxY)

Há duas formas de instalar o Postgres, localmente ou via Docker. Eu recomendo fortemente que você assista o vídeo do canal do Gustavo ELX PRO:
[Aqui você vai aprender a instalar o Postgres e o pgAdmin com o Docker](https://www.youtube.com/watch?v=A1hZPA_VKic)

Comando para instalar o postgres com docker:
```bash
docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres 
```
ou com network:
```bash
docker network create --driver bridge postgres-network

docker run --name postgres-docker --network=postgres-network -e "POSTGRES_PASSWORD=postgres" -p 5432:5432 -v $HOME/docker/volumes/postgres:/var/lib/postgresql/data -d postgres

docker run --name docker-pgadmin --network=postgres-network -p 15432:80 -e "PGADMIN_DEFAULT_EMAIL=g.92oliveira@gmail.com" -e "PGADMIN_DEFAULT_PASSWORD=postgres" -d dpage/pgadmin4
```

O `pgAdmin` é uma aplicação que nos permite visualizar as tabelas e os dados nelas mais facilmente.

Para instalar o Docker no WSL2, sugiro esse link: [Guia rápido do WSL2 + Docker](https://github.com/codeedu/wsl2-docker-quickstart)

### inotify-tools (para usuários linux)
Tem que ser instalado para o Live Reloading do Phoenix funcionar: [acesse esse link para instalar](https://github.com/inotify-tools/inotify-tools/wiki)

## Verificando se Tudo Está Funcionando <a name="verificando-se-tudo-esta-funcionando"></a>

Agora que tudo está instalado, você já pode criar o seu primeiro aplicativo Phoenix e colocá-lo em funcionamento.

Para verificar se tudo está funcionando, vamos executar um comando para criar um aplicativo Phoenix:
```bash
$ mix phx.new hello
```

### Alterando configurações do PostgreSQL <a name="alterando-configuracoes-do-postgresql"></a>

O `username` e o `password` devem ser iguais ao do PostgreSQL. Se você não alterou o _nome do usuário_ e a _senha_ no momento de instalação do PostgreSQL, você pode deixar o padrão "postgres", caso contrário, você terá que alterar nos dois arquivos abaixo:
```elixir
# Configurações para o Ambiente de Desenvolvimento
# caminho: config/dev.exs

config :delivery_app, DeliveryApp.Repo,
  username: "postgres",
  password: "postgres",
  database: "delivery_app",
  hostname: "localhost",
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
```
```elixir
# Configurações para o Ambiente de Testes
# caminho: config/test.exs

config :delivery_app, DeliveryApp.Repo,
  username: "postgres",
  password: "postgres",
  database: "delivery_app_test#{System.get_env("MIX_TEST_PARTITION")}",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox
```
### Comando para criar o banco de dados:
```bash
$ mix ecto.create
```
Após, você deverá ver algo semelhante:
```bash
Compiling 11 files (.ex)
Generated delivery_app app
The database for DeliveryApp.Repo has been created
``` 
__ATENÇÃO!__ Se você receber algum erro, certifique-se de que o `usuário` e a `senha` do postgres estejam corretas e, de que o banco de dados tenha sido iniciado.

### Verificando se o banco foi iniciado (pra quem instalou __sem__ docker) <a name="verificando-se-o-banco-foi-iniciado-sem-docker"></a>

- Se você instalou __sem__ usar docker, você pode usar esse comando para verificar se o postgres foi iniciado:
```bash
$ sudo service postgresql status
13/main (port 5432): down
```
- Caso o retorno tenha sido `down` inicie o banco de dados com o comando:
```bash
$ sudo service postgresql start
* Starting PostgreSQL 13 database server
```
- Após o comando `start` você receberá a mensagem `online`
```bash
$ sudo service postgresql status
13/main (port 5432): online
```

### Verificando se o banco foi iniciado (pra quem instalou __com__ docker) <a name="verificando-se-o-banco-foi-iniciado-docker"></a>

- Se você instalou o Postgres __com__ docker, você pode usar esse comando para verificar se o Postgres foi iniciado. No meu caso, está rodando apenas o pgAdmim, que eu já havia iniciado ele antes:
```bash
$ docker container ls
CONTAINER ID   IMAGE            COMMAND            CREATED       STATUS        PORTS                            NAMES
44c8e2eb0171   dpage/pgadmin4   "/entrypoint.sh"   5 weeks ago   Up 26 hours   443/tcp, 0.0.0.0:15432->80/tcp   pgadmin-dev
```
- Se o Postgres não apareceu, rode o comando:
```bash
$ docker container ls -a
61676d09bc02   postgres              "docker-entrypoint.s…"   5 weeks ago   Exited (0) 12 minutes ago                                    postgres-dev
44c8e2eb0171   dpage/pgadmin4        "/entrypoint.sh"         5 weeks ago   Up 26 hours                 443/tcp, 0.0.0.0:15432->80/tcp   pgadmin-dev
```
- Pegue o número do postgres, e rode esse comando:
```bash
$ docker container start 61676d09bc02
```
- Rode novamente o comando abaixo para verificar se o postgres foi iniciado. No meu caso ele aparece com o pgAdmin, que eu já havia iniciado antes do Postgres:
```bash
$ docker container ls
CONTAINER ID   IMAGE            COMMAND                  CREATED       STATUS              PORTS
    NAMES
61676d09bc02   postgres         "docker-entrypoint.s…"   5 weeks ago   Up About a minute   0.0.0.0:5432->5432/tcp           postgres-dev
44c8e2eb0171   dpage/pgadmin4   "/entrypoint.sh"         5 weeks ago   Up 26 hours         443/tcp, 0.0.0.0:15432->80/tcp   pgadmin-dev
```
### Rodando o servidor do Phoenix <a name="rodando-o-servidor-do-phoenix"></a>

Para verificar se tudo está funcionando, digite o comando abaixo:
```bash
$ mix phx.server
```
Após, acesse `http://localhost:4000/` e você verá algo semelhante:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1g8l14x88xea867y4x2.png)

## Extenções para o Visual Studio Code <a name="extensoes-para-o-visual-studio-code"></a>

Um editor de texto bastante usado pelos desenvolvedores Elixir é o Visual Studio Code. Nessa seção, falaremos sobre as extensões que podemos instalar para melhorar a nossa experiência.

### [ElixirLS](https://marketplace.visualstudio.com/items?itemName=JakeBecker.elixir-ls) <a name="elixirls"></a>

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whs6ko9gcjqfz4g0qh36.png)
A primeira extensão que precisamos instalar é o __ElixirLS__ que fornece:
* Suporte a linguagem Elixir;
* Depurador;
* Autocomplete;
* Fechamento automático inteligente de blocos de código;
* Consulta de documentação ao passar o mouse;
* Formatador de código ao salvar o arquivo;
* Entre outras coisas...

### [__Elixir Theme__](https://marketplace.visualstudio.com/items?itemName=maiquitome.elixir-theme&ssr=false#overview) <a name="elixir-theme"></a>

![Elixir Theme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1gd4lwqmd7pdy46olga.png)
É um tema de cores feito especialmente para código elixir. Nele as cores são bem separadas, onde conseguimos bater o olho e achar as coisas mais rapidamente.

## Instalando Bibliotecas Externas no Projeto <a name="instalando-bibliotecas-externas-no-projeto"></a>

Durante o desenvolvimento, é muito comum precisarmos utilizar bibliotecas de terceiros. Não vale a pena desenvolver novamente algo que outra pessoa já fez, testou, e dedicou tempo em análise. Por isso, os projetos que desenvolvemos sempre possuem dependências externas, ou seja, bibliotecas desenvolvidas por terceiros que precisam ser referenciadas pelo nosso projeto.

Vamos então falar sobre as dependências que podem ser instaladas em um projeto Elixir. Ao longo do tempo poderei adicionar novas dependências neste artigo. E, quem sabe, se começar a ficar extenso, posso fazer um novo artigo falando somente sobre dependências.

### Credo <a name="credo"></a>

Credo é uma ferramenta de análise de código estático para a linguagem Elixir com foco no ensino e na consistência do código. É bom para manter a equipe com um padrão de código.

A versão mais recente você pode encontrar aqui: https://hex.pm/packages/credo

* Adicione `:credo` como uma dependência ao `mix.exs` do seu projeto:
 ```elixir
 defp deps do
   [
     {:credo, "~> 1.5", only: [:dev, :test], runtime: false}
   ]
 end
 ```

* Execute o comando abaixo para instalar:
```bash
$ mix deps.get
```
* Execute o comando para gerar o arquivo de configuração `.credo.exs`. Nele você poderá desabilitar algumas exigências.
```bash
$ mix credo gen.config
* creating .credo.exs
```
Agora podemos instalar uma extensão do vscode para ele sublinhar o código quando tiver alguma inconsistência:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqsuiqtrx8n7v7w9xpvi.png)

Ou, ao invés de instalar a extensão, podemos também simplismente rodar o comando `mix credo` no terminal para verificar as inconcistências:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ejlt6cb229mj75pq34b.png)
Nesse caso o `Credo` está nos informando que os módulos devem ter documentação, mas se decidirmos no momento não fazer documentação, podemos desabilitar essa função no arquivo `.credo.exs` trocando `[]` por `false`:
```elixir
# .credo.exs

# ANTES
{Credo.Check.Readability.ModuleDoc, []},
        
# DEPOIS
{Credo.Check.Readability.ModuleDoc, false},
```
__Ou__ podemos colocar um `@moduledoc false` informando que não estamos usando documentação no módulo:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvitztdvqio671rjbz61.png) 

### Argon2 <a name="argon2"></a>

Argon2 é uma biblioteca de segurança que nos ajuda a encriptar senhas. Argon2 tem melhor resistência à quebra de senha do que Bcrypt e Pbkdf2. Sua principal vantagem é que, por ser uma função de difícil memorização, foi projetada para resistir a ataques paralelos que usam GPUs ou outro hardware dedicado.

A versão mais recente você pode encontrar aqui: 
https://hex.pm/packages/argon2_elixir

Adicione `:argon2_elixir` como uma dependência ao `mix.exs` do seu projeto:

```elixir
def deps do
  [{:argon2_elixir, "~> 2.0"}]
end
```

Não esqueça de executar o comando para instalar:
```bash
$ mix deps.get
```

### ExCoveralls <a name="excoveralls"></a>

ExCoveralls é uma biblioteca Elixir que relata estatísticas de cobertura de teste. 

Para instalar visite o link: https://github.com/parroty/excoveralls#mixexs

Nesse link você terá acesso ao código da imagem abaixo, copie e cole no arquivo `mix.exs` conforme a imagem: 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rfpjjxgildmhzyy92shu.png)
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dh3gfik9jeqe2i1c5564.png)
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9f6wa61nzdrvher0t7u9.png) 

Não esqueça de executar o comando para instalar:
```bash
$ mix deps.get
```

#### Usando o ExCoveralls 

Comando para verificar a cobertura de testes:
```bash
$ mix coveralls
```
ou
```bash
$ mix test --cover
```

Gerando um relatório em html:
```bash
$ mix coveralls.html
```
Esse comando irá gerar uma pasta chamada `cover` e dentro vamos ter o arquivo `excoverals.html`
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cds1mwtjup3yjuuqrzdq.png)
 
Clique com o direito do mouse em cima do arquivo, e copie o caminho do arquivo:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ct58lgu52mt5bb2ca2sb.png) 

Para quem está no Linux, é só colar o caminho no navegador. Para quem está usando Windows com WSL2 terá que informar a pasta de onde está o Linux; se o seu projeto estiver no Linux:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vuk2ugu0zr4ulc6morgi.png) 

No navegador você verá algo semelhante:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ajygmxfilq1erz89lf9s.png)

#### Arquivo coveralls.json

Podemos criar um arquivo no diretório raiz chamado `coveralls.json` onde podemos informar qual pasta ou arquivo deverá ser ignorado pelo ExCoveralls; pois existem arquivos que não precisam de testes, que é o caso de alguns arquivos que são por default do Phoenix.

No [repositório do ExCoveralls](https://github.com/parroty/excoveralls#exclude-files) você encontra também o código padrão para o arquivo `coveralls.json`:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6ym07zxgyf1juhvxex1.png)

O seu arquivo deve ficar semelhante: 
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qnvmct01y14opzs7d45j.png)

### ExMachina <a name="exmachina"></a>

O ExMachina facilita a criação de dados de teste e associações. Funciona muito bem com Ecto, mas é configurável para trabalhar com qualquer biblioteca de persistência.

Mais informações você encontra na documentação: https://hexdocs.pm/ex_machina/ExMachina.html

Para instalar basta adicionar `:ex_machina` ao seu arquivo `mix.exs`:
```elixir
def deps do
  # Get the latest from hex.pm. Works with Ecto 3.0
  [
    {:ex_machina, "~> 2.7.0"},
  ]
end
```

A última versão você encontra aqui: https://hex.pm/packages/ex_machina

Não esqueça de executar o comando para instalar:
```bash
$ mix deps.get
```

Se você quer saber como funciona essa lib, você pode acessar um dos meus artigos do projeto Rockelivery onde isso é abordado com detalhes: [Projeto Rockelivery: API para Pedidos em um Restaurante com Elixir e Phoenix (Parte 4)](https://dev.to/maiquitome/projeto-rockelivery-api-para-pedidos-em-um-restaurante-com-elixir-e-phoenix-parte-4-376n-temp-slug-7603210?preview=903a746a15201cb5fc02a646a4232264c48ae0166b11f54716a19b7685fb0a3434d2e7b6ec5420df859696dc8b3db46d330d0d8c546191337237d77d#refatorando-com-exmachina)

## Conclusão <a name="conclusao"></a>

Gostaria de te agradecer pela leitura até aqui e espero ter ajudado de alguma forma. Espero que, aos poucos, possamos ir ajustando as informações nesse artigo, atualizando e acrescentando novas ferramentas. Então, fique de olho nas atualizações. Qualquer dúvida ou sugestão, por favor deixe-me saber, estou sempre no [Linkedin](https://www.linkedin.com/in/maiquitome/) :)