Skip to content

Commit 69954c5

Browse files
authored
Merge pull request #49 from UncleGrumpy/fix_dialyzer_bugs
Fix bugs in dialyzer task
2 parents 54a9b71 + 5a03a1e commit 69954c5

File tree

2 files changed

+71
-49
lines changed

2 files changed

+71
-49
lines changed

README.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,16 +524,24 @@ Use the `dialyzer` task to check applications for type discrepancies. To use the
524524
$ rebar3 atomvm dialyzer
525525
```
526526

527-
This task requires a complete AtomVM installation. This includes the AtomVM binary, the standard atomvmlib libraries, compiled beam files, and the `atomvm`
528-
launcher script. The `atomvm` launcher script should be in your PATH. This is all taken care of with a MacOS install using MacPorts, or Homebrew.
529-
Linux users will need to build from source and use the cmake "install" target. If you have "installed" AtomVM to a non-standard location (i.e. /otp/atomvm)
530-
and the `atomvm` launcher script is not in your PATH you must supply the install location containing the AtomVM libraries using the `--atomvm_root` option
531-
when using this task. For example:
527+
The `atomvm` launcher script should be in your PATH. This is taken care of with a MacOS install using MacPorts, or
528+
Homebrew. Linux users will need to build from source and use the cmake "install" target. If you have installed AtomVM
529+
to a non-standard location (i.e. /otp/atomvm) and the `atomvm` launcher script is not in your PATH you must supply the
530+
install location containing the AtomVM libraries using the `--atomvm_root` option when using this task. You may also
531+
use the path to the build directory used for a generic_unix build of the AtomVM BEAM libraries.
532+
533+
Example for a non-standard instal when `atomvm` launcher is not in PATH:
532534

533535
```
534536
$ rebar3 atomvm dialyzer --atomvm_root /opt/atomvm
535537
```
536538

539+
Example using a development build directory:
540+
541+
```
542+
$ rebar3 atomvm dialyzer --atomvm_root /home/joe/work/AtomVM/build
543+
```
544+
537545
This option may also be supplied in the `atomvm_rebar3_plugin` configuration options in rebar.conf. Example:
538546

539547
```erlang

src/atomvm_dialyzer_provider.erl

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,15 @@ init(State) ->
7272

7373
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
7474
do(State) ->
75-
% no plugins in analysis
76-
rebar_paths:unset_paths([plugins], State),
77-
rebar_paths:set_paths([deps], State),
7875
try
7976
Config = get_opts(State),
8077
rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Config]),
8178
ok = do_dialize(Config, State),
8279
{ok, State}
8380
catch
8481
C:E:S ->
85-
rebar_api:error(
86-
"An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [
87-
?PROVIDER, C, E, S
88-
]
89-
),
82+
rebar_api:error("An error (~p) occurred in the ~p task.", [E, ?PROVIDER]),
83+
rebar_api:debug("Class=~p Error=~p~nSTACKTRACE:~n~p~n", [C, E, S]),
9084
{error, E}
9185
end.
9286

@@ -132,9 +126,9 @@ do_dialize(Config, State) ->
132126
PLT = plt_absolute_name(State),
133127
case dialyzer:plt_info(PLT) of
134128
{ok, _} ->
135-
check_app_plt(Config, State);
129+
check_app_plt(State);
136130
_ ->
137-
do_build_plt(Config, State)
131+
do_build_plt(State)
138132
end,
139133
AppBEAMs = get_app_beam_abspath(State),
140134
rebar_api:info("Analyzing application with dialyzer...", []),
@@ -150,27 +144,26 @@ do_dialize(Config, State) ->
150144
print_warnings(Problems)
151145
catch
152146
throw:{dialyzer_error, Reason} ->
153-
rebar_api:error("Dialyzer failed! reason: ~p.~n", [Reason])
147+
rebar_api:abort("Dialyzer failed! reason: ~p.~n", [Reason])
154148
end,
155149
ok.
156150

157151
% @private
158152
check_base_plt(Config) ->
159153
rebar_api:info("Checking AtomVM base PLT...", []),
160154
PLT = base_plt_absname(Config),
161-
BEAMdir = get_base_beam_path(Config),
162155
try
163156
dialyzer:run([
164-
{analysis_type, plt_check}, {plts, [PLT]}, {output_plt, PLT}, {files_rec, BEAMdir}
157+
{analysis_type, plt_check}, {init_plt, PLT}, {output_plt, PLT}
165158
])
166159
of
167160
[] ->
168161
ok;
169162
_ ->
170-
do_build_base_plt(Config)
163+
ok = do_build_base_plt(Config)
171164
catch
172165
throw:{dialyzer_error, _} ->
173-
do_build_base_plt(Config)
166+
ok = do_build_base_plt(Config)
174167
end,
175168
ok.
176169

@@ -179,12 +172,12 @@ base_plt_absname(Config) ->
179172
Home =
180173
case os:getenv("HOME") of
181174
false ->
182-
rebar_api:error("Unable to locate users home directory");
175+
rebar_api:abort("Unable to locate users home directory", []);
183176
Path ->
184177
string:trim(Path)
185178
end,
186179
Base = maps:get(base_plt_location, Config, filename:join(Home, ".cache/rebar3")),
187-
[Version, _] = string:split(string:trim(os:cmd("atomvm -version")), "+"),
180+
Version = atomvm_version(Config),
188181
BasePLT = filename:absname_join(filename:absname(Base), "AtomVM-" ++ Version ++ ".plt"),
189182
rebar_api:debug("Base PLT file: ~p", [BasePLT]),
190183
string:trim(BasePLT).
@@ -204,52 +197,44 @@ do_build_base_plt(Config) ->
204197
ok;
205198
Failure ->
206199
print_warnings(Failure),
207-
rebar_api:error("Failed to create project plt!~n")
200+
rebar_api:abort("Failed to create project plt!~n", [])
208201
catch
209202
throw:{dialyzer_error, Error} ->
210-
rebar_api:error("Failed to crete plt, error:~p~n", [Error])
211-
end,
212-
ok.
203+
rebar_api:abort("Failed to crete plt, error:~p~n", [Error])
204+
end.
213205

214206
% @private
215-
check_app_plt(Config, State) ->
207+
check_app_plt(State) ->
216208
rebar_api:info("Checking application PLT...", []),
217209
PLT = plt_absolute_name(State),
218210
try dialyzer:run([{analysis_type, plt_check}, {plts, [PLT]}]) of
219211
_ ->
220212
ok
221213
catch
222214
throw:{dialyzer_error, _} ->
223-
do_build_plt(Config, State)
215+
ok = do_build_plt(State)
224216
end,
225217
ok.
226218

227219
% @private
228-
do_build_plt(Config, State) ->
220+
do_build_plt(State) ->
229221
rebar_api:info("Building application PLT...", []),
230222
%% build plt
231223
BEAMdir = string:trim(get_app_beam_abspath(State)),
232224
PLT = string:trim(plt_absolute_name(State)),
233-
BasePLT = base_plt_absname(Config),
234225
try
235226
dialyzer:run([
236227
{analysis_type, plt_build},
237-
{init_plt, PLT},
238-
{plts, [BasePLT]},
239228
{output_plt, PLT},
240229
{files_rec, [BEAMdir]}
241230
])
242231
of
243-
[] ->
244-
ok;
245-
Failure ->
246-
print_warnings(Failure),
247-
rebar_api:error("Failed to create project plt!~n")
232+
_ ->
233+
ok
248234
catch
249235
throw:{dialyzer_error, Error} ->
250-
rebar_api:error("Failed to crete plt, error:~p~n", [Error])
251-
end,
252-
ok.
236+
rebar_api:abort("Failed to crete plt, error: ~p~n", [Error])
237+
end.
253238

254239
%% @private
255240
plt_absolute_name(State) ->
@@ -265,7 +250,7 @@ get_base_beam_path(Config) ->
265250
[] ->
266251
default_base_beam_path();
267252
Base ->
268-
get_base_beam_path_list(filename:absname(Base))
253+
get_base_beam_path_list(Base)
269254
end,
270255
rebar_api:debug("AtomVM beam PATH: ~p", [Path]),
271256
Path.
@@ -282,7 +267,7 @@ atomvm_install_path() ->
282267
BinPath =
283268
case os:find_executable("atomvm") of
284269
false ->
285-
rebar_api:error("Path to AtomVM installation not found!");
270+
rebar_api:abort("Path to AtomVM installation not found!", []);
286271
AtomVM ->
287272
AtomVM
288273
end,
@@ -296,22 +281,52 @@ default_base_beam_path() ->
296281

297282
%% @private
298283
get_base_beam_path_list(Base) ->
284+
NotFound = lists:duplicate(length(?LIBS), []),
299285
Libs =
300-
case [filelib:wildcard(Base ++ "/lib/" ++ atom_to_list(Lib) ++ "*/ebin") || Lib <- ?LIBS] of
301-
[] ->
302-
[filename:join(Base, atom_to_list(Lib2) ++ "/src/beams") || Lib2 <- ?LIBS];
286+
case
287+
lists:foldl(
288+
fun(E, Acc) ->
289+
[filelib:wildcard(Base ++ "/lib/" ++ atom_to_list(E) ++ "*/ebin") | Acc]
290+
end,
291+
[],
292+
?LIBS
293+
)
294+
of
295+
NotFound ->
296+
%% not a standard install, look for source build beams
297+
lists:foldl(
298+
fun(E, Acc) ->
299+
[
300+
filelib:wildcard(Base ++ "/libs/" ++ atom_to_list(E) ++ "*/src/beams")
301+
| Acc
302+
]
303+
end,
304+
[],
305+
?LIBS
306+
);
303307
Paths ->
304308
Paths
305309
end,
306310
rebar_api:debug("AtomVM libraries to add to plt: ~p~n", [Libs]),
307311
case Libs of
308312
[] ->
309-
rebar_api:error("Unable to locate AtomVM beams in path"),
310-
{error, no_beams_found};
313+
rebar_api:abort("Unable to locate AtomVM beams in path", []);
311314
Ebins ->
312315
Ebins
313316
end.
314317

318+
atomvm_version(Config) ->
319+
Base = filename:absname(string:trim(maps:get(atomvm_root, Config, atomvm_install_path()))),
320+
Version =
321+
case filename:basename(Base) of
322+
"build" ->
323+
string:trim(os:cmd(filename:absname_join(Base, "src/AtomVM") ++ " -version"));
324+
_ ->
325+
string:trim(os:cmd("atomvm -version"))
326+
end,
327+
rebar_api:debug("AtomVM version = ~p", [Version]),
328+
Version.
329+
315330
% @private
316331
app_profile_abs_dir(State) ->
317332
Profile =
@@ -321,8 +336,7 @@ app_profile_abs_dir(State) ->
321336
Prof1 when is_atom(Prof1) ->
322337
Prof1;
323338
Arg ->
324-
rebar_api:error("Unable to determine rebar3 profile, got badarg ~p", [Arg]),
325-
{error, bad_rebar_profile}
339+
rebar_api:abort("Unable to determine rebar3 profile, got badarg ~p", [Arg])
326340
end,
327341
WorkDir = filename:absname(filename:join("_build", Profile)),
328342
ok = filelib:ensure_path(WorkDir),

0 commit comments

Comments
 (0)