Packages
igniter
0.5.43
0.8.2
0.8.1
0.8.0
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.30
0.6.29
0.6.28
0.6.27
0.6.26
0.6.25
0.6.24
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.52
0.5.51
0.5.50
0.5.49
0.5.48
0.5.47
0.5.46
0.5.45
0.5.44
0.5.43
0.5.42
0.5.41
0.5.40
0.5.39
0.5.38
0.5.37
0.5.36
0.5.35
0.5.34
0.5.33
0.5.32
0.5.31
0.5.30
0.5.29
0.5.28
0.5.27
0.5.26
0.5.25
0.5.24
0.5.23
0.5.22
0.5.21
0.5.20
0.5.19
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.78
0.3.77
0.3.76
0.3.75
0.3.74
0.3.73
0.3.72
0.3.71
0.3.70
0.3.69
0.3.68
0.3.67
0.3.66
0.3.65
0.3.64
0.3.63
0.3.62
0.3.61
0.3.60
0.3.59
0.3.58
0.3.57
0.3.56
0.3.55
0.3.54
0.3.53
0.3.52
0.3.51
0.3.50
0.3.49
0.3.48
0.3.47
0.3.46
0.3.45
0.3.44
0.3.43
0.3.42
0.3.41
0.3.40
0.3.39
0.3.38
0.3.37
0.3.36
0.3.35
0.3.34
0.3.33
0.3.32
0.3.31
0.3.30
0.3.29
0.3.28
0.3.27
0.3.26
0.3.25
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A code generation and project patching framework
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/igniter.gen.task.ex
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
* `--no-optional` or `-o` - Whether or not to define the task to be compatible with igniter as an optional dependency.
* `--upgrade` or `-u` - Whether or not the task is an upgrade task. See the upgrades guide for more.
* `--private` or `-p` - Whether or not the task is a private task. This means it has no shortdoc or moduledoc.
Upgrade tasks are always private.
"""
def info(_argv, _source) do
%Igniter.Mix.Task.Info{
group: :igniter,
example: @example,
positional: [:task_name],
schema: [optional: :boolean, upgrade: :boolean, private: :boolean],
aliases: [o: :optional, u: :upgrade, p: :private],
defaults: [optional: true, upgrade: false, private: false]
}
end
def igniter(igniter) do
task_name = igniter.args.positional.task_name
options = igniter.args.options
options =
if options[:upgrade] do
Keyword.put(options, :private, true)
else
options
end
module_name = Module.concat(Mix.Tasks, Mix.Utils.command_to_module_name(to_string(task_name)))
app_name = Igniter.Project.Application.app_name(igniter)
contents =
if options[:optional] do
optional_template(module_name, task_name, app_name, options)
else
template(module_name, task_name, app_name, options)
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, app_name, opts) do
docs =
if opts[:private] do
"@moduledoc false"
else
"""
@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
\"\"\"
"""
end
"""
defmodule #{inspect(module_name)} do
use Igniter.Mix.Task
@example "mix #{task_name} --example arg"
#{docs}
@impl Igniter.Mix.Task
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
# Groups allow for overlapping arguments for tasks by the same author
# See the generators guide for more.
group: #{inspect(app_name)},
# *other* dependencies to add
# i.e `{:foo, "~> 2.0"}`
adds_deps: [],
# *other* dependencies to add and call their associated installers, if they exist
# i.e `{:foo, "~> 2.0"}`
installs: [],
# An example invocation
example: @example,
#{only(opts, task_name)}\
# a list of positional arguments, i.e `[:file]`
positional: #{positional(opts)},
# 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: [],
# Default values for the options in the `schema`
defaults: [],
# CLI aliases
aliases: [],
# A list of options in the schema that are required
required: []
}
end
@impl Igniter.Mix.Task
def igniter(igniter) do
#{execute(opts, task_name)}
end
end
"""
end
defp docs_module(module_name, task_name, opts) do
if opts[:private] do
""
else
"""
defmodule #{inspect(module_name)}.Docs do
@moduledoc false
def short_doc do
"A short description of your task"
end
def example do
"mix #{task_name} --example arg"
end
def long_doc do
\"\"\"
\#{short_doc()}
Longer explanation of your task
## Example
```bash
\#{example()}
```
## Options
* `--example-option` or `-e` - Docs for your option
\"\"\"
end
end
"""
end
end
defp optional_template(module_name, task_name, app_name, opts) do
"""
#{docs_module(module_name, task_name, opts)}
if Code.ensure_loaded?(Igniter) do
defmodule #{inspect(module_name)} do
#{optional_docs(opts, :present)}
use Igniter.Mix.Task
@impl Igniter.Mix.Task
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
# Groups allow for overlapping arguments for tasks by the same author
# See the generators guide for more.
group: #{inspect(app_name)},
# *other* dependencies to add
# i.e `{:foo, "~> 2.0"}`
adds_deps: [],
# *other* dependencies to add and call their associated installers, if they exist
# i.e `{:foo, "~> 2.0"}`
installs: [],
#{example(opts, task_name)}\
#{only(opts, task_name)}\
# a list of positional arguments, i.e `[:file]`
positional: #{positional(opts)},
# 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: [],
# Default values for the options in the `schema`
defaults: [],
# CLI aliases
aliases: [],
# A list of options in the schema that are required
required: []
}
end
@impl Igniter.Mix.Task
def igniter(igniter) do
#{execute(opts, task_name)}
end
end
else
defmodule #{inspect(module_name)} do
#{optional_docs(opts, :missing)}
use Mix.Task
def run(_argv) do
Mix.shell().error(\"\"\"
The task '#{task_name}' requires igniter. Please install igniter and try again.
For more information, see: https://hexdocs.pm/igniter/readme.html#installation
\"\"\")
exit({:shutdown, 1})
end
end
end
"""
end
defp optional_docs(opts, location) do
if opts[:private] do
"@moduledoc false"
else
install_igniter =
if location == :missing do
" | Install `igniter` to use"
else
""
end
"""
@shortdoc "\#{__MODULE__.Docs.short_doc()}#{install_igniter}"
@moduledoc __MODULE__.Docs.long_doc()
"""
end
end
defp only(opts, task_name) do
if !opts[:upgrade] && String.ends_with?(task_name, ".install") do
"""
# A list of environments that this should be installed in.
only: nil,
"""
else
""
end
end
defp example(opts, _task_name) do
if opts[:private] do
""
else
"""
# An example invocation
example: __MODULE__.Docs.example(),
"""
end
end
defp execute(opts, task_name) do
if opts[:upgrade] do
"""
positional = igniter.args.positional
options = igniter.args.options
upgrades = %{
# "0.1.1" => [&change_foo_to_bar/2]
}
# For each version that requires a change, add it to this map
# Each key is a version that points at a list of functions that take an
# igniter and options (i.e. flags or other custom options).
# See the upgrades guide for more.
Igniter.Upgrades.run(igniter, positional.from, positional.to, upgrades, custom_opts: options)
"""
else
"""
# Do your work here and return an updated igniter
igniter
|> Igniter.add_warning("mix #{task_name} is not yet implemented")
"""
end
end
defp positional(opts) do
if opts[:upgrade] do
"[:from, :to]"
else
"[]"
end
end
end