Все, что вы хотели знать о Rebar, но ленились прочитать

Preview:

Citation preview

Юра Жлоба для Erlang Dnipro 2014

Все, что вы хотели знать о Rebar, но ленились прочитать :)

Rebar – это арматура для железобетонных конструкций

http://en.wikipedia.org/wiki/Rebar

Известный инструмент для сборки Erlang-проектов

https://github.com/rebar/rebar/

Rebar умеет

Собирать Erlang-сорцы

Собирать С/C++ сорцы (драйвера)

Собирать ErlyDTL шаблоны

Собирать Protocol Buffers определения

Rebar умеет

Создавать модули из шаблонов

Создавать релизы

Управлять зависимостями

Запускать тесты (EUnit и Common Test)

Генерировать документацию

Rebar это

Один исполняемый файлик

cкачал, положил в проект

или в PATH

и запускай :)

Rebar это

Популярный проект на github

https://github.com/rebar/rebar/

117 контрибуторов

100 форков

12600 строк кода

Как его освоить?

Wiki-документация в проекте на github

https://github.com/rebar/rebar/wiki

Как его освоить?

Встроенная документация

rebar help

rebar --commands

rebar help compilerebar help get-depsrebar help eunit

Как его освоить?

Доклад Dizzy Smith

Erlang разработчика из Basho

на Erlang User Conference 2012

Applied Rebar

Как его освоить?

Смотреть в исходный код.

Некоторые вещи можно узнать только оттуда.

Например, опции сборкиErlyDTL шаблонов

Как его освоить?

Все эти источники не полны

Нельзя просто взять, и прочитатьвсе про Rebar в одном месте по порядку

Как его освоить?

Мой доклад исправляет этот недостаток :)

Основные команды

Начать очень просто

Нам хватит 4-х команд

Основные команды

Вытягиваем зависимости

rebar get-deps

Основные команды

Собираем проект

rebar compile

Основные команды

Запускаем тесты

rebar eunit

Основные команды

Очищаем проект

rebar clean

Основные команды

И одна опция

skip_deps=true

Основные команды

rebar get-deps

rebar compile

rebar compile skip_deps=true

rebar eunit skip_deps=true

rebar clean skip_deps=true

Основные команды

4 команды и одна опцияи вы знатоки Rebar :)

rebar get-depsrebar compile rebar compile skip_deps=truerebar eunit skip_deps=truerebar clean skip_deps=true

Сборка

соблюдаем

OTP Design Principles

Сборка

OTP Design Principles

ebin, include, src, priv

Сборка

ebin, include, src, priv

c_src, deps, test

Сборка

Erlc

http://www.erlang.org/doc/man/erlc.html

Сборка

erlc -I include -o ebin src/*.erl

Сборка

-I include

-o ebin

-DNAME=value

-Werror

src/*erl

Сборка

ebin/myapp.app

{application,metalkia, [{description,"web blog platform"}, {vsn,"1"}, {registered,[]}, {applications,[kernel,stdlib]}, {mod,{metalkia_app,[]}}, {env,[]}, {modules, [main_handler,metalkia_app,metalkia_sup]}]}.

Сборка

src/myapp.app.src

{application,metalkia, [{description,"web blog platform"}, {vsn,"1"}, {registered,[]}, {applications,[kernel,stdlib]}, {mod,{metalkia_app,[]}}, {env,[]}, {modules, []}]}.

Сборка

C/C++

c_src

Сборка

ErlyDTL

templates/*.dtl ebin/*_dtl.beam→

Сборка

Google Protocol Buffers

src/*.proto →ebin/*_pb.beam, include/*_pb.hrl

Управление зависимостями

{deps, [Dependency1, Dependency2, Dependency3]}.

Управление зависимостями

Dependency:

{App, VsnRegex, Source}

Управление зависимостями

Source:

{git, Url, Rev}{hg, Url, Rev}{bzr, Url, Rev}

Управление зависимостями

Revision:

{branch, "master"}

{tag, "v1.0"}

"62b7c9b12daacfcbcf274bc0925a7f8d10e3a1e0"

"v1.0"

"HEAD"

""

Управление зависимостями

{deps, [ {emysql, ".*", {git, "https://github.com/Eonblast/Emysql.git", "62b7c9b12daacfcbcf274bc0925a7f8d10e3a1e0"}}, {mcd, ".*", {git, "https://github.com/EchoTeam/mcd.git", "f72ebf5006e1b1234e16f86514e4291c57506024"}}, {cowboy, ".*", {git, "https://github.com/extend/cowboy", "0.8.6"}}, {mimetypes, ".*", {git, "git://github.com/spawngrid/mimetypes.git", {branch, "master"}}}, {lager, ".*", {git, "https://github.com/basho/lager.git", "2.0.1"}}, {ux, ".*", {git, "https://github.com/erlang-unicode/ux.git", "v3.4.1"}} ]}.

Управление зависимостями

Зависимость от tag или commitХорошо

Зависимость от “HEAD”, {branch, “master”}не очень хорошо :(

Управление зависимостями

Все зависимости сами должны бытьRebar проектами

транзитивные тоже

Управление зависимостями

Не rebar зависимость должна быть помечена [raw]

{somelib, ".*", {git, "https://somewhere.com/somelib.git", "v1.0"},

[raw]}

Управление зависимостями

rebar check-deps

rebar list-deps

rebar update-deps

rebar delete-deps

Шаблоны

rebar create template= [var=foo,...]

Шаблоны

rebar create template=simpleapp appid=myapp

rebar create template=simplesrv srvid=my_server

Шаблоны

rebar create-app appid=myapp

rebar create-node nodeid=mynode

Шаблоны

rebar list-templates

Шаблоны

rebar list-templates==> tmp (list-templates) * simplesrv: priv/templates/simplesrv.template (escript) (variables: "srvid") * simplenode: priv/templates/simplenode.template (escript) (variables: "nodeid") * simplemod: priv/templates/simplemod.template (escript) (variables: "modid") * simplefsm: priv/templates/simplefsm.template (escript) (variables: "fsmid") * simpleapp: priv/templates/simpleapp.template (escript) (variables: "appid") * ctsuite: priv/templates/ctsuite.template (escript) (variables: "testmod") * basicnif: priv/templates/basicnif.template (escript) (variables: "module")

Шаблоны

rebar create template=simpleapp appid=coolstuff ==> coolstuff (create) Writing src/coolstuff.app.src Writing src/coolstuff_app.erl Writing src/coolstuff_sup.erl yura ~/p/coolstuff $ tree . └── src ├── coolstuff_app.erl ├── coolstuff.app.src └── coolstuff_sup.erl

1 directory, 3 files

Шаблоны

rebar create template=simplesrv srvid=my_server ==> coolstuff (create) Writing src/my_server.erl yura ~/p/coolstuff $ cat src/my_server.erl -module(my_server). -behaviour(gen_server). -define(SERVER, ?MODULE). ...

Шаблоны

rebar create template=simplemod modid=my_cool_module ==> coolstuff (create) Writing src/my_cool_module.erl Writing test/my_cool_module_tests.erl yura ~/p/coolstuff $ cat src/my_cool_module.erl -module(my_cool_module).

-export([my_func/0]).

my_func() -> ok. yura ~/p/coolstuff $ cat test/my_cool_module_tests.erl -module(my_cool_module_tests). -include_lib("eunit/include/eunit.hrl").

Шаблоны

yura ~/p/rebar/priv/templates $ ls -1 *.template

basicnif.template

ctsuite.template

simpleapp.template

simplefsm.template

simplemod.template

simplenode.template

simplesrv.template

Шаблоны

yura ~/p/rebar/priv/templates $ ls -1 simpleapp* simpleapp_app.erl simpleapp.app.src simpleapp_sup.erl simpleapp.template

yura ~/p/rebar/priv/templates $ cat simpleapp.template {variables, [{appid, "myapp"}]}. {template, "simpleapp.app.src", "src/{{appid}}.app.src"}. {template, "simpleapp_app.erl", "src/{{appid}}_app.erl"}. {template, "simpleapp_sup.erl", "src/{{appid}}_sup.erl"}.

Шаблоны

simpleapp -- создает приложение

simplesrv -- создает gen_server модуль

simplemod -- создает пустой модуль

Шаблоны

simplefsm -- создает gen_fsm модуль

basicnif -- создает порт, erlang-модуль и с-файл

ctsuite -- создает common test suite модуль

simplenode -- создает файлы для релиза

Шаблоны

~/.rebar/templates

либо клонировать rebar

Тестирование

rebar eunit

Тестирование

rebar eunit skip_deps=true

Тестирование

rebar eunit skip_deps=truesuites=module1_test

Тестирование

rebar eunit skip_deps=truesuites=”module1_test,module2_test”

Тестирование

rebar eunit skip_deps=truesuites=module1_testtests=some_test_fun

Тестирование

rebar ct \[suites=\] \[case=\]

rebar.config

http://www.erlang.org/doc/man/compile.html

{erl_opts, [debug_info, warn_export_all, warn_missing_spec, warning_as_errors, {d, MY_MACRO, Value}, {parse_transform, lager_transform} ]}.

rebar.config

src_dir

deps_dir

target_dir

{erl_opts, [{i, "my_include"}]}

rebar.config

Вложенные OTP-приложения

{lib_dirs, ["deps", "apps"]}.

{sub_dirs, ["apps/app1", "apps/app2"]}.

rebar.config

{cover_enabled, true}.

{clean_files, ["erl_crash.dump"]}.

rebar.config

Настройки документированы слабо

В чужих конфигах встречаются нигде не описанные опции

Большинство настроек не нужно

rebar.config

Нужно:

{deps, []}.

warning_as_error

{parse_transform, lager_transform}

и все :)

Escipt

Создание и запуск

консольных приложений

на Erlang

Escipt

Я делаю такие приложения

на Bash или Python,

но ...

Escipt

Rebar сам является

escript приложением

Escipt

#!/usr/bin/env escript

%%! -pa rebar/rebar/ebin

полезная нагрузка

Escipt

Исходный код Erlang

Скомпилированный beam-файл

Zip-архив с beam-файлами

Escipt

Rebar представляет собой Zip-архив

и его можно распаковать :)

только сперва нужно переименовать

Escipt

mv rebar rebar_file

unzip rebar_file

Escipt

Archive: rebar_file warning [rebar_file]: 51 extra bytes at beginning or within zipfile (attempting to process anyway) creating: rebar/ creating: rebar/ebin/ inflating: rebar/ebin/getopt.beam inflating: rebar/ebin/mustache.beam inflating: rebar/ebin/rebar.app inflating: rebar/ebin/rebar.beam ... creating: priv/ creating: priv/templates/ inflating: priv/templates/basicnif.c inflating: priv/templates/basicnif.erl inflating: priv/templates/basicnif.template ...

Прочее

rebar xref

rebar qc

rebar doc

Сборка релизов

Вопросы?

Recommended