-
Notifications
You must be signed in to change notification settings - Fork 21
/
git_ops.check_message.ex
70 lines (49 loc) · 1.92 KB
/
git_ops.check_message.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
defmodule Mix.Tasks.GitOps.CheckMessage do
use Mix.Task
@shortdoc "Check if a file's content follows the Conventional Commits spec"
@moduledoc """
Receives a file path and validates if it's content follows the Conventional Commits specification.
mix git_ops.check_message <path/to/file>
Logs an error if the commit message is not parse-able.
See https://www.conventionalcommits.org/en/v1.0.0/ for more details on Conventional Commits.
"""
alias GitOps.Commit
alias GitOps.Config
@doc false
def run([path]) do
message = File.read!(path)
case Commit.parse(message) do
{:ok, _} ->
:ok
:error ->
types = Config.types()
not_hidden_types =
types
|> Enum.reject(fn {_type, opts} -> opts[:hidden?] end)
|> Enum.map_join("|", fn {type, _} -> type end)
hidden_types =
types
|> Enum.filter(fn {_type, opts} -> opts[:hidden?] end)
|> Enum.map_join("|", fn {type, _} -> type end)
all_types = "#{not_hidden_types}|#{hidden_types}"
error_exit("""
Not a valid Conventional Commit message:
#{message}
The Conventionl Commit message format is:
<type>[optional scope][optional !]: <description>
[optional body]
[optional footer(s)]
Where:
• <type> is one of #{all_types}
• A bugfix is specified by type `fix`
• A new feature is specified by type `feat`
• A breaking change is specified by either `!` after <type>[optional scope] or by a
`BREAKING CHANGE: <description>` footer.
See https://www.conventionalcommits.org/en/v1.0.0/ for more details.
""")
end
end
def run(_), do: error_exit("Invalid usage. See `mix help git_ops.check_message`")
@spec error_exit(String.t()) :: no_return
defp error_exit(message), do: raise(Mix.Error, message: message)
end