Packages
igniter
0.3.47
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/igniter/util/info.ex
defmodule Igniter.Util.Info do
@moduledoc false
require Logger
alias Igniter.Mix.Task.Info
def compose_install_and_validate!(
igniter \\ Igniter.new(),
argv,
schema,
task_name,
opts,
acc \\ []
) do
schema = recursively_compose_schema(schema, argv, task_name, opts)
case schema.installs do
[] ->
igniter =
igniter
|> add_deps(
List.wrap(schema.adds_deps),
opts
)
|> Igniter.apply_and_fetch_dependencies(opts)
{igniter, Enum.uniq(acc), validate!(argv, schema, task_name)}
installs ->
schema = %{schema | installs: []}
install_names = Keyword.keys(installs)
igniter
|> add_deps(
List.wrap(installs),
opts
)
|> Igniter.apply_and_fetch_dependencies(opts)
|> maybe_set_only(install_names, argv, task_name)
|> compose_install_and_validate!(
argv,
%{
schema
| composes: Enum.map(install_names, &"#{&1}.install"),
installs: [],
adds_deps: schema.adds_deps
},
task_name,
Keyword.delete(opts, :only),
acc ++ install_names
)
end
end
defp maybe_set_only(igniter, install_names, argv, parent) do
Enum.reduce(install_names, igniter, fn install, igniter ->
composing_task = "#{install}.install"
with composing_task when not is_nil(composing_task) <- Mix.Task.get(composing_task),
true <- function_exported?(composing_task, :info, 2),
composing_schema when not is_nil(composing_schema) <-
composing_task.info(argv, parent),
only when not is_nil(only) <- composing_schema.only do
Igniter.Project.Deps.set_dep_option(igniter, install, :only, only)
else
_ ->
igniter
end
end)
end
defp add_deps(igniter, add_deps, opts) do
Enum.reduce(add_deps, igniter, fn dependency, igniter ->
with {_, _, dep_opts} <- dependency,
only when not is_nil(only) <- dep_opts[:only],
false <- Mix.env() in only do
Igniter.add_warning(igniter, """
Dependency #{inspect(dependency)} could not be installed,
because it is configured to be installed with `only: #{inspect(only)}`.
Please install it manually, for example:
`MIX_ENV=#{Enum.at(only, 0)} mix igniter.install #{dependency}`.
""")
else
_ ->
Igniter.Project.Deps.add_dep(
igniter,
dependency,
Keyword.merge(opts, notify_on_present?: true, yes?: !!opts[:yes])
)
end
end)
end
def validate!(argv, schema, task_name)
def validate!(_argv, nil, _task_name), do: {[], []}
def validate!(argv, schema, task_name) do
merged_schema = recursively_compose_schema(schema, argv, task_name, [])
options_key =
if merged_schema.extra_args? do
:switches
else
:strict
end
OptionParser.parse!(
argv,
[
{options_key, merged_schema.schema || []},
{:aliases, merged_schema.aliases || []}
]
)
end
defp recursively_compose_schema(%Info{composes: []} = schema, _argv, _parent, _opts), do: schema
defp recursively_compose_schema(%Info{composes: [compose | rest]} = schema, argv, parent, opts) do
with composing_task when not is_nil(composing_task) <- Mix.Task.get(compose),
true <- function_exported?(composing_task, :info, 2),
composing_schema when not is_nil(composing_schema) <- composing_task.info(argv, parent) do
composing_task_name = Mix.Task.task_name(composing_task)
composing_schema =
if opts[:only] do
%{composing_schema | only: opts[:only]}
else
composing_schema
end
recursively_compose_schema(
%Info{
schema
| schema:
merge_schemas(
schema.schema,
composing_schema.schema,
parent,
composing_task_name
),
aliases:
merge_aliases(
schema.aliases,
composing_schema.aliases,
parent,
composing_task_name
),
composes: rest,
extra_args?: schema.extra_args? || composing_schema.extra_args?,
installs: Keyword.merge(composing_schema.installs, schema.installs),
adds_deps: Keyword.merge(composing_schema.adds_deps, schema.adds_deps)
},
argv,
parent,
Keyword.delete(opts, :only)
)
|> Map.put(:composes, List.wrap(composing_schema.composes))
|> recursively_compose_schema(argv, composing_task_name, Keyword.delete(opts, :only))
else
_ ->
recursively_compose_schema(
%{schema | composes: rest},
argv,
parent,
Keyword.delete(opts, :only)
)
end
end
defp merge_schemas(schema, composing_schema, task, composing_task) do
schema = schema || []
composing_schema = composing_schema || []
Keyword.merge(composing_schema, schema, fn key, composing_value, schema_value ->
if composing_value != schema_value do
Logger.warning("""
#{composing_task} has a different configuration for argument: #{key}. Using #{task}'s configuration.
#{composing_task}: #{composing_value}
#{task}: #{schema_value}
""")
end
schema_value
end)
end
defp merge_aliases(aliases, composing_aliases, task, composing_task) do
aliases = aliases || []
composing_aliases = composing_aliases || []
Keyword.merge(composing_aliases, aliases, fn key, composing_value, schema_value ->
if composing_value != schema_value do
Logger.warning("""
#{composing_task} has a different configuration for alias: #{key}. Using #{task}'s configuration.
#{composing_task}: #{composing_value}
#{task}: #{schema_value}
""")
end
schema_value
end)
end
end