Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jungsoft/elixir-style-guide
Our Elixir style guide
https://github.com/jungsoft/elixir-style-guide
Last synced: about 1 month ago
JSON representation
Our Elixir style guide
- Host: GitHub
- URL: https://github.com/jungsoft/elixir-style-guide
- Owner: jungsoft
- License: mit
- Created: 2020-08-18T13:23:58.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2022-01-24T13:21:54.000Z (almost 3 years ago)
- Last Synced: 2023-03-06T14:52:46.730Z (almost 2 years ago)
- Size: 81.1 KB
- Stars: 7
- Watchers: 3
- Forks: 3
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Elixir Style Guide
Welcome to Jungsoft's Elixir Style Guide. Sit down, have a cup of coffee and read this calmly. ☕
## Introduction
The goal of this guide is to help our team to understand and
follow code style best practices, maintaining a pattern.As this guide is an extension of the [Christopher Adams Elixir Style Guide](https://github.com/christopheradams/elixir_style_guide), we **highly recommend** reading it before you continue.
# Table of Contents
* __[General Guidelines](#general-guidelines)__
* [Aliases](#aliases)
* [Blank Lines](#blank-lines)
* [Breaking Lines](#breaking-lines)
* [Dangling Commas](#dangling-commas)
* [Moduledocs](#moduledocs)
* ['With do' Indentation](#with-do-indentation)
* __[Schemas](#schemas)__
* [Ecto Schema](#ecto-schema)
* [GraphQL Schema](#graphql-schema)# General Guidelines
## Aliases#### Ordering
The aliases should be ordered alphabetically using the full path as it is easier to add and remove an alias and you do not need to rearrange the groupings.
```elixir
# ❌ Bad
alias Jungsoft.{
AModule,
BModule,
CModule,
}
alias Jungsoft.AModule.ASubModule# ✅ Good
alias Jungsoft.AModule
alias Jungsoft.AModule.ASubModule
alias Jungsoft.BModule
alias Jungsoft.CModule# ❌ Bad
alias Jungsoft.{
AModule,
BModule,
CModule,
}# ✅ Good
alias Jungsoft.AModule
alias Jungsoft.BModule
alias Jungsoft.CModule# ❌ Bad
alias Jungsoft.AModule.ASubModule.ASubSubModule
alias Jungsoft.AModule.ASubModule
alias Jungsoft.CModule
alias Jungsoft.BModule# ✅ Good
alias Jungsoft.AModule.ASubModule
alias Jungsoft.AModule.ASubModule.ASubSubModule
alias Jungsoft.BModule
alias Jungsoft.CModule
```[Back to top ⬆️](#table-of-contents)
## Blank Lines
Blank lines are important in some cases, but in some others can make the code less readable.
The examples below will give more details about this.#### Module
Modules should not contain a blank line between the `moduledoc` and the module name.
```elixir
# ❌ Bad
defmodule Jungsoft.NicePlaceToWork do@moduledoc false
# DO SOMETHING
end# ✅ Good
defmodule Jungsoft.NicePlaceToWork do
@moduledoc false# DO SOMETHING
end
```The module `end` should not contain a blank space either.
```elixir
# ❌ Bad
defmodule Jungsoft.BestPeople do
@moduledoc falsedef foo do
true
endend
# ✅ Good
defmodule Jungsoft.BestPeople do
@moduledoc falsedef foo do
true
end
end
```#### Function
Different functions should contain exactly one blank space between each other.
```elixir
# ❌ Bad
defmodule Jungsoft.GoodCoffee do
@moduledoc falsedef foo, do: true
def bar, do: true
def func, do: true
end# ✅ Good
defmodule Jungsoft.GoodCoffee do
@moduledoc falsedef foo, do: true
def bar, do: true
def func, do: true
end
```Functions should not contain a blank line between the function call and the parameters. In addition, they should not end with a blank line.
```elixir
# ❌ Bad
defmodule Jungsoft.BeautifulOfficeView do
@moduledoc falsedef foo do
1 + 1
end
end# ✅ Good
defmodule Jungsoft.BeautifulOfficeView do
@moduledoc falsedef foo do
1 + 1
end
end
```#### With
The `with do` parameters should not be separated by blank spaces. Except when `else` contains multiple options. In this case should use the same logic as `case` and `cond` normal style (see [here](https://github.com/christopheradams/elixir_style_guide#multiline-case-clauses)).
```elixir
# ❌ Bad
with %StarWars{} <- Jungsoft.function_1(),
true <- Jungsoft.function_2()
do## DO SOMETHING
else
%StarTrek{} ->
{:error, "Wrong choice"}false ->
## DO SOMETHINGend
# ✅ Good
with %StarWars{} <- Jungsoft.function_1(),
true <- Jungsoft.function_2()
do
## DO SOMETHING
else
%StarTrek{} ->
{:error, "Wrong choice"}false ->
## DO SOMETHING
end
```[Back to top ⬆️](#table-of-contents)
## Breaking Lines
When an enumerable contains more than 3 arguments, it should be broken into multiple lines. See an example for Lists below.
```elixir
# ❌ Bad
list = ["value1", "value2", "value3", "value4"]# ✅ Good
list = [
"value1",
"value2",
"value3",
"value4",
]# ✅ Good
list = ["value1", "value2", "value3"]
``````elixir
# ❌ Bad
map = %{a: 1, b: 2, c: 3, d: 4}# ✅ Good
map = %{
a: 1,
b: 2,
c: 3,
d: 4,
}# ✅ Good
map = %{a: 1, b: 2, c: 3}
```**This is also valid for Keyword Lists.**
[Back to top ⬆️](#table-of-contents)
## Dangling Commas
Objects with the possibility to span in multiple lines should contain a comma dangle in the last parameter. See an example of lists below.
```elixir
# ❌ Bad
list = [
"value1",
"value2",
"value3",
"value4"
]# ✅ Good
list = [
"value1",
"value2",
"value3",
"value4",
]
```**This is also valid for Maps and Keyword Lists.**
[Back to top ⬆️](#table-of-contents)
## Moduledocs
Modules that are meant to be public and used across the application (e.g. phoenix contexts, ecto schemas) must have a `@moduledoc` with a description (not `false`). Modules that are meant to be private for a specific context (e.g. an adapter for a public service), must have a `@moduledoc false`. See more about this here: https://hexdocs.pm/elixir/writing-documentation.html#hiding-internal-modules-and-functions
```elixir
# ❌ Bad
defmodule Jungsoft.Accounts do
@moduledoc false# Public functions for the Accounts context
end# ❌ Bad
defmodule Jungsoft.Storage.S3Adapter do
@moduledoc """
Adapter for AWS S3
"""# Functions that must be used only in the Storage context
end# ✅ Good
defmodule Jungsoft.Accounts do
@moduledoc """
The Accounts context that manipulates the users of the application.
"""# Public functions for the Accounts context
end# ✅ Good
defmodule Jungsoft.Storage.S3Adapter do
@moduledoc false# Functions that must be used only in the Storage context
end
```[Back to top ⬆️](#table-of-contents)
## 'With do' Indentation
#### Space
When `with do` contains multiple lines, it's necessary to add two blank spaces before the first parameter. This is only valid when editor tab size is **2**. If you followed the Jungsoft guidelines this should be your case. 😊
```elixir
# ❌ Bad
with true <- Jungsoft.function_1(),
false <- Jungsoft.function_2()
do
## DO SOMETHING
end# ❌ Bad
with true <- Jungsoft.function_1(),
false <- Jungsoft.function_2()
do
## DO SOMETHING
end# ❌ Bad
with true <- Jungsoft.function_1() do
## DO SOMETHING
end# ✅ Good
with true <- Jungsoft.function_1(),
false <- Jungsoft.function_2()
do
## DO SOMETHING
end# ✅ Good
with true <- Jungsoft.function_1() do
## DO SOMETHING
end
```[Back to top ⬆️](#table-of-contents)
# Schemas
The schemas should respect a pattern for organizing the parameters.
Independent of the schema type, the parameters should be grouped by type:
```elixir
# ❌ Bad
schema "foo" do
field :name, :stringfield :age, :integer
has_one :one, Bar
has_one :two, Module
timestamps()
end# ✅ Good
schema "foo" do
field :name, :string
field :age, :integerhas_one :one, Bar
has_one :two, Moduletimestamps()
end
```The other patterns are different based on the type of schema (Ecto or GraphQL). These differences are listed below.
## Ecto Schema
The Ecto schema parameters need to be organized in a order of importance:
| Importance | Field |
|---|---|
| 1º | field |
| 2º | belongs_to |
| 3º | has_one |
| 4º | has_many |
| 5º | timestamps |In this way, `field` should be inserted before `belongs_to`, and so on.
## GraphQL Schema
The GraphQL schema parameters need to be organized in a order of importance:
| Importance | Field |
|---|---|
| 1º | normal fields |
| 2º | custom fields (with the `resolve`) |
| 3º | associations |In this way, `normal fields` should be inserted before `custom fields`, and so on.
Remember, the first schema rule should be respected here as well (see [here](#schemas)). Therefore, `normal fields` should be grouped and separated with a blank space. Same is valid with `custom fields` and `associations`.
[Back to top ⬆️](#table-of-contents)