Rebar3’s system is based on the concept of providers. A provider has three callbacks: init(State) -> {ok, NewState}, which helps set up the state required, state dependencies, etc. do(State) -> {ok, NewState} | {error, Error}, which does the actual work. format_error(Error) -> String, which prints errors when they happen, and to filter out sensitive elements from the state. A provider should also be an OTP Library application, which can be fetched as any other Erlang dependency, except for ...