1 %% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
2 %%%-------------------------------------------------------------------
3 %%% @author Eric Merritt <ericbmerritt@gmail.com>
4 %%% @copyright (C) 2006 - 2011, Eric Merritt
6 %%% Provides task sorting and manipulation support to the sinan.
8 %%%-------------------------------------------------------------------
12 -include_lib("sinan/include/sinan.hrl").
21 -export_type([task_description
/0,
24 %%====================================================================
26 %%====================================================================
28 -type
task_description() :: record(task
).
29 -type
task_name() :: atom().
31 %%====================================================================
33 %%====================================================================
34 -spec
ensure_started(atom()) -> ok
.
35 ensure_started(App
) ->
36 case application:start(App
) of
37 {error
, {already_started
, _
}} ->
42 erlang:throw({error_starting_app
, App
, Error
})
45 %% @doc get a specific task description
46 -spec
get_task(sin_state:state(), task_name()) -> [task_name()].
47 get_task(State
, TaskName
) ->
49 get_task(State
, TaskName
, Tasks
).
51 %% @doc get a dependency ordered list of tasks from the system.
52 -spec
get_task_list(sin_state:state(), task_name()) -> [task_name()].
53 get_task_list(State
, TaskName
) ->
55 RootTask
= get_task(State
, TaskName
, Tasks
),
56 lists:map(fun(DepTaskName
) ->
57 get_task(State
, DepTaskName
, Tasks
)
59 process_deps(State
, RootTask
, Tasks
)).
61 %% @doc get a list of all tasks in the system
62 -spec
get_tasks() -> [record(task
)].
64 [sin_task_depends:description(),
65 sin_task_dialyzer:description(),
66 sin_task_version:description(),
67 sin_task_eunit:description(),
68 sin_task_proper:description(),
69 sin_task_eqc:description(),
70 sin_task_shell:description(),
71 sin_task_release:description(),
72 sin_task_help:description(),
73 sin_task_gen:description(),
74 sin_task_doc:description(),
75 sin_task_dist:description(),
76 sin_task_clean:description(),
77 sin_task_build:description(),
78 sin_task_xref:description(),
79 sin_task_erts:description(),
80 sin_task_escript:description(),
81 sin_task_echo:description(),
82 sin_task_cucumber:description()].
84 %% @doc define the behaviour for tasks.
85 behaviour_info(callbacks
) ->
86 [{description
, 0}, {do_task
, 2}];
90 %% @doc Format an exception thrown by this module
91 -spec
format_exception(sin_exceptions:exception()) ->
93 format_exception(Exception
) ->
94 sin_exceptions:format_exception(Exception
).
96 %%====================================================================
97 %%% Internal functions
98 %%====================================================================
100 -spec
get_task(sin_state:state(),
101 task_name(), [task_description()]) -> task_description().
102 get_task(_State
, TaskName
, [Task
= #task
{name
= TaskName
} | _
]) ->
104 get_task(State
, TaskName
, [_
| Rest
]) ->
105 get_task(State
, TaskName
, Rest
);
106 get_task(State
, TaskName
, _
) ->
107 ?
SIN_RAISE(State
, {task_not_found
, TaskName
}).
109 process_deps(State
, Task
, Tasks
) ->
110 {DepChain
, _
, _
} = process_deps(State
, Task
, Tasks
, []),
113 lists:flatten([{'NONE', Task#task
.name
} | DepChain
])),
116 process_deps(State
, Task
, Tasks
, Seen
) ->
117 case lists:member(Task
, Seen
) of
121 Deps
= Task#task
.deps
,
122 DepList
= lists:map(fun(Dep
) ->
123 {Dep
, Task#task
.name
}
125 {NewDeps
, _
, NewSeen
} =
126 lists:foldl(fun(Arg
, Acc
) ->
127 process_dep(State
, Arg
, Acc
)
129 {[], Tasks
, Seen
}, Deps
),
130 {[DepList
| NewDeps
], Tasks
, NewSeen
}
133 process_dep(State
, TaskName
, {Deps
, Tasks
, Seen
}) ->
134 Task
= get_task(State
, TaskName
, Tasks
),
135 {NewDeps
, _
, NewSeen
} = process_deps(State
,
136 Task
, Tasks
, [TaskName
| Seen
]),
137 {[Deps
| NewDeps
], Tasks
, NewSeen
}.
139 %% @doc Reorder the tasks according to thier dependency set.
140 reorder_tasks(State
, OTaskList
) ->
141 case sin_topo:sort(OTaskList
) of
145 ?
SIN_RAISE(State
, cycle_fault
,
146 "There was a cycle in the task list. "
147 "Unable to complete build!")
150 %%====================================================================
152 %%====================================================================