@@ -24,6 +24,27 @@ defmodule Mix.Tasks.GitHooks.Run do
24
24
25
25
@ opaque git_hook_args :: list ( String . t ( ) )
26
26
27
+ @ typedoc """
28
+ Run options:
29
+
30
+ * `include_hook_args?`: Whether the git hook args should be sent to the
31
+ command to be executed. In case of `true`, the args will be amended to the
32
+ command. Defaults to `false`.
33
+ """
34
+ @ type run_opts :: [ { :include_hook_args , String . t ( ) } ]
35
+
36
+ @ doc """
37
+ Runs a task for a given git hook.
38
+
39
+ The task can be one of three different types:
40
+
41
+ * `{:cmd, "command arg1 arg2"}`: Runs a command.
42
+ * `{:file, "path_to_file"}`: Runs an executable file.
43
+ * `"command arg1 arg2"`: Runs a simple command, supports no options.
44
+
45
+ The first two options above can use a third element in the tuple, see
46
+ [here](`t:run_opts/0`) more info about the options.
47
+ """
27
48
@ impl true
28
49
@ spec run ( list ( String . t ( ) ) ) :: :ok | no_return
29
50
def run ( [ ] ) , do: error_exit ( )
@@ -46,34 +67,55 @@ defmodule Mix.Tasks.GitHooks.Run do
46
67
end
47
68
48
69
@ spec run_task ( String . t ( ) , atom , git_hook_args ( ) ) :: :ok | no_return
49
- @ spec run_task ( { :file , String . t ( ) } , atom , git_hook_args ( ) ) :: :ok | no_return
70
+ @ spec run_task ( { :file , String . t ( ) , run_opts ( ) } , atom , git_hook_args ( ) ) :: :ok | no_return
71
+ @ spec run_task ( { :cmd , String . t ( ) , run_opts ( ) } , atom , git_hook_args ( ) ) :: :ok | no_return
50
72
defp run_task ( { :file , script_file } , git_hook_type , git_hook_args ) do
73
+ run_task ( { :file , script_file , [ ] } , git_hook_type , git_hook_args )
74
+ end
75
+
76
+ defp run_task ( { :file , script_file , opts } , git_hook_type , git_hook_args ) do
77
+ args =
78
+ if Keyword . get ( opts , :include_hook_args? , false ) do
79
+ git_hook_args
80
+ else
81
+ [ ]
82
+ end
83
+
51
84
script_file
52
85
|> Path . absname ( )
53
86
|> System . cmd (
54
- git_hook_args ,
55
- stderr_to_stdout: true ,
87
+ args ,
56
88
into: Config . io_stream ( git_hook_type )
57
89
)
58
90
end
59
91
60
- defp run_task ( task , git_hook_type , _git_hook_args ) do
61
- [ command | args ] = String . split ( task , " " )
92
+ defp run_task ( { :cmd , command } , git_hook_type , git_hook_args ) do
93
+ run_task ( { :cmd , command , [ ] } , git_hook_type , git_hook_args )
94
+ end
95
+
96
+ defp run_task ( { :cmd , command , opts } , git_hook_type , git_hook_args ) when is_list ( opts ) do
97
+ [ command | args ] = String . split ( command , " " )
98
+
99
+ command_args =
100
+ if Keyword . get ( opts , :include_hook_args? , false ) do
101
+ Enum . concat ( args , git_hook_args )
102
+ else
103
+ args
104
+ end
62
105
63
106
command
64
107
|> System . cmd (
65
- args ,
66
- stderr_to_stdout: true ,
108
+ command_args ,
67
109
into: Config . io_stream ( git_hook_type )
68
110
)
69
111
|> case do
70
112
{ _result , 0 } ->
71
- Printer . success ( "`#{ task } ` was successful" )
113
+ Printer . success ( "`#{ command } ` was successful" )
72
114
73
115
{ result , _ } ->
74
116
if ! Config . verbose? ( git_hook_type ) , do: IO . puts ( result )
75
117
76
- Printer . error ( "#{ Atom . to_string ( git_hook_type ) } failed on `#{ task } `" )
118
+ Printer . error ( "#{ Atom . to_string ( git_hook_type ) } failed on `#{ command } `" )
77
119
error_exit ( )
78
120
end
79
121
rescue
@@ -82,6 +124,16 @@ defmodule Mix.Tasks.GitHooks.Run do
82
124
error_exit ( )
83
125
end
84
126
127
+ defp run_task ( command , git_hook_type , git_hook_args ) when is_binary ( command ) do
128
+ run_task ( { :cmd , command , [ ] } , git_hook_type , git_hook_args )
129
+ end
130
+
131
+ defp run_task ( task , git_hook_type , _git_hook_args ) ,
132
+ do:
133
+ raise ( """
134
+ Invalid task #{ inspect ( task ) } for hook #{ inspect ( git_hook_type ) } ", only String, {:file, ""} or {:cmd, ""} are supported.
135
+ """ )
136
+
85
137
@ spec get_atom_from_arg ( String . t ( ) ) :: atom | no_return
86
138
defp get_atom_from_arg ( git_hook_type_arg ) do
87
139
case git_hook_type_arg do
0 commit comments