summaryrefslogtreecommitdiff
path: root/build-aux/introspect
blob: 9b527455f09edba81f20d009620530fcaecf8597 (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
#!/usr/bin/env escript
%% -*- mode: erlang -*-

main(_) ->
    introspect("rebar.config.script").

introspect(File) ->
    Bindings = [{'SCRIPT', File}, {'CONFIG', []}],
    {ok, Config} = file:script(File, Bindings),
    {deps, Deps} = lists:keyfind(deps, 1, Config),
    introspect_deps(Deps).

introspect_deps([]) ->
    ok;
introspect_deps([Dep | Rest]) ->
    introspect_dep(Dep),
    introspect_deps(Rest).

introspect_dep({App, VsnRegex, {git, Url, From}, _Raw}) ->
    introspect_dep({App, VsnRegex, {git, Url, From}});
introspect_dep({App, _VsnRegex, {git, _Url, From}}) ->
    io:format(bold("~s~n"), [App]),
    introspect_diff(App, From),
    io:format("~n", []),
    ok.

revision({branch, Branch}) ->
    Branch;
revision({tag, Tag}) ->
    Tag;
revision(Rev) ->
    Rev.

introspect_diff(App, From) ->
    introspect_diff(App, revision(From), "origin/master").

introspect_diff(App, From, ToBranch) ->
    {ok, Log} = sh(App, io_lib:format("git log --pretty=oneline ~s..~s", [From, ToBranch])),
    case Log of
        [] ->
            io:format("  up to date on ~s~n", [bold(ToBranch)]);
        _ ->
            io:format("  ~B commits behind ~s~n", [length(Log), bold(ToBranch)]),
            io:format("~s~n~n", [string:join(["    " ++ L || L <- Log], "\n")])
    end.

sh(App, Cmd) ->
    Dir = lists:flatten(["src/", atom_to_list(App)]),
    Port = open_port({spawn, lists:flatten(Cmd)},
                     [{cd, Dir},
                      {line, 16384},
                      exit_status,
                      stderr_to_stdout,
                      use_stdio]),
    read_port(Port).

read_port(Port) ->
    read_port(Port, []).

read_port(Port, Acc) ->
    receive
        {Port, {data, {eol, Line}}} ->
            read_port(Port, [Line | Acc]);
        {Port, {data, {noeol, Line}}} ->
            read_port(Port, [Line | Acc]);
        {Port, {exit_status, 0}} ->
            {ok, lists:reverse(Acc)};
        {Port, {exit_status, Code}} ->
            {error, Code, Acc}
    end.

bold(Text) ->
    "\e[1m" ++ Text ++ "\e[0m".