-
-
Notifications
You must be signed in to change notification settings - Fork 20
/
igniter.gen.task.ex
199 lines (161 loc) · 5.55 KB
/
igniter.gen.task.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
defmodule Mix.Tasks.Igniter.Gen.Task do
use Igniter.Mix.Task
@example "mix igniter.gen.task my_app.install"
@shortdoc "Generates a new igniter task"
@moduledoc """
#{@shortdoc}
## Example
```bash
#{@example}
```
## Options
* `--optional` or `-o` - Whether or not to define the task to be compatible with igniter as an optional dependency.
"""
def info(_argv, _source) do
%Igniter.Mix.Task.Info{
example: @example,
positional: [:task_name],
schema: [optional: :boolean],
aliases: [o: :optional]
}
end
def igniter(igniter, argv) do
{%{task_name: task_name}, argv} = positional_args!(argv)
options = options!(argv)
module_name = Module.concat(Mix.Tasks, Mix.Utils.command_to_module_name(to_string(task_name)))
contents =
if options[:optional] do
optional_template(module_name, task_name)
else
template(module_name, task_name)
end
file = "lib/mix/tasks/#{task_name}.ex"
if Igniter.exists?(igniter, file) do
Igniter.add_issue(
igniter,
"Could not generate task #{task_name}, as `#{file}` already exists."
)
else
Igniter.create_new_file(igniter, file, contents)
end
end
defp template(module_name, task_name) do
"""
defmodule #{inspect(module_name)} do
use Igniter.Mix.Task
@example "mix #{task_name} --example arg"
@shortdoc "A short description of your task"
@moduledoc \"\"\"
\#{@shortdoc}
Longer explanation of your task
## Example
```bash
\#{@example}
```
## Options
* `--example-option` or `-e` - Docs for your option
\"\"\"
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
# dependencies to add
adds_deps: [],
# dependencies to add and call their associated installers, if they exist
installs: [],
# An example invocation
example: @example,
# Accept additional arguments that are not in your schema
# Does not guarantee that, when composed, the only options you get are the ones you define
extra_args?: false,
# A list of environments that this should be installed in, only relevant if this is an installer.
only: nil,
# a list of positional arguments, i.e `[:file]`
positional: [],
# Other tasks your task composes using `Igniter.compose_task`, passing in the CLI argv
# This ensures your option schema includes options from nested tasks
composes: [],
# `OptionParser` schema
schema: [],
# CLI aliases
aliases: []
}
end
def igniter(igniter, argv) do
# extract positional arguments according to `positional` above
{arguments, argv} = positional_args!(argv)
# extract options according to `schema` and `aliases` above
options = options!(argv)
# Do your work here and return an updated igniter
igniter
|> Igniter.add_warning("mix #{task_name} is not yet implemented")
end
end
"""
end
defp optional_template(module_name, task_name) do
"""
defmodule #{inspect(module_name)} do
@example "mix #{task_name} --example arg"
@shortdoc "A short description of your task"
if !Code.ensure_loaded?(Igniter) do
@shortdoc "\#{@shortdoc} | Install `igniter` to use"
end
@moduledoc \"\"\"
\#{@shortdoc}
Longer explanation of your task
## Example
```bash
\#{@example}
```
## Options
* `--example-option` or `-e` - Docs for your option
\"\"\"
if Code.ensure_loaded?(Igniter) do
use Igniter.Mix.Task
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
# dependencies to add
adds_deps: [],
# dependencies to add and call their associated installers, if they exist
installs: [],
# An example invocation
example: @example,
# Accept additional arguments that are not in your schema
# Does not guarantee that, when composed, the only options you get are the ones you define
extra_args?: false,
# A list of environments that this should be installed in, only relevant if this is an installer.
only: nil,
# a list of positional arguments, i.e `[:file]`
positional: [],
# Other tasks your task composes using `Igniter.compose_task`, passing in the CLI argv
# This ensures your option schema includes options from nested tasks
composes: [],
# `OptionParser` schema
schema: [],
# CLI aliases
aliases: []
}
end
def igniter(igniter, argv) do
# extract positional arguments according to `positional` above
{arguments, argv} = positional_args!(argv)
# extract options according to `schema` and `aliases` above
options = options!(argv)
# Do your work here and return an updated igniter
igniter
|> Igniter.add_warning("mix #{task_name} is not yet implemented")
end
else
use Mix.Task
def run(_argv) do
Mix.shell().error(\"\"\"
The task '#{task_name}' requires igniter to be run.
Please install igniter and try again.
For more information, see: https://hexdocs.pm/igniter
\"\"\")
exit({:shutdown, 1})
end
end
end
"""
end
end