- How do I use rebar3 format outside of a rebar3 project?
- This hex.pm project's source is a broken link. Can I still use it?
- Why doesn't elvis like records in type specs?
How do I use rebar3 format outside of a rebar3 project?
You pick up Erlang. You want all your usual tools with it. One of those tools is auto-formatting. Does Erlang have an auto-formatter? It does! Can you use it? ... With some effort, you can. But, seemingly, you can't use it as like a normal auto-formatter. These tools document industrial use but not one-off use!
You can use it as you expected, though, if you add it as a rebar3-wide plugin:
$ cat ~/.config/rebar3/rebar.config
{plugins, [
{rebar3_format, "1.3.0"}
]}.
{format, [{formatter, default_formatter}, {options, #{inline_clause_bodies => true}}]}.
With that configuration in place, the following just works:
$ cat h1.erl
-module(h1).
-export([hello/0, hello/1]).
hello() ->
hello("world").
hello(Name) ->
io:fwrite("Hello, ~s!~n", [Name]).
$ rebar3 format --files=h1.erl
$ cat h1.erl
-module(h1).
-export([hello/0, hello/1]).
hello() -> hello("world").
hello(Name) -> io:fwrite("Hello, ~s!~n", [Name]).
Or delete the last line of that rebar3.config to get the first h1.erl as the formatted result.
An alternative is erlfmt:
{plugins, [
{erlfmt, "1.3.0"}
]}.
{erlfmt, [write]}.
With this rebar3.config in place, this works:
$ cat h1.erl
-module(h1).
-export([hello/0, hello/1]).
hello() -> hello("world").
hello(Name) -> io:fwrite("Hello, ~s!~n", [Name]).
what_is(Erlang) -> case Erlang of movie -> [hello(mike, joe, robert), credits]; language -> formatting_arguments end.
$ rebar3 fmt h1.erl
$ cat h1.erl
-module(h1).
-export([hello/0, hello/1]).
hello() -> hello("world").
hello(Name) -> io:fwrite("Hello, ~s!~n", [Name]).
what_is(Erlang) ->
case Erlang of
movie -> [hello(mike, joe, robert), credits];
language -> formatting_arguments
end.
This hex.pm project's source is a broken link. Can I still use it?
You can, because hex.pm is a separate host of the projects published on it. You can also explore them, f.e. https://preview.hex.pm/preview/fossil/0.1.0 has a file selector at the top that includes all of fossil 0.1.0's assets.
Why doesn't elvis like records in type specs?
I get this complaint from elvis:
- The spec in line 20 uses a record, please define a type for the record and use that instead.
about this code:
-record(session, {
active :: 1..5,
stacks :: {list(#vocab{}), list(#vocab{}), list(#vocab{}), list(#vocab{}), list(#vocab{})}
-spec save(#session{}) -> 'ok'. % line 20
What's elvis's problem, hah? Typespecs support records. Dialyzer works with this. Why shouldn't I use it?
https://youtu.be/yAkvVHnAKNI?t=733 goes into a reason why, and seems to amount to dialyzer treating record types as invariants, enforced within functions, whereas other type specs are enforced only at function boundaries.