split-config.escript 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. Sections = lists:filter(fun({<<"modules">>, _}) -> false;
  16. (_) -> true
  17. end, Sections0),
  18. ok = dump_sections(Sections).
  19. parse_sections(Lines) ->
  20. {ok, P} = re:compile("#+\s*CONFIG_SECTION_(BGN|END)\s*=\s*([^\s-]+)\s*="),
  21. Parser =
  22. fun(Line) ->
  23. case re:run(Line, P, [{capture, all_but_first, binary}]) of
  24. {match, [<<"BGN">>, Name]} -> {section_bgn, Name};
  25. {match, [<<"END">>, Name]} -> {section_end, Name};
  26. nomatch -> continue
  27. end
  28. end,
  29. parse_sections(Lines, Parser, ?BASE, #{?BASE => []}).
  30. parse_sections([], _Parse, _Section, Sections) ->
  31. lists:map(fun({N, Lines}) -> {N, lists:reverse(Lines)} end,
  32. maps:to_list(Sections));
  33. parse_sections([Line | Lines], Parse, Section, Sections) ->
  34. case Parse(Line) of
  35. {section_bgn, Name} ->
  36. ?BASE = Section, %% assert
  37. true = (Name =/= ?BASE), %% assert
  38. false = maps:is_key(Name, Sections), %% assert
  39. Include = iolist_to_binary(["include {{ platform_etc_dir }}/", Name, ".conf"]),
  40. Base = maps:get(?BASE, Sections),
  41. NewSections = Sections#{?BASE := [Include | Base], Name => []},
  42. parse_sections(Lines, Parse, Name, NewSections);
  43. {section_end, Name} ->
  44. true = (Name =:= Section), %% assert
  45. parse_sections(Lines, Parse, ?BASE, Sections);
  46. continue ->
  47. Acc = maps:get(Section, Sections),
  48. parse_sections(Lines, Parse, Section, Sections#{Section => [Line | Acc]})
  49. end.
  50. dump_sections([]) -> ok;
  51. dump_sections([{Name, Lines0} | Rest]) ->
  52. Filename = filename:join(["etc", iolist_to_binary([Name, ".conf.seg"])]),
  53. Lines = [[L, "\n"] || L <- Lines0],
  54. ok = file:write_file(Filename, Lines),
  55. dump_sections(Rest).