source: trunk/src/directory_tester.erl @ 95

Revision 95, 3.8 KB checked in by dom, 2 years ago (diff)

Two improvements (and new start API): multiple directories watched, and slave started if no node given

Line 
1%%% Copyright (C) Dominic Williams
2%%% All rights reserved.
3%%% See file COPYING.
4
5-module (directory_tester).
6-export ([init/1, init/2, init/3]).
7-export ([run_once/1, run_once/2, run_once/3]).
8-export ([slave_node/1]).
9-export ([read_args/1]).
10
11run_once (Args) ->
12    {Directories, Options} = read_args (Args),
13    run_once (Directories, Options).
14
15run_once (Directories, All_options) ->
16    Slave_args = proplists: get_value (slave, All_options),
17    Options = proplists: delete (slave, All_options),
18    run_once (Directories, slave (Slave_args), Options).
19
20run_once (Directories, Node, Options) ->
21    run (start (Directories, Node, Options)).
22
23init (Args) ->
24    {Directories, Options} = read_args (Args),
25    init (Directories, Options).
26
27init (Directories, All_options) ->
28    Slave_args = proplists: get_value (slave, All_options),
29    Options = proplists: delete (slave, All_options),
30    init (Directories, slave (Slave_args), Options).
31   
32init (Directories, Node, Options) ->
33    loop (start (Directories, Node, Options)).
34
35slave (undefined) ->
36    {Host, Name} = slave_node (node ()),
37    {ok, Slave} = slave: start_link (Host, Name),
38    Slave;
39slave (Args) when is_list (Args) ->
40    {Host, Name} = slave_node (node ()),
41    {ok, Slave} = slave: start_link (Host, Name, Args),
42    Slave.
43
44start (Directories, Node, Options) ->
45    Compiler_options = options (compiler, Options),
46    Compiler_args = [notify_me (compiler), Directories, Compiler_options],
47    Compiler = spawn_link (compiler, init, Compiler_args),
48    Tester = spawn_link (tester, init, [notify_me (tester), Node]),
49    Compiler ! check,
50    Printer = spawn_link (text_printer, init, [standard_io]),
51    {Compiler, Tester, Printer}.
52
53
54slave_node (nonode@nohost) ->
55    not_alive;
56slave_node (Node) ->
57    Node_string = atom_to_list (Node),
58    [Name, Host_string] = string: tokens (Node_string, "@"),
59    Slave_name_string = Name ++ "_extremeforge_slave",
60    Slave_name = list_to_atom (Slave_name_string),
61    Host = list_to_atom (Host_string),
62    {Host, Slave_name}.
63
64read_args (Args) when length (Args) == 1 ->
65    [Dirs] = read_path_args (Args),
66    {Dirs, []};
67read_args (Args) when length (Args) == 2 ->
68    [Dirs, Incs] = read_path_args (Args),
69    Options = [{compiler, [{i, I} || I <- Incs]}],
70    {Dirs, Options};
71read_args ([Arg1, Arg2, Slave_args]) ->
72    {Dirs, C_options} = read_args ([Arg1, Arg2]),
73    {Dirs, [{slave, Slave_args} | C_options]}.
74
75read_path_args (Paths) ->
76    Dirs = [string: tokens (P, ":") || P <- Paths],
77    Not_dir = [D || D <- lists: concat (Dirs), not filelib: is_dir (D)],
78    {not_dir, []} = {not_dir, Not_dir},
79    Dirs.
80
81notify_me (Atom) ->
82    Parent = self (),
83    fun (Event) ->
84            Parent ! {notify, {self (), Atom, Event}}
85    end.
86
87loop ({Compiler, Tester, Printer}) ->
88    receive
89        stop ->
90            Compiler ! {self (), stop},
91            Tester ! {self (), stop};
92        {notify, {Compiler, compiler, {{binaries, Bs}, {removed, Rs}}}} ->
93            delete (Rs, Tester),
94            run (Bs, Tester),
95            loop ({Compiler, Tester, Printer});
96        {notify, Event} ->
97            Printer ! Event,
98            loop ({Compiler, Tester, Printer})
99    after 4000 ->
100            Compiler ! check,
101            loop ({Compiler, Tester, Printer})
102    end.
103
104run ({Compiler, Tester, Printer}) ->
105    receive
106        {notify, {Compiler, compiler, {{binaries, Bs}, {removed, Rs}}}} ->
107            Compiler ! {self (), stop},
108            delete (Rs, Tester),
109            run (Bs, Tester),
110            Tester ! {self (), stop},
111            run ({Compiler, Tester, Printer});
112        {notify, Event} ->
113            Printer ! Event,
114            run ({Compiler, Tester, Printer});
115        {Tester, bye} ->
116            done;
117        {_, bye} ->
118            run ({Compiler, Tester, Printer})
119    end.
120
121delete ([], _) ->
122    pass;
123delete (Removed, Tester) ->
124    Tester ! {delete, Removed}.
125
126run ([], _) ->
127    pass;
128run (Binaries, Tester) ->
129    Tester ! {run, Binaries}.
130
131options (Key, List) ->
132    lists: concat (proplists: get_all_values (Key, List)).
Note: See TracBrowser for help on using the repository browser.