This release took a while to build; OTP-25.1 had incompatibilities with EUnit that interrupted the CI process, and which are corrected in later releases.
This new vendor structure should be of no impact to anyone using Rebar3 as a built artifact, but should make the life of corporate users and package managers much easier by having pre-bundled in all dependencies and allowing effective offline builds. It also simplifies our bootstrap code and reduces security issues by not having to download a certificate bundle without certificates, at least until our oldest supported version can use Erlang’s new built-in on-host certificate lookup mechanisms.
If you do rely on Rebar3 source for your tooling or any other mechanisms, then you will want to cd apps/rebar before running other commands.
Tonight I just cut another release (3.22.0) for a Windows patch that was breaking the shell, but I snuck in an optional improvement to compiler output:
Given the module:
-module(fake_mod).
-export([diagnostic/1]).
diagnostic(A) ->
X = add(5 / 0),
{X,X}.
add(X) -> X.
add(X, Y) -> X + Y.
Calling rebar3 compile can now yield:
...
===> Compiling apps/rebar/src/fake_mod.erl failed
┌─ apps/rebar/src/fake_mod.erl:
│
5 │ diagnostic(A) ->
│ ╰── variable 'A' is unused
┌─ apps/rebar/src/fake_mod.erl:
│
6 │ X = add(5 / 0),
│ ╰── evaluation of operator '/'/2 will fail with a 'badarith' exception
┌─ apps/rebar/src/fake_mod.erl:
│
11 │ add(X, Y) -> X + Y.
│ ╰── function add/2 is unused
By default, this format is turned off, but can be turned on optionally by configuring values with the following:
{compiler_error_format, rich}.
You may want to put it in your global rebar3 config file. That being said, this may break some tooling that could parse rebar3-specific output. The default value is {compiler_error_format, minimal}. and putting that value back in should fix any breakage. We’re also expecting color output to have a few bugs related to a rather naive heuristic used to delimit language constructs, but we wanted to make the feature available for feedback and this bug-fixing release was a decent opportunity.
This functionality relies on an expanded compiler API exposed by Rebar3, but since we’re not yet quite sure what form we want it to take, we’ll keep the new API undocumented in the short term.
Speaking of which, has anyone spent time using the rich compiler output? My own experience had been good and I was thinking of turning it on by default but wanted to check first.
Only issue I’ve had is our ancient Latin-1 environment at work stumbling over the output, but I guess we’re the very last non-UTF-8 users in this world.
which are clearly misaligned and if we for example delete function definition of diagnostic/1 but leave it in -export attribute then export error is presented like:
So this is dependent on scoping structures and coding style a bit. In larger code bases and with some functional patterns this can be seen as regression in representation of errors. However, if this can be fixed i would also like this mode to be set as default as it is, in many cases, big improvement.
This might actually be a tab width issue. The problem here is that I’m using the compiler error that gives you a line number and the nth character to work with, and I assume they’re all mono-spaced. Obviously tab characters aren’t the same and the analysis is currently missing that bit for the alignment.
That’s likely fixable, but a bit more work than the current thing. Good call-out.
After receiving no further comments on the compiler error format, I’ve just merged the PR in main, so any fresh (non-release) version of rebar3 installed will have the cool new errors.
Is there a way to disable rich error messages, as well as “Line X Column Y” error format for dialyzer, globally?
Explanation: 99% of the time I run builds in the Emacs shell, and I have scripts for opening sources of compile errors and stacktraces. However, the fancier error messages become, the uglier regexps I have to write for these scripts. It would be nice to always get errors in machine-readable form instead.
You just need to put this line in your global rebar3 config file:
{compiler_error_format, minimal}.
But the column number now comes stock from the erlang compiler so it might still be a component, just shown more simply — this is what Dialyzer returns directly. I think there’s an output_format param, but it’s either formatted or raw, but the column will be there regardless.