summaryrefslogtreecommitdiff
path: root/src/rebar_app_discover.erl
blob: 425226234fc5e2f90962e20270cbbf191b2439d2 (plain)
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
-module(rebar_app_discover).

-export([do/2,
         find_apps/1]).

do(Config, LibDirs) ->
    Apps = find_apps(LibDirs),
    lists:foldl(fun(AppInfo, ConfigAcc) ->
                        rebar_config:add_app(ConfigAcc, AppInfo)
            end, Config, Apps).

-spec all_app_dirs(list(file:name())) -> list(file:name()).
all_app_dirs(LibDirs) ->
    lists:flatmap(fun(LibDir) ->
                          app_dirs(LibDir)
                  end, LibDirs).

app_dirs(LibDir) ->
    Path1 = filename:join([LibDir,
                           "*",
                           "src",
                           "*.app.src"]),
    Path2 = filename:join([LibDir,
                           "src",
                           "*.app.src"]),

    Path3 = filename:join([LibDir,
                           "*",
                           "ebin",
                           "*.app"]),
    Path4 = filename:join([LibDir,
                           "ebin",
                           "*.app"]),

    lists:usort(lists:foldl(fun(Path, Acc) ->
                                    Files = filelib:wildcard(Path),
                                    [app_dir(File) || File <- Files] ++ Acc
                            end, [], [Path1, Path2, Path3, Path4])).

find_apps(LibDirs) ->
    lists:map(fun(AppDir) ->
                      AppFile = filelib:wildcard(filename:join([AppDir, "ebin", "*.app"])),
                      AppSrcFile = filelib:wildcard(filename:join([AppDir, "src", "*.app.src"])),
                      case AppFile of
                          [File] ->
                              AppInfo = create_app_info(AppDir, File),
                              AppInfo1 = rebar_app_info:app_file(AppInfo, File),
                              case AppSrcFile of
                                  [F] ->
                                      rebar_app_info:app_file_src(AppInfo1, F);
                                  [] ->
                                      AppInfo1
                              end;
                          [] ->
                              case AppSrcFile of
                                  [File] ->
                                      AppInfo = create_app_info(AppDir, File),
                                      rebar_app_info:app_file_src(AppInfo, File);
                                  [] ->
                                      error
                              end
                      end
              end, all_app_dirs(LibDirs)).

app_dir(AppFile) ->
    filename:join(lists:droplast(filename:split(filename:dirname(AppFile)))).

create_app_info(AppDir, AppFile) ->
    case file:consult(AppFile) of
        {ok, [{application, AppName, AppDetails}]} ->
            AppVsn = proplists:get_value(vsn, AppDetails),
            AbsCwd = filename:absname(rebar_utils:get_cwd()),
            {ok, AppInfo} = rebar_app_info:new(AppName, AppVsn, AppDir),
            RebarConfig = filename:join(AppDir, "rebar.config"),
            AppConfig = case filelib:is_file(RebarConfig) of
                            true ->
                                rebar_config:new(RebarConfig);
                            false ->
                                rebar_config:new()
                        end,
            AppConfig1 = rebar_config:set_xconf(AppConfig, base_dir, AbsCwd),
            AppInfo1 = rebar_app_info:config(AppInfo, AppConfig1),
            rebar_app_info:dir(AppInfo1, AppDir)
    end.