| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- -module('rebar.config').
- -export([do/2]).
- do(Dir, CONFIG) ->
- case iolist_to_binary(Dir) of
- <<".">> ->
- C1 = deps(CONFIG),
- Config = dialyzer(C1),
- maybe_dump(Config ++ [{overrides, overrides()}] ++ coveralls() ++ config());
- _ ->
- CONFIG
- end.
- bcrypt() ->
- {bcrypt, {git, "https://github.com/emqx/erlang-bcrypt.git", {branch, "0.6.0"}}}.
- quicer() ->
- {quicer, {git, "https://github.com/emqx/quic.git", {tag, "0.0.9"}}}.
- deps(Config) ->
- {deps, OldDeps} = lists:keyfind(deps, 1, Config),
- MoreDeps = [bcrypt() || provide_bcrypt_dep()] ++
- [quicer() || is_quicer_supported()],
- lists:keystore(deps, 1, Config, {deps, OldDeps ++ MoreDeps}).
- overrides() ->
- [ {add, [ {extra_src_dirs, [{"etc", [{recursive,true}]}]}
- , {erl_opts, [{compile_info, [{emqx_vsn, get_vsn()}]}]}
- ]}
- ] ++ snabbkaffe_overrides().
- %% Temporary workaround for a rebar3 erl_opts duplication
- %% bug. Ideally, we want to set this define globally
- snabbkaffe_overrides() ->
- Apps = [snabbkaffe, ekka, mria],
- [{add, App, [{erl_opts, [{d, snk_kind, msg}]}]} || App <- Apps].
- config() ->
- [ {cover_enabled, is_cover_enabled()}
- , {profiles, profiles()}
- , {plugins, plugins()}
- ].
- is_cover_enabled() ->
- case os:getenv("ENABLE_COVER_COMPILE") of
- "1"-> true;
- "true" -> true;
- _ -> false
- end.
- is_enterprise(ce) -> false;
- is_enterprise(ee) -> true.
- is_quicer_supported() ->
- not (false =/= os:getenv("BUILD_WITHOUT_QUIC") orelse
- is_win32() orelse is_centos_6()
- ).
- is_centos_6() ->
- %% reason:
- %% glibc is too old
- case file:read_file("/etc/centos-release") of
- {ok, <<"CentOS release 6", _/binary >>} ->
- true;
- _ ->
- false
- end.
- is_win32() ->
- win32 =:= element(1, os:type()).
- project_app_dirs(Edition) ->
- ["apps/*"] ++
- case is_enterprise(Edition) of
- true -> ["lib-ee/*"];
- false -> []
- end.
- plugins() ->
- [ {relup_helper,{git,"https://github.com/emqx/relup_helper", {tag, "2.0.0"}}}
- , {er_coap_client, {git, "https://github.com/emqx/er_coap_client", {tag, "v1.0.4"}}}
- %% emqx main project does not require port-compiler
- %% pin at root level for deterministic
- , {pc, {git, "https://github.com/emqx/port_compiler.git", {tag, "v1.11.1"}}}
- ]
- %% test plugins are concatenated to default profile plugins
- %% otherwise rebar3 test profile runs are super slow
- ++ test_plugins().
- test_plugins() ->
- [ {rebar3_proper, "0.12.1"}
- , {coveralls, {git, "https://github.com/emqx/coveralls-erl", {tag, "v2.2.0-emqx-1"}}}
- ].
- test_deps() ->
- [ {bbmustache, "1.10.0"}
- , {meck, "0.9.2"}
- , {proper, "1.4.0"}
- ].
- common_compile_opts() ->
- [ debug_info % alwyas include debug_info
- , {compile_info, [{emqx_vsn, get_vsn()}]}
- ] ++
- [{d, 'EMQX_BENCHMARK'} || os:getenv("EMQX_BENCHMARK") =:= "1" ].
- prod_compile_opts() ->
- [ compressed
- , deterministic
- , warnings_as_errors
- | common_compile_opts()
- ].
- prod_overrides() ->
- [{add, [ {erl_opts, [deterministic]}]}].
- profiles() ->
- Vsn = get_vsn(),
- [ {'emqx',
- [ {erl_opts, prod_compile_opts()}
- , {relx, relx(Vsn, cloud, bin, ce)}
- , {overrides, prod_overrides()}
- , {project_app_dirs, project_app_dirs(ce)}
- , {post_hooks, [{compile, "bash build emqx doc"}]}
- ]}
- , {'emqx-pkg',
- [ {erl_opts, prod_compile_opts()}
- , {relx, relx(Vsn, cloud, pkg, ce)}
- , {overrides, prod_overrides()}
- , {project_app_dirs, project_app_dirs(ce)}
- , {post_hooks, [{compile, "bash build emqx-pkg doc"}]}
- ]}
- , {'emqx-enterprise',
- [ {erl_opts, prod_compile_opts()}
- , {relx, relx(Vsn, cloud, bin, ee)}
- , {overrides, prod_overrides()}
- , {project_app_dirs, project_app_dirs(ee)}
- , {post_hooks, [{compile, "bash build emqx-enterprise doc"}]}
- ]}
- , {'emqx-enterprise-pkg',
- [ {erl_opts, prod_compile_opts()}
- , {relx, relx(Vsn, cloud, pkg, ee)}
- , {overrides, prod_overrides()}
- , {project_app_dirs, project_app_dirs(ee)}
- , {post_hooks, [{compile, "bash build emqx-enterprise-pkg doc"}]}
- ]}
- , {'emqx-edge',
- [ {erl_opts, prod_compile_opts()}
- , {relx, relx(Vsn, edge, bin, ce)}
- , {overrides, prod_overrides()}
- , {project_app_dirs, project_app_dirs(ce)}
- , {post_hooks, [{compile, "bash build emqx-edge doc"}]}
- ]}
- , {'emqx-edge-pkg',
- [ {erl_opts, prod_compile_opts()}
- , {relx, relx(Vsn, edge, pkg, ce)}
- , {overrides, prod_overrides()}
- , {project_app_dirs, project_app_dirs(ce)}
- , {post_hooks, [{compile, "bash build emqx-edge-pkg doc"}]}
- ]}
- , {check,
- [ {erl_opts, common_compile_opts()}
- , {project_app_dirs, project_app_dirs(ce)}
- ]}
- , {test,
- [ {deps, test_deps()}
- , {erl_opts, common_compile_opts() ++ erl_opts_i(ce) }
- , {extra_src_dirs, [{"test", [{recursive, true}]}]}
- , {project_app_dirs, project_app_dirs(ce)}
- ]}
- ].
- %% RelType: cloud (full size) | edge (slim size)
- %% PkgType: bin | pkg
- relx(Vsn, RelType, PkgType, Edition) ->
- [ {include_src,false}
- , {include_erts, true}
- , {extended_start_script,false}
- , {generate_start_script,false}
- , {sys_config,false}
- , {vm_args,false}
- , {release, {emqx, Vsn}, relx_apps(RelType, Edition)}
- , {overlay, relx_overlay(RelType, Edition)}
- , {overlay_vars, [ {built_on_arch, rebar_utils:get_arch()}
- , {emqx_description, emqx_description(RelType, Edition)}
- | overlay_vars(RelType, PkgType, Edition)]}
- ].
- emqx_description(cloud, ee) -> "EMQ X Enterprise Edition";
- emqx_description(cloud, ce) -> "EMQ X Community Edition";
- emqx_description(edge, ce) -> "EMQ X Edge Edition".
- overlay_vars(RelType, PkgType, _Edition) ->
- overlay_vars_rel(RelType) ++ overlay_vars_pkg(PkgType).
- %% vars per release type, cloud or edge
- overlay_vars_rel(RelType) ->
- VmArgs = case RelType of
- cloud -> "vm.args";
- edge -> "vm.args.edge"
- end,
- [ {vm_args_file, VmArgs}
- ].
- %% vars per packaging type, bin(zip/tar.gz/docker) or pkg(rpm/deb)
- overlay_vars_pkg(bin) ->
- [ {platform_bin_dir, "bin"}
- , {platform_data_dir, "data"}
- , {platform_etc_dir, "etc"}
- , {platform_lib_dir, "lib"}
- , {platform_log_dir, "log"}
- , {platform_plugins_dir, "plugins"}
- , {runner_root_dir, "$(cd $(dirname $(readlink $0 || echo $0))/..; pwd -P)"}
- , {runner_bin_dir, "$RUNNER_ROOT_DIR/bin"}
- , {runner_etc_dir, "$RUNNER_ROOT_DIR/etc"}
- , {runner_lib_dir, "$RUNNER_ROOT_DIR/lib"}
- , {runner_log_dir, "$RUNNER_ROOT_DIR/log"}
- , {runner_data_dir, "$RUNNER_ROOT_DIR/data"}
- , {runner_user, ""}
- , {is_elixir, "no"}
- ];
- overlay_vars_pkg(pkg) ->
- [ {platform_bin_dir, ""}
- , {platform_data_dir, "/var/lib/emqx"}
- , {platform_etc_dir, "/etc/emqx"}
- , {platform_lib_dir, ""}
- , {platform_log_dir, "/var/log/emqx"}
- , {platform_plugins_dir, "/var/lib/emqx/plugins"}
- , {runner_root_dir, "/usr/lib/emqx"}
- , {runner_bin_dir, "/usr/bin"}
- , {runner_etc_dir, "/etc/emqx"}
- , {runner_lib_dir, "$RUNNER_ROOT_DIR/lib"}
- , {runner_log_dir, "/var/log/emqx"}
- , {runner_data_dir, "/var/lib/emqx"}
- , {runner_user, "emqx"}
- , {is_elixir, "no"}
- ].
- relx_apps(ReleaseType, Edition) ->
- [ kernel
- , sasl
- , crypto
- , public_key
- , asn1
- , syntax_tools
- , ssl
- , os_mon
- , inets
- , compiler
- , runtime_tools
- , redbug
- , {hocon, load}
- , {emqx, load} % started by emqx_machine
- , {emqx_conf, load}
- , emqx_machine
- , {mnesia, load}
- , {ekka, load}
- , {emqx_plugin_libs, load}
- , {esasl, load}
- , observer_cli
- , system_monitor
- , emqx_http_lib
- , emqx_resource
- , emqx_connector
- , emqx_authn
- , emqx_authz
- , emqx_auto_subscribe
- , emqx_gateway
- , emqx_exhook
- , emqx_bridge
- , emqx_rule_engine
- , emqx_modules
- , emqx_management
- , emqx_dashboard
- , emqx_retainer
- , emqx_statsd
- , emqx_prometheus
- , emqx_psk
- , emqx_slow_subs
- , emqx_plugins
- ]
- ++ [quicer || is_quicer_supported()]
- %++ [emqx_license || is_enterprise(Edition)]
- ++ [bcrypt || provide_bcrypt_release(ReleaseType)]
- ++ relx_apps_per_rel(ReleaseType)
- %% NOTE: applications below are only loaded after node start/restart
- %% TODO: Add loaded/unloaded state to plugin apps
- %% then we can always start plugin apps
- ++ [{N, load} || N <- relx_plugin_apps(ReleaseType, Edition)].
- relx_apps_per_rel(cloud) ->
- [ xmerl
- | [{observer, load} || is_app(observer)]
- ];
- relx_apps_per_rel(edge) ->
- [].
- is_app(Name) ->
- case application:load(Name) of
- ok -> true;
- {error,{already_loaded, _}} -> true;
- _ -> false
- end.
- relx_plugin_apps(ReleaseType, Edition) ->
- relx_plugin_apps_per_rel(ReleaseType)
- ++ relx_plugin_apps_enterprise(Edition).
- relx_plugin_apps_per_rel(cloud) ->
- [];
- relx_plugin_apps_per_rel(edge) ->
- [].
- relx_plugin_apps_enterprise(ee) ->
- [list_to_atom(A) || A <- filelib:wildcard("*", "lib-ee"),
- filelib:is_dir(filename:join(["lib-ee", A]))];
- relx_plugin_apps_enterprise(ce) -> [].
- relx_overlay(ReleaseType, Edition) ->
- [ {mkdir, "log/"}
- , {mkdir, "data/"}
- , {mkdir, "plugins"}
- , {mkdir, "data/mnesia"}
- , {mkdir, "data/configs"}
- , {mkdir, "data/patches"}
- , {mkdir, "data/scripts"}
- , {template, "rel/emqx_vars", "releases/emqx_vars"}
- , {template, "rel/BUILT_ON", "releases/{{release_version}}/BUILT_ON"}
- , {copy, "bin/emqx", "bin/emqx"}
- , {copy, "bin/emqx_ctl", "bin/emqx_ctl"}
- , {copy, "bin/node_dump", "bin/node_dump"}
- , {copy, "bin/install_upgrade.escript", "bin/install_upgrade.escript"}
- , {copy, "bin/emqx", "bin/emqx-{{release_version}}"} %% for relup
- , {copy, "bin/emqx_ctl", "bin/emqx_ctl-{{release_version}}"} %% for relup
- , {copy, "bin/install_upgrade.escript", "bin/install_upgrade.escript-{{release_version}}"} %% for relup
- , {copy, "apps/emqx_gateway/src/lwm2m/lwm2m_xml", "etc/lwm2m_xml"}
- , {copy, "apps/emqx_authz/etc/acl.conf", "etc/acl.conf"}
- , {template, "bin/emqx.cmd", "bin/emqx.cmd"}
- , {template, "bin/emqx_ctl.cmd", "bin/emqx_ctl.cmd"}
- , {copy, "bin/nodetool", "bin/nodetool"}
- , {copy, "bin/nodetool", "bin/nodetool-{{release_version}}"}
- ] ++ etc_overlay(ReleaseType, Edition).
- etc_overlay(ReleaseType, _Edition) ->
- Templates = emqx_etc_overlay(ReleaseType),
- [ {mkdir, "etc/"}
- , {copy, "{{base_dir}}/lib/emqx/etc/certs","etc/"}
- ] ++
- lists:map(
- fun({From, To}) -> {template, From, To};
- (FromTo) -> {template, FromTo, FromTo}
- end, Templates)
- ++ extra_overlay(ReleaseType).
- extra_overlay(cloud) ->
- [
- ];
- extra_overlay(edge) ->
- [].
- emqx_etc_overlay(cloud) ->
- emqx_etc_overlay_common() ++
- [ {"{{base_dir}}/lib/emqx/etc/emqx_cloud/vm.args","etc/vm.args"}
- ];
- emqx_etc_overlay(edge) ->
- emqx_etc_overlay_common() ++
- [ {"{{base_dir}}/lib/emqx/etc/emqx_edge/vm.args","etc/vm.args"}
- ].
- emqx_etc_overlay_common() ->
- [ {"{{base_dir}}/lib/emqx_conf/etc/emqx.conf.all", "etc/emqx.conf"}
- , {"{{base_dir}}/lib/emqx/etc/ssl_dist.conf", "etc/ssl_dist.conf"}
- ].
- get_vsn() ->
- %% to make it compatible to Linux and Windows,
- %% we must use bash to execute the bash file
- %% because "./" will not be recognized as an internal or external command
- PkgVsn = os:cmd("bash pkg-vsn.sh"),
- re:replace(PkgVsn, "\n", "", [{return ,list}]).
- maybe_dump(Config) ->
- is_debug() andalso file:write_file("rebar.config.rendered", [io_lib:format("~p.\n", [I]) || I <- Config]),
- Config.
- is_debug() -> is_debug("DEBUG") orelse is_debug("DIAGNOSTIC").
- is_debug(VarName) ->
- case os:getenv(VarName) of
- false -> false;
- "" -> false;
- _ -> true
- end.
- provide_bcrypt_dep() ->
- not is_win32().
- provide_bcrypt_release(ReleaseType) ->
- provide_bcrypt_dep() andalso ReleaseType =:= cloud.
- erl_opts_i(Edition) ->
- [{i, "apps"}] ++
- [{i, Dir} || Dir <- filelib:wildcard(filename:join(["apps", "*", "include"]))] ++
- case is_enterprise(Edition) of
- true ->
- [{i, Dir} || Dir <- filelib:wildcard(filename:join(["lib-ee", "*", "include"]))];
- false -> []
- end.
- dialyzer(Config) ->
- {dialyzer, OldDialyzerConfig} = lists:keyfind(dialyzer, 1, Config),
- AppsToAnalyse = case os:getenv("DIALYZER_ANALYSE_APP") of
- false ->
- [];
- Value ->
- [ list_to_atom(App) || App <- string:tokens(Value, ",")]
- end,
- AppNames = app_names(),
- KnownApps = [Name || Name <- AppsToAnalyse, lists:member(Name, AppNames)],
- AppsToExclude = AppNames -- KnownApps,
- case length(AppsToAnalyse) > 0 of
- true ->
- lists:keystore(dialyzer, 1, Config, {dialyzer, OldDialyzerConfig ++ [{exclude_apps, AppsToExclude}]});
- false ->
- Config
- end.
- coveralls() ->
- case {os:getenv("GITHUB_ACTIONS"), os:getenv("GITHUB_TOKEN")} of
- {"true", Token} when is_list(Token) ->
- Cfgs = [{coveralls_repo_token, Token},
- {coveralls_service_job_id, os:getenv("GITHUB_RUN_ID")},
- {coveralls_commit_sha, os:getenv("GITHUB_SHA")},
- {coveralls_coverdata, "_build/test/cover/*.coverdata"},
- {coveralls_service_name, "github"}],
- case os:getenv("GITHUB_EVENT_NAME") =:= "pull_request"
- andalso string:tokens(os:getenv("GITHUB_REF"), "/") of
- [_, "pull", PRNO, _] ->
- [{coveralls_service_pull_request, PRNO} | Cfgs];
- _ ->
- Cfgs
- end;
- _ ->
- []
- end.
- app_names() -> list_dir("apps") ++ list_dir("lib-ee").
- list_dir(Dir) ->
- case filelib:is_dir(Dir) of
- true ->
- {ok, Names} = file:list_dir(Dir),
- [list_to_atom(Name) || Name <- Names, filelib:is_dir(filename:join([Dir, Name]))];
- false ->
- []
- end.
|