-
Notifications
You must be signed in to change notification settings - Fork 3
/
tetrapak_task_shell.erl
100 lines (87 loc) · 3.8 KB
/
tetrapak_task_shell.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
% Copyright 2010-2011, Travelping GmbH <info@travelping.com>
% Permission is hereby granted, free of charge, to any person obtaining a
% copy of this software and associated documentation files (the "Software"),
% to deal in the Software without restriction, including without limitation
% the rights to use, copy, modify, merge, publish, distribute, sublicense,
% and/or sell copies of the Software, and to permit persons to whom the
% Software is furnished to do so, subject to the following conditions:
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
% DEALINGS IN THE SOFTWARE.
-module(tetrapak_task_shell).
-behaviour(tetrapak_task).
-export([run/2, start_deps/1]).
run("shell", _) ->
code:ensure_loaded(tpk),
case tetrapak_io:can_start_shell() of
true ->
TestDir = tetrapak:config_path("test.ct.srcdir"),
case filelib:is_dir(TestDir) of
true -> code:add_pathz(TestDir);
false -> ok
end,
tetrapak:require("tetrapak:reload"),
tetrapak_task:print_output_header(user, "shell"),
tetrapak_io:start_shell(),
timer:sleep(infinity);
false ->
tetrapak:fail("Cannot start shell")
end;
run("tetrapak:reload", _) ->
EbinDir = tetrapak:path("ebin"),
Modules = lists:map(fun (F) -> {list_to_atom(filename:basename(F, ".beam")), filename:join(EbinDir, F)} end, filelib:wildcard("*.beam", EbinDir)),
lists:foreach(fun ({Mod, Path}) ->
case code:is_loaded(Mod) of
{file, _} ->
DiskMtime = tpk_file:mtime(Path),
(DiskMtime > loaded_mtime(Mod)) andalso load(Mod);
false ->
load(Mod)
end
end, Modules);
run("tetrapak:tpk-help", _) ->
io:format("tpk:r(Task) -- runs the given task\n"
"tpk:h() -- shows this help\n"
"tpk:l() -- reloads changed modules\n"
"tpk:s() -- starts the current application\n"
"tpk:s(App) -- starts an application and all its dependencies\n"
"tpk:c() -- runs \"check\"\n"
"tpk:b() -- runs \"build\"\n"
"tpk:bl() -- runs \"build\" and reloads modules\n");
run("tetrapak:startapp", _) ->
case start_deps(tetrapak:get("config:appfile:name")) of
ok ->
done;
{failed, App, Error} ->
tetrapak:fail("failed to start ~s: ~p", [App, Error])
end.
start_deps(App) ->
case application:start(App) of
ok ->
io:format("Started ~s~n", [App]),
ok;
{error, {already_started, App}} ->
ok;
{error, {not_started, DepApp}} ->
case start_deps(DepApp) of
ok ->
start_deps(App);
Error ->
Error
end;
{error, Error} ->
{failed, App, Error}
end.
loaded_mtime(Mod) ->
{Y,Mon,D,H,Min,S} = proplists:get_value(time, Mod:module_info(compile)),
calendar:universal_time_to_local_time({{Y,Mon,D},{H,Min,S}}).
load(Mod) ->
io:format("load ~s~n", [Mod]),
code:purge(Mod),
code:load_file(Mod).