refactor: make release edition static info at compile time

This commit is contained in:
Zaiming (Stone) Shi 2022-02-28 10:42:49 +01:00
parent 96815539c1
commit d029a73b99
6 changed files with 61 additions and 67 deletions

View File

@ -39,7 +39,6 @@
%%--------------------------------------------------------------------
start(_Type, _Args) ->
ok = emqx_release:put_edition(),
ok = maybe_load_config(),
ok = emqx_persistent_session:init_db_backend(),
ok = maybe_start_quicer(),

View File

@ -17,55 +17,33 @@
-module(emqx_release).
-export([ edition/0
, put_edition/0
, put_edition/1
, description/0
, version/0
]).
-include("emqx_release.hrl").
-define(EMQX_DESCS,
#{ee => "EMQX Enterprise",
ce => "EMQX",
edge => "EMQX Edge"
}).
-define(EMQX_REL_VSNS,
#{ee => ?EMQX_RELEASE_EE,
ce => ?EMQX_RELEASE_CE,
edge => ?EMQX_RELEASE_CE
}).
%% @doc Return EMQX description.
description() ->
case os:getenv("EMQX_DESCRIPTION") of
false -> "EMQX Community Edition";
"" -> "EMQX Community Edition";
Str -> string:strip(Str, both, $\n)
end.
maps:get(edition(), ?EMQX_DESCS).
%% @doc Return EMQX edition info.
%% Read info from persistent_term at runtime.
%% Or meck this function to run tests for another eidtion.
-spec edition() -> ce | ee | edge.
edition() ->
try persistent_term:get(emqx_edition)
catch error : badarg -> get_edition() end.
%% @private initiate EMQX edition info in persistent_term.
put_edition() ->
ok = put_edition(get_edition()).
%% @hidden This function is mostly for testing.
%% Switch to another eidtion at runtime to run edition-specific tests.
-spec put_edition(ce | ee | edge) -> ok.
put_edition(Which) ->
persistent_term:put(emqx_edition, Which),
ok.
-spec get_edition() -> ce | ee | edge.
get_edition() ->
edition(description()).
edition(Desc) ->
case re:run(Desc, "enterprise", [caseless]) of
{match, _} ->
ee;
_ ->
case re:run(Desc, "edge", [caseless]) of
{match, _} -> edge;
_ -> ce
end
end.
edition() -> ?EMQX_RELEASE_EDITION.
%% @doc Return the release version.
version() ->
@ -85,8 +63,5 @@ version() ->
Vsn
end.
-ifdef(EMQX_ENTERPRISE).
build_vsn() -> ?EMQX_RELEASE_EE.
-else.
build_vsn() -> ?EMQX_RELEASE_CE.
-endif.
build_vsn() ->
maps:get(edition(), ?EMQX_REL_VSNS).

View File

@ -152,7 +152,7 @@ dump_schema(Dir, SchemaModule) ->
-spec gen_doc(file:name_all(), module()) -> ok.
gen_doc(File, SchemaModule) ->
Version = emqx_release:version(),
Title = "# EMQX " ++ Version ++ " Configuration",
Title = "# " ++ emqx_release:description() ++ " " ++ Version ++ " Configuration",
BodyFile = filename:join([code:lib_dir(emqx_conf), "etc", "emqx_conf.md"]),
{ok, Body} = file:read_file(BodyFile),
Doc = hocon_schema_md:gen(SchemaModule, #{title => Title, body => Body}),

25
build
View File

@ -70,10 +70,18 @@ make_doc() {
local libs_dir1 libs_dir2
libs_dir1="$("$FIND" "_build/default/lib/" -maxdepth 2 -name ebin -type d)"
libs_dir2="$("$FIND" "_build/$PROFILE/lib/" -maxdepth 2 -name ebin -type d)"
case $PROFILE in
emqx-enterprise)
SCHEMA_MODULE='emqx_enterprise_conf_schema'
;;
*)
SCHEMA_MODULE='emqx_conf_schema'
;;
esac
# shellcheck disable=SC2086
erl -noshell -pa $libs_dir1 $libs_dir2 -eval \
"Dir = filename:join(['_build', '${PROFILE}', lib, emqx_dashboard, priv, www, static]), \
ok = emqx_conf:dump_schema(Dir), \
ok = emqx_conf:dump_schema(Dir, $SCHEMA_MODULE), \
halt(0)."
}
@ -229,10 +237,17 @@ export_release_vars() {
local erl_opts=()
if [[ "$profile" = *enterprise* ]]
then
erl_opts+=( "{d,'EMQX_ENTERPRISE'}" )
fi
case "$profile" in
*enterprise*)
erl_opts+=( "{d, 'EMQX_RELEASE_EDITION', ee}" )
;;
*edge*)
erl_opts+=( "{d, 'EMQX_RELEASE_EDITION', edge}" )
;;
*)
erl_opts+=( "{d, 'EMQX_RELEASE_EDITION', ce}" )
;;
esac
# At this time, Mix provides no easy way to pass `erl_opts' to
# dependencies. The workaround is to set this variable before

View File

@ -15,9 +15,15 @@
-export([roots/0, fields/1, validations/0]).
roots() -> [{license,
hoconsc:mk(hoconsc:union([hoconsc:ref(?MODULE, key_license),
hoconsc:ref(?MODULE, file_license)]),
#{desc => "TODO"})}
hoconsc:mk(hoconsc:union([hoconsc:ref(?MODULE, key_license),
hoconsc:ref(?MODULE, file_license)]),
#{desc => """EMQX Enterprise license.
A license is either a `key` or a `file`.
When `key` and `file` are both configured, `key` is used.
EQMX by default starts with a trial license. For a different license,
visit https://www.emqx.com/apply-licenses/emqx to apply.
"})}
].
fields(key_license) ->

View File

@ -115,17 +115,18 @@ test_deps() ->
, {proper, "1.4.0"}
].
common_compile_opts(Vsn) ->
common_compile_opts(Edition, Vsn) ->
[ debug_info % always include debug_info
, {compile_info, [{emqx_vsn, Vsn}]}
, {d, 'EMQX_RELEASE_EDITION', Edition}
] ++
[{d, 'EMQX_BENCHMARK'} || os:getenv("EMQX_BENCHMARK") =:= "1" ].
prod_compile_opts(Vsn) ->
prod_compile_opts(Edition, Vsn) ->
[ compressed
, deterministic
, warnings_as_errors
| common_compile_opts(Vsn)
| common_compile_opts(Edition, Vsn)
].
prod_overrides() ->
@ -137,28 +138,28 @@ profiles() ->
profiles_ce() ->
Vsn = get_vsn(emqx),
[ {'emqx',
[ {erl_opts, prod_compile_opts(Vsn)}
[ {erl_opts, prod_compile_opts(ce, Vsn)}
, {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(Vsn)}
[ {erl_opts, prod_compile_opts(ce, Vsn)}
, {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-edge',
[ {erl_opts, prod_compile_opts(Vsn)}
[ {erl_opts, prod_compile_opts(edge, Vsn)}
, {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(Vsn)}
[ {erl_opts, prod_compile_opts(edge, Vsn)}
, {relx, relx(Vsn, edge, pkg, ce)}
, {overrides, prod_overrides()}
, {project_app_dirs, project_app_dirs(ce)}
@ -168,16 +169,15 @@ profiles_ce() ->
profiles_ee() ->
Vsn = get_vsn('emqx-enterprise'),
EE = {d, 'EMQX_ENTERPRISE'},
[ {'emqx-enterprise',
[ {erl_opts, [EE | prod_compile_opts(Vsn)]}
[ {erl_opts, prod_compile_opts(ee, Vsn)}
, {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, [EE | prod_compile_opts(Vsn)]}
[ {erl_opts, prod_compile_opts(ee, Vsn)}
, {relx, relx(Vsn, cloud, pkg, ee)}
, {overrides, prod_overrides()}
, {project_app_dirs, project_app_dirs(ee)}
@ -188,14 +188,13 @@ profiles_ee() ->
%% EE has more files than CE, always test/check with EE options.
profiles_dev() ->
Vsn = get_vsn('emqx-enterprise'),
EE = {d, 'EMQX_ENTERPRISE'},
[ {check,
[ {erl_opts, [EE | common_compile_opts(Vsn)]}
[ {erl_opts, common_compile_opts(ee, Vsn)}
, {project_app_dirs, project_app_dirs(ee)}
]}
, {test,
[ {deps, test_deps()}
, {erl_opts, [EE | common_compile_opts(Vsn) ++ erl_opts_i()]}
, {erl_opts, common_compile_opts(ee, Vsn) ++ erl_opts_i()}
, {extra_src_dirs, [{"test", [{recursive, true}]}]}
, {project_app_dirs, project_app_dirs(ee)}
]}
@ -218,9 +217,9 @@ relx(Vsn, RelType, PkgType, Edition) ->
| overlay_vars(RelType, PkgType, Edition)]}
].
emqx_description(cloud, ee) -> "EMQX Enterprise Edition";
emqx_description(cloud, ce) -> "EMQX Community Edition";
emqx_description(edge, ce) -> "EMQX Edge Edition".
emqx_description(cloud, ee) -> "EMQX Enterprise";
emqx_description(cloud, ce) -> "EMQX";
emqx_description(edge, ce) -> "EMQX Edge".
overlay_vars(RelType, PkgType, Edition) ->
overlay_vars_rel(RelType)