-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathmake_version_file.escript
executable file
·115 lines (104 loc) · 4.05 KB
/
make_version_file.escript
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env escript
%% -*- erlang -*-
%% vim: ts=4 sw=4 et ft=erlang
%%
%% Coyright 2021 - Jesse Gumm
%%
%% MIT License
%%
%% The Version calculations were lifted from relx:
%% https://github.com/erlware/relx/blob/6a9eae01662e72f403f2f12967332727dd422678/src/rlx_config.erl#L229
-define(VSN_PREVIOUS, "version.previous").
-define(VSN_OLD_PREVIOUS, ?VSN_PREVIOUS ++ ".old").
-define(VSN_CURRENT, "version.current").
-define(VSN_HISTORY, "version.history").
-define(VSN_LOCK, "version.lock").
main(["go"]) ->
case filelib:is_regular(?VSN_LOCK) of
true ->
io:format("Cannot proceed. Previous version attempt failed. You probably want to run this with the revert option~n"),
halt(1);
false ->
{Vsn, RawRef, RawCount} = collect_default_refcount(),
VsnString = build_vsn_string(Vsn, RawRef, RawCount),
OldVsn = read_file(?VSN_CURRENT),
case VsnString==OldVsn of
true ->
io:format("No version change~n");
false ->
VsnChange = [OldVsn," => ",VsnString],
io:format("Version Change: ~s~n",[VsnChange]),
io:format("Saving new version file: ~s.~n",[?VSN_CURRENT]),
file:rename(?VSN_PREVIOUS, ?VSN_OLD_PREVIOUS),
file:rename(?VSN_CURRENT, ?VSN_PREVIOUS),
file:write_file(?VSN_CURRENT, VsnString),
io:format("Locking Version while release is being generated...~n"),
file:write_file(?VSN_LOCK, "")
end
end;
main(["revert"]) ->
case filelib:is_regular(?VSN_LOCK) of
true ->
file:rename(?VSN_PREVIOUS, ?VSN_CURRENT),
file:rename(?VSN_OLD_PREVIOUS, ?VSN_PREVIOUS),
file:delete(?VSN_LOCK),
io:format("Version File successfully reverted~n");
false ->
io:format("The version is not currently locked~n"),
halt(1)
end;
main(["finish"]) ->
case filelib:is_regular(?VSN_LOCK) of
true ->
NewVsn = read_file(?VSN_CURRENT),
OldVsn = read_file(?VSN_PREVIOUS),
VsnChange = [OldVsn," => ",NewVsn],
TS = timestamp(),
file:write_file(?VSN_HISTORY, ["(",TS,"): ",VsnChange, "\n"], [append]),
file:delete(?VSN_OLD_PREVIOUS),
file:delete(?VSN_LOCK),
io:format("Version Unlocked~n");
false ->
io:format("The version is not currently locked, but that is okay~n")
end;
main(_) ->
ScriptName = escript:script_name(),
io:format("Usage:
./~s go
./~s finish
./~s revert~n", [ScriptName, ScriptName, ScriptName]),
halt(1).
read_file(F) ->
case file:read_file(F) of
{ok, X} -> binary_to_list(X);
{error, _} -> "first-run"
end.
collect_default_refcount() ->
%% Get the tag timestamp and minimal ref from the system. The
%% timestamp is really important from an ordering perspective.
RawRef = os:cmd("git log -n 1 --pretty=format:'%h\n' "),
{Tag, Vsn} = parse_tags(),
RawCount = get_patch_count(Tag),
{Vsn, RawRef, RawCount}.
get_patch_count(RawRef) ->
Ref = re:replace(RawRef, "\\s", "", [global]),
Cmd = io_lib:format("git rev-list --count ~s..HEAD", [Ref]),
os:cmd(Cmd).
build_vsn_string(Vsn, RawRef, RawCount) ->
%% Cleanup the tag and the Ref information. Basically leading 'v's and
%% whitespace needs to go away.
RefTag = [".ref", re:replace(RawRef, "\\s", "", [global])],
Count = re:replace(RawCount, "\\D", "", [global]),
%% Create the valid [semver](http://semver.org) version from the tag
case iolist_to_binary(Count) of
<<"0">> ->
lists:flatten(Vsn);
CountBin ->
binary_to_list(iolist_to_binary([Vsn, "+build.", CountBin, RefTag]))
end.
parse_tags() ->
Tag = os:cmd("git describe --abbrev=0 --tags"),
Vsn = string:trim(string:trim(Tag, leading, "v"), trailing, "\n"),
{Tag, Vsn}.
timestamp() ->
calendar:system_time_to_rfc3339(os:system_time(second)).