/
markdown.ex
99 lines (79 loc) · 2.41 KB
/
markdown.ex
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
defmodule Changex.Formatter.Markdown do
use Changex.Formatter
@moduledoc """
Format changelog to the terminal in markdown format.
"""
@doc """
Take a map of commits in the following format:
%{
fix: %{
scope1: [commit1, commit2],
scope2: [commit5, commit6]
}
feat: %{
scope1: [commit3, commit4],
scope2: [commit7, commit8]
}
}
And return a string in the format:
# v0.0.1
## Bug Fixes
* **Scope 1**
* commit 1 - hash
* commit 2 - hash
* **Scope 2**
* commit 5 - hash
* commit 6 - hash
## Features
* **Scope 1**
* commit 3 - hash
* commit 4 - hash
* **Scope 2**
* commit 7 - hash
* commit 8 - hash
"""
def format(commits, opts \\ []) do
heading(Keyword.get(opts, :version)) <> types(commits, opts)
end
defp heading(version) do
"# #{(version || current_version)}\n"
end
defp types(commits, opts) do
valid_types
|> Enum.filter(fn (type) -> Dict.get(commits, type) end)
|> Enum.map(fn (type) -> build_type(type, Dict.get(commits, type), opts) end)
|> Enum.join("\n")
end
defp build_type(type, commits, opts) when is_map(commits) do
"\n## #{type |> lookup_type}\n\n" <> build_commits(commits, opts)
end
defp build_type(type, _, opts), do: nil
defp build_commits(commits, opts) do
commits
|> Enum.map(fn (commit) -> build_commit_scope(commit, opts) end)
|> Enum.join("\n")
end
defp build_commit_scope({scope, commits}, opts) do
response = " * **#{to_string(scope)}**"
commits
|> Enum.reduce(response, fn (commit, acc) -> build_commit(commit, acc, opts) end)
end
defp build_commit(commit, acc, opts) do
hash = get_hash(commit, opts)
description = Keyword.get(commit, :description) |> String.split("\n") |> Enum.join("\n ")
acc <> "\n * #{description} (#{hash})"
end
defp get_hash(commit, opts) do
hash = Keyword.get(commit, :hash)
if Keyword.has_key?(opts, :github) do
"[#{hash}](https://github.com/#{Keyword.get(opts, :github)}/commit/#{hash})"
else
hash
end
end
defp valid_types, do: [:fix, :feat, :perf, :break]
defp lookup_type(:fix), do: "Bug Fixes"
defp lookup_type(:feat), do: "Features"
defp lookup_type(:perf), do: "Performance Improvements"
defp lookup_type(:break), do: "Breaking Changes"
end