Юра Жлоба для 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
ebin, include, src, priv
Сборка
ebin, include, src, priv
c_src, deps, test
Сборка
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
Сборка
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
Сборка релизов
Вопросы?
Top Related