1 %% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
2 %%%---------------------------------------------------------------------------
3 %%% @copyright Erlware, LLC
4 %%% @author Eric Merritt <ericbmerritt@gmail.com>
5 %%% @author Anders Nygren <anders.nygren@gmail.com>
6 %%% @doc Parse an erlang file (yrl, hrl, erl) and information about the file
7 %%% that is relevant to the build system
9 %%%-------------------------------------------------------------------
10 -module(sin_file_info
).
13 -export([file_regex
/0, process_file
/3, initialize
/2]).
14 -export_type([date/0, time/0, date_time
/0, mod
/0]).
16 -include_lib("sinan/include/sinan.hrl").
17 -include_lib("kernel/include/file.hrl").
20 %%====================================================================
22 %%====================================================================
23 -type
date() :: {Year
:: non_neg_integer(),
24 Month
:: non_neg_integer(),
25 Day
:: non_neg_integer()}.
27 -type
time() :: {Hour
:: non_neg_integer(),
28 Minute
:: non_neg_integer(),
29 Second
:: non_neg_integer()}.
31 -type
date_time() :: {date() , time()}.
32 -type
mod() :: record(module
).
34 -type
type() :: hrl
| erl
| yrl
| jxa
| {other
, string()}.
36 %%====================================================================
38 %%====================================================================
40 "^((.+\.erl)|(.+\.hrl)|(.+\.yrl)|(.+\.jxa))$".
42 -spec
process_file(sin_state:state(), string(), [string()]) ->
44 process_file(State0
, Path0
, Includes
) ->
45 sin_sig:do_if_changed(?MODULE
,
49 do_extract(State1
, Path1
, Includes
)
52 -spec
initialize(string(), type()) ->
54 initialize(Path
, Type
) ->
57 module_deps
=sets:new(),
60 include_timestamps
=[],
61 called_modules
=sets:new()}.
64 %%====================================================================
66 %%====================================================================
67 -spec
deps_changed(mod(), sin_state:state()) -> boolean().
68 deps_changed(#module
{include_timestamps
=Includes
}, State
) ->
69 lists:any(fun({Path
, Stamp
}) ->
70 not Stamp
== get_timestamp_info(State
, Path
)
73 -spec
do_extract(sin_state:state(), string(), [string()]) ->
74 {sin_state:state(), mod()}.
75 do_extract(State0
, Path
, Includes
) ->
76 case filename:extension(Path
) of
77 Ext
when Ext
== ".erl";
80 {State1
, Mod0
, ChangeSig
} = sin_erl_info:process_file(State0
,
83 Mod1
= add_stamp_info(State1
, Path
, Mod0
, ChangeSig
),
85 Ext
when Ext
== ".jxa" ->
86 {State1
, Mod0
, ChangeSig
} = sin_jxa_info:process_file(State0
,
89 Mod1
= add_stamp_info(State1
, Path
, Mod0
, ChangeSig
),
92 ?
SIN_RAISE(State0
, {unable_to_parse_file
, Path
, Error
})
95 -spec
add_stamp_info(sin_state:state(), string(), mod(), term()) -> mod().
96 add_stamp_info(State
, Path
, Mod
, ChangeSig
) ->
97 Mod#module
{changed
=get_timestamp_info(State
, Path
),
98 change_sig
=ChangeSig
}.
100 -spec
get_timestamp_info(sin_state:state(), string()) -> non_neg_integer().
101 get_timestamp_info(State
, Path
) ->
102 case file:read_file_info(Path
) of
104 FileInfo#file_info
.mtime
;
108 ?
SIN_RAISE(State
, {unable_to_get_file_info
, Path
, Reason
})