split-config.escript 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #!/usr/bin/env escript
  2. %% This script reads up emqx.conf and split the sections
  3. %% and dump sections to separate files.
  4. %% Sections are grouped between CONFIG_SECTION_BGN and
  5. %% CONFIG_SECTION_END pairs
  6. %%
  7. %% NOTE: this feature is so far not used in opensource
  8. %% edition due to backward-compatibility reasons.
  9. -mode(compile).
  10. -define(BASE, <<"emqx">>).
  11. main(_) ->
  12. {ok, Bin} = file:read_file("etc/emqx.conf"),
  13. Lines = binary:split(Bin, <<"\n">>, [global]),
  14. Sections0 = parse_sections(Lines),
  15. {value, _, Sections1} = lists:keytake(<<"modules">>, 1, Sections0),
  16. {value, {N, Base}, Sections2} = lists:keytake(<<"emqx">>, 1, Sections1),
  17. IncludeNames = proplists:get_keys(Sections2),
  18. Includes = lists:map(fun(Name) ->
  19. iolist_to_binary(["include {{ platform_etc_dir }}/", Name, ".conf"])
  20. end, IncludeNames),
  21. ok = dump_sections([{N, Base ++ Includes}| Sections2]).
  22. parse_sections(Lines) ->
  23. {ok, P} = re:compile("#+\s*CONFIG_SECTION_(BGN|END)\s*=\s*([^\s-]+)\s*="),
  24. Parser =
  25. fun(Line) ->
  26. case re:run(Line, P, [{capture, all_but_first, binary}]) of
  27. {match, [<<"BGN">>, Name]} -> {section_bgn, Name};
  28. {match, [<<"END">>, Name]} -> {section_end, Name};
  29. nomatch -> continue
  30. end
  31. end,
  32. parse_sections(Lines, Parser, ?BASE, #{?BASE => []}).
  33. parse_sections([], _Parse, _Section, Sections) ->
  34. lists:map(fun({N, Lines}) -> {N, lists:reverse(Lines)} end,
  35. maps:to_list(Sections));
  36. parse_sections([Line | Lines], Parse, Section, Sections) ->
  37. case Parse(Line) of
  38. {section_bgn, Name} ->
  39. ?BASE = Section, %% assert
  40. true = (Name =/= ?BASE), %% assert
  41. false = maps:is_key(Name, Sections), %% assert
  42. NewSections = Sections#{?BASE := maps:get(?BASE, Sections), Name => []},
  43. parse_sections(Lines, Parse, Name, NewSections);
  44. {section_end, Name} ->
  45. true = (Name =:= Section), %% assert
  46. parse_sections(Lines, Parse, ?BASE, Sections);
  47. continue ->
  48. Acc = maps:get(Section, Sections),
  49. parse_sections(Lines, Parse, Section, Sections#{Section => [Line | Acc]})
  50. end.
  51. dump_sections([]) -> ok;
  52. dump_sections([{Name, Lines0} | Rest]) ->
  53. Filename = filename:join(["etc", iolist_to_binary([Name, ".conf.seg"])]),
  54. Lines = [[L, "\n"] || L <- Lines0],
  55. ok = file:write_file(Filename, Lines),
  56. dump_sections(Rest).