diff options
Diffstat (limited to 'src/rebar_base_compiler.erl')
-rw-r--r-- | src/rebar_base_compiler.erl | 129 |
1 files changed, 59 insertions, 70 deletions
diff --git a/src/rebar_base_compiler.erl b/src/rebar_base_compiler.erl index b6172c2..e1312a9 100644 --- a/src/rebar_base_compiler.erl +++ b/src/rebar_base_compiler.erl @@ -28,58 +28,68 @@ -include("rebar.hrl"). --export([run/8]). +-export([run/4, run/7, run/8]). %% =================================================================== %% Public API %% =================================================================== -run(Config, SourceDir, SourceExt, TargetDir, TargetExt, - FirstFiles, CompileFn, Opts) -> - SourceExtRe = ".*\\" ++ SourceExt ++ [$$], +run(Config, FirstFiles, RestFiles, CompileFn) -> + %% Compile the first files in sequence + compile_each(FirstFiles, Config, CompileFn), - %% Options: - %% recurse_source_dir - %% needs_compile_checks - [ fun/2 ] - Recursive = proplists:get_bool(recurse_source_dir, Opts), - - %% Find all the source files we can - FoundFiles = filelib:fold_files(SourceDir, SourceExtRe, Recursive, - fun(F, Acc) -> [F | Acc] end, []), - - %% Construct two lists of targets. "FirstTargets" is the list of files which - %% must be compiled first and in strict order; "RestTargets" is all remaining files - %% that may be compiled in any order. - FirstTargets = [{Fs, target_file(Fs, SourceDir, SourceExt, TargetDir, TargetExt)} || - Fs <- FirstFiles], - RestTargets = [{Fs, target_file(Fs, SourceDir, SourceExt, TargetDir, TargetExt)} || - Fs <- drop_each(FirstFiles, FoundFiles)], - - %% Setup list of functions which determine if a file needs compilation or not. By - %% default we just check the last modified date - NeedsCompileFns = [ fun check_source_lastmod/3 ] ++ - rebar_config:get(Config, needs_compile_checks, []), - - %% Compile the first targets in sequence - compile_each(FirstTargets, Config, NeedsCompileFns, CompileFn), - - %% Spin up workers - case RestTargets of + %% Spin up workers for the rest of the files + case RestFiles of [] -> ok; _ -> Self = self(), - F = fun() -> compile_worker(Self, Config, NeedsCompileFns, CompileFn) end, + F = fun() -> compile_worker(Self, Config, CompileFn) end, Pids = [spawn_monitor(F) || _I <- lists:seq(1,3)], - compile_queue(Pids, RestTargets) + compile_queue(Pids, RestFiles) end. +run(Config, FirstFiles, SourceDir, SourceExt, TargetDir, TargetExt, Compile3Fn) -> + run(Config, FirstFiles, SourceDir, SourceExt, TargetDir, TargetExt, + Compile3Fn, [check_last_mod]). + +run(Config, FirstFiles, SourceDir, SourceExt, TargetDir, TargetExt, + Compile3Fn, Opts) -> + %% Convert simple extension to proper regex + SourceExtRe = ".*\\" ++ SourceExt ++ [$$], + + %% Find all possible source files + FoundFiles = rebar_utils:find_files(SourceDir, SourceExtRe), + + %% Remove first files from found files + RestFiles = [Source || Source <- FoundFiles, + lists:member(Source, FirstFiles) == false], + + %% Check opts for flag indicating that compile should check lastmod + CheckLastMod = proplists:get_bool(check_last_mod, Opts), + + run(Config, FirstFiles, RestFiles, + fun(S, C) -> + Target = target_file(S, SourceDir, SourceExt, TargetDir, TargetExt), + simple_compile_wrapper(S, Target, Compile3Fn, C, CheckLastMod) + end). + %% =================================================================== %% Internal functions %% =================================================================== +simple_compile_wrapper(Source, Target, Compile3Fn, Config, false) -> + Compile3Fn(Source, Target, Config); +simple_compile_wrapper(Source, Target, Compile3Fn, Config, true) -> + case filelib:last_modified(Target) < filelib:last_modified(Source) of + true -> + Compile3Fn(Source, Target, Config); + false -> + skipped + end. + target_file(SourceFile, SourceDir, SourceExt, TargetDir, TargetExt) -> %% Remove all leading components of the source dir from the file -- we want %% to maintain the deeper structure (if any) of the source file path @@ -97,46 +107,25 @@ remove_common_path1(FilenameParts, _) -> filename:join(FilenameParts). -drop_each([], List) -> - List; -drop_each([Member | Rest], List) -> - drop_each(Rest, lists:delete(Member, List)). - - -needs_compile(_SourceFile, _TargetFile, _Config, []) -> - false; -needs_compile(SourceFile, TargetFile, Config, [Fn | Rest]) -> - case Fn(SourceFile, TargetFile, Config) of - true -> - true; - false -> - needs_compile(SourceFile, TargetFile, Config, Rest) - end. - -check_source_lastmod(SourceFile, TargetFile, _Config) -> - filelib:last_modified(TargetFile) < filelib:last_modified(SourceFile). - -compile(Source, Target, Config, NeedsCompileFns, CompileFn) -> - case needs_compile(Source, Target, Config, NeedsCompileFns) of - true -> - ok = filelib:ensure_dir(Target), - CompileFn(Source, Target, Config); - false -> +compile(Source, Config, CompileFn) -> + case CompileFn(Source, Config) of + ok -> + ok; + skipped -> skipped end. - -compile_each([], _Config, _NeedsCompileFns, _CompileFn) -> +compile_each([], _Config, _CompileFn) -> ok; -compile_each([{Source, Target} | Rest], Config, NeedsCompileFns, CompileFn) -> - case compile(Source, Target, Config, NeedsCompileFns, CompileFn) of +compile_each([Source | Rest], Config, CompileFn) -> + case compile(Source, Config, CompileFn) of ok -> ?CONSOLE("Compiled ~s\n", [Source]); skipped -> ?INFO("Skipped ~s\n", [Source]) end, - compile_each(Rest, Config, NeedsCompileFns, CompileFn). + compile_each(Rest, Config, CompileFn). @@ -149,8 +138,8 @@ compile_queue(Pids, Targets) -> [] -> Worker ! empty, compile_queue(Pids, Targets); - [{Source, Target} | Rest] -> - Worker ! {compile, Source, Target}, + [Source | Rest] -> + Worker ! {compile, Source}, compile_queue(Pids, Rest) end; @@ -176,17 +165,17 @@ compile_queue(Pids, Targets) -> ?FAIL end. -compile_worker(QueuePid, Config, NeedsCompileFns, CompileFn) -> +compile_worker(QueuePid, Config, CompileFn) -> QueuePid ! {next, self()}, receive - {compile, Source, Target} -> - case catch(compile(Source, Target, Config, NeedsCompileFns, CompileFn)) of + {compile, Source} -> + case catch(compile(Source, Config, CompileFn)) of ok -> QueuePid ! {compiled, Source}, - compile_worker(QueuePid, Config, NeedsCompileFns, CompileFn); + compile_worker(QueuePid, Config, CompileFn); skipped -> QueuePid ! {skipped, Source}, - compile_worker(QueuePid, Config, NeedsCompileFns, CompileFn); + compile_worker(QueuePid, Config, CompileFn); Error -> QueuePid ! {fail, Error}, ok |