Slide 1

Slide 1 text

3 > 2 MARK ALLEN | @BYTEMEORG | [email protected]

Slide 2

Slide 2 text

CONTEXT ¡ Rebar was a build tool started in 2009 – had widespread community adoption ¡ Organically grew from a straight forward build tool to encompass all sorts of Erlang compilation tasks including C, protobufs, parse transformations and more. ¡ This organic growth and feature additions made it difficult to override and extend behaviors. ¡ Sometimes dependency management was especially frustrating (“meck hell”) ¡ Lack of a clear repeatable build system was also quite frustrating

Slide 3

Slide 3 text

REBAR3 ¡ Major rework of the original tool. Rebar3 broke compatibility in some ways. That’s why it had to be a completely separate tool. Big changes include: ¡ Moving many compilers into plugins (protobufs, C, ErlyDTL templates and more) ¡ Using relx instead of reltool to build releases ¡ Always providing a “lock” file full of specific library commits for repeatable builds ¡ Integration with the hex.pm package repository service ¡ The ability to use profiles and composition to assume a profile ¡ Was adopted by the Ericsson OTP team

Slide 4

Slide 4 text

STORY TIME

Slide 5

Slide 5 text

DEPENDENCIES ¡ No need to explicitly fetch dependencies, rebar will decide whether it needs dependencies to complete a task and (usually) do the right thing ¡ Integration with hex ¡ Can keep the “traditional” specification if you want ¡ Move some dependencies into profiles: one for test, one for edoc ¡ rebar.lock keeps your build repeatable – always use the same version of a dependency unless you explicitly ask for upgrades

Slide 6

Slide 6 text

REBAR3 SHELL ¡ My favorite thing ever!!111eleven!! ¡ Checks your dependencies, compiles your code, and pops you right into an Erlang shell ¡ One command! ¡ It’s the

Slide 7

Slide 7 text

INTEGRATION WITH HEX ¡ rebar3_hex plugin ¡ Add to your global rebar.config in ~/.config/rebar3/rebar.config {plugins, [rebar3_hex]}. ¡ Register yourself: rebar3 hex user register

Slide 8

Slide 8 text

ADD HEX METADATA TO YOUR .APP.SRC {application, gisla, [{description, "Sagas for Erlang"}, {vsn, "2.0.0"}, {registered, []}, {applications, [kernel, stdlib, hut]}, {env,[]}, {modules, []}, {maintainers, ["Mark Allen"]}, {licenses, ["MIT"]}, {links, [{"Github", "https://github.com/mrallen1/gisla"}]} ]}.

Slide 9

Slide 9 text

PUBLISH YOUR CODE TO HEX $ rebar3 hex publish ===> Verifying dependencies... Publishing gisla 2.0.0 Description: Sagas for Erlang Dependencies: hut 1.2.0 Included files: gisla/LICENSE gisla/README.md gisla/include/gisla.hrl gisla/rebar.config gisla/rebar.lock gisla/src/gisla.app.src gisla/src/gisla.erl Maintainers: Mark Allen Licenses: MIT Links: Github: https://github.com/mrallen1/gisla Build tools: rebar3 Before publishing, please read Hex CoC: https://hex.pm/policies/codeofconduct Proceed? ("Y")>

Slide 10

Slide 10 text

RELEASES USING RELX ¡ rebar2 uses “reltool” which is bundled with OTP ¡ rebar3 uses “relx” which has a easier to understand syntax ¡ Might not need a “release” section if you’re building libraries

Slide 11

Slide 11 text

RELEASE CONFIG {{relx, [{release, {udon, "0.1.0"}, [udon, cowboy, jsone, cuttlefish, sasl]}, {dev_mode, true}, {include_erts, false}, {overlay_vars, "./config/vars.config"}, {overlay, [ {mkdir, "etc"}, {mkdir, "bin"}, {mkdir, "data/ring"}, {mkdir, "log/sasl"}, {template, "./config/admin_bin", "bin/udon-admin"}, {template, "./config/advanced.config", "etc/advanced.config"} ]}] }.

Slide 12

Slide 12 text

RELEASE ARTIFACTS ¡ rebar3 release (dev mode on) ¡ rebar3 as prod release tar (dev mode off)

Slide 13

Slide 13 text

TEMPLATES $ rebar3 new app (built-in): Complete OTP Application structure. cmake (built-in): Standalone Makefile for building C/C++ in c_src escript (built-in): Complete escriptized application structure lib (built-in): Complete OTP Library application (no processes) structure plugin (built-in): Rebar3 plugin project structure rebar3_riak_core (custom): Rebar3 Riak Core Application release (built-in): OTP Release structure for executable programs umbrella (built-in): OTP structure for executable programs (alias of 'release' template)

Slide 14

Slide 14 text

TEMPLATES $ rebar3 new app (built-in): Complete OTP Application structure. cmake (built-in): Standalone Makefile for building C/C++ in c_src escript (built-in): Complete escriptized application structure lib (built-in): Complete OTP Library application (no processes) structure plugin (built-in): Rebar3 plugin project structure rebar3_riak_core (custom): Rebar3 Riak Core Application release (built-in): OTP Release structure for executable programs umbrella (built-in): OTP structure for executable programs (alias of 'release' template)

Slide 15

Slide 15 text

TEMPLATE VARIABLES $ rebar3 new help app app: built-in template Description: Complete OTP Application structure. Variables: name="mylib" (Name of the OTP application) desc="An OTP application" (Short description of the app) date="2017-11-08" datetime="2017-11-08T02:35:13+00:00" author_name="Mark Allen" author_email=”[email protected]" copyright_year="2017" apps_dir="apps" (Directory where applications will be created if needed)

Slide 16

Slide 16 text

TEMPLATES USE MUSTACHE SYNTAX -module({{name}}_test). -include_lib("eunit/include/eunit.hrl”). %% Hello this is a very silly rebar3 template example {{name}}_test() -> ?assert( 2 == 2 ). Templates should be installed in ~/.config/rebar3/templates/<>/<>.tpl

Slide 17

Slide 17 text

CUSTOM REBAR3 PLUGINS ¡ Huge topic – too much to cover, but the basics are easy and straight forward ¡ Plugins are modeled on a “provider” library with a behaviour. You implement three callback functions ¡ init(State) -> {ok, NewState} ¡ do(State) -> {ok, NewState} | {error, Error} ¡ format_error(Error) -> string() ¡ Built in rebar3 template for new plugins. ¡ Plugins can also have their own template files ¡ Can be a huge help for “in house” Erlang frameworks ¡ https://bitbucket.org/ferd/rebar3-todo-plugin

Slide 18

Slide 18 text

PLUGIN INITIALIZATION -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. init(State) -> Provider = providers:create([ {name, ?PROVIDER}, % The 'user friendly' name of the task {module, ?MODULE}, % The module implementation of the task {bare, true}, % The task can be run by the user, always true {deps, ?DEPS}, % The list of dependencies {example, "rebar3 todo"}, % How to use the plugin {opts, [ % list of options understood by the plugin {deps, $d, "deps", undefined, "also run against dependencies"} ]}, {short_desc, "Reports TODOs in source code"}, {desc, "Scans top-level application source and find ” "instances of TODO: in commented out content " "to report it to the user."} ]), {ok, rebar_state:add_provider(State, Provider)}.

Slide 19

Slide 19 text

PLUGIN ACTION -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. do(State) -> Apps = case discovery_type(State) of project -> rebar_state:project_apps(State); deps -> rebar_state:project_apps(State) ++ lists:usort(rebar_state:all_deps(State)) end, lists:foreach(fun check_todo_app/1, Apps), {ok, State}.

Slide 20

Slide 20 text

PLUGIN FORMAT ERROR -spec format_error(any()) -> iolist(). format_error(Reason) -> io_lib:format("~p", [Reason]).

Slide 21

Slide 21 text

CONVERTING TO REBAR3 ¡ Checklist ¡ Update dependencies to “new” style ¡ Move test and doc dependencies into their own profiles ¡ If needed, include relx directives to your application ¡ Provide rebar2 compatibility ¡ Example: lager

Slide 22

Slide 22 text

LAGER REBAR3 CONFIG {eunit_opts, [verbose]}. {eunit_compile_opts, [ export_all, nowarn_untyped_record, nowarn_export_all ]}. {deps, [ {goldrush, "0.1.9"} ]}.

Slide 23

Slide 23 text

LAGER REBAR3 CONFIG {eunit_opts, [verbose]}. {eunit_compile_opts, [ export_all, nowarn_untyped_record, nowarn_export_all ]}. {deps, [ {goldrush, "0.1.9"} ]}.

Slide 24

Slide 24 text

LAGER REBAR2 COMPATIBILITY $ cat rebar.config.script case erlang:function_exported(rebar3, main, 1) of true -> % rebar3 CONFIG; false -> % rebar 2.x or older %% Rebuild deps, possibly including those that have been moved to %% profiles [{deps, [ {goldrush, ".*", {git, "https://github.com/DeadZen/goldrush.git", {tag, "0.1.9"}}} ]} | lists:keydelete(deps, 1, CONFIG)] end.

Slide 25

Slide 25 text

REBAR3 DEBUGGING DEBUG=1 rebar3 compile

Slide 26

Slide 26 text

REBAR3 RESOURCES ¡ http://www.rebar3.org ¡ http://github.com/erlang/rebar3 ¡ The #rebar channel on IRC freenode ¡ Introduction to rebar3 (Erlang Factory SF 2015): https://www.youtube.com/watch?v=v_boPIY9y-8 ¡ From rebar2 to rebar3 (Erlang Factory SF 2016): https://www.youtube.com/watch?v=-tF1DyN8o7Q ¡ https://hex.pm

Slide 27

Slide 27 text

THANK YOU! QUESTIONS?