Formatted errors can accidentally contain substrings which are control
sequences for io:format/2. This is a naive attempt to handle such cases.
One example is running xref on the following module
(assuming module m does not exist)
```
-module(handle_error).
-export([f/0]).
f() -> m:'bobby~stables'().
```
```
$ rebar3 xref
===> Verifying dependencies...
===> Compiling myapp
===> Running cross reference analysis...
escript: exception error: bad argument
in function io:format/3
called as io:format(<0.23.0>,
"\e[0;31m===> \e[1mWarning: handle_error:f/0 is unused export (Xref)\nWarning: handle_error:f/0 calls undefined function m:bobby~stables/0 (Xref)\n\n\e[0m\e[0m",
[])
in call from rebar3:handle_error/1 (/Users/gomoripeti/git/rebar3/_build/default/lib/rebar/src/rebar3.erl, line 279)
```
The current code could not cope with missing dependencies, as they would
prevent the rebar3 app from loading or properly building its config,
which prevented the log state from being carried along with default
values. This in turn would turn in an escript-level error that
obfuscated the true source of failure.
This patch bypasses the whole state setup and logging macros and logs an
error message manually when a dependency such as crypto or SSL is
missing from the Erlang install.
Breaking up initial call to parse from the ones deep inside the provider
parsing to do smarter namespace detection, added 'as' the ability to
look into these also, and cleaned up the code a whole lot that would
depend on implicit assumptions.
A side-effect is that 'do' is now valid for all namespaces, although it
can be overriden.