From 9c15b57aa413a773192fdd0aa75f908a08a47b84 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 26 Sep 2020 22:47:03 -0400 Subject: [PATCH] Specify dependencies for MIB files This is required for compile order to be maintained in a post-3.14 world. --- src/rebar_compiler_mib.erl | 66 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/rebar_compiler_mib.erl b/src/rebar_compiler_mib.erl index 499976d3..e25cc809 100644 --- a/src/rebar_compiler_mib.erl +++ b/src/rebar_compiler_mib.erl @@ -61,8 +61,9 @@ atoms_in_mib_first_files_warning(Atoms) -> ?WARN(W, [Atoms]). -dependencies(_, _, _) -> - []. +dependencies(File, _Dir, SrcDirs) -> + SrcFiles = lists:append([src_files(SrcDir) || SrcDir <- SrcDirs]), + file_deps(File, SrcFiles). compile(Source, OutDirs, _, Opts) -> {_, BinOut} = lists:keyfind(".bin", 1, OutDirs), @@ -99,3 +100,64 @@ clean(MibFiles, AppInfo) -> rebar_file_utils:delete_each( [filename:join([AppDir, "include", MIB++".hrl"]) || MIB <- MIBs]), ok = rebar_file_utils:rm_rf(filename:join([AppDir, "priv/mibs/*.bin"])). + +src_files(Dir) -> + %% .mib extension is assumed to be valid here + case file:list_dir(Dir) of + {ok, Files} -> + [filename:join(Dir, File) + || File <- Files, + filename:extension(File) =:= ".mib"]; + _ -> + [] + end. + +file_deps(File, Files) -> + DepMods = imports_in_file(File), + lists:filter( + fun(F) -> + Mods = modules_in_file(F), + lists:any(fun(M) -> lists:member(M, Mods) end, DepMods) + end, + Files + ). + +modules_in_file(File) -> + {ok, Bin} = file:read_file(File), + Res = re:run( + Bin, + "^([a-zA-Z0-9_-]+)\\s+DEFINITIONS\\s+::=\\s+BEGIN", + [multiline, {capture, all_but_first, list}, global, unicode] + ), + case Res of + nomatch -> + []; + {match, List} -> + lists:usort(lists:append(List)) + end. + +imports_in_file(File) -> + {ok, Bin} = file:read_file(File), + ImportMatch = re:run( + Bin, + "IMPORTS\\s+(.*);", + [multiline, dotall, ungreedy, {capture, all_but_first, list}, global] + ), + case ImportMatch of + nomatch -> + []; + {match, ImportSections} -> + Modules = re:run( + ImportSections, + "FROM\\s+([a-zA-Z0-9_-]+)\\s+", + [multiline, {capture, all_but_first, list}, global] + ), + case Modules of + nomatch -> + []; + {match, List} -> + lists:usort(lists:append(List)) + end + end. + +