Packages
igniter_new
0.5.31
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.12
0.4.11
0.4.10
0.4.9
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.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.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Create a new mix project with igniter, and run igniter installers in one command!
Current section
Files
Jump to
Current section
Files
lib/task_helpers.ex
defmodule Igniter.Installer.TaskHelpers do
@moduledoc false
@apps [:logger, :public_key, :ssl, :inets, :eex]
@tasks [
"igniter.install": %{
mfa: {Igniter.CopiedTasks, :install, []}
},
"igniter.add": %{
mfa: {Igniter.CopiedTasks, :add, []}
},
"igniter.remove": %{
mfa: {Igniter.CopiedTasks, :remove, []}
},
"igniter.upgrade": %{
mfa: {Igniter.CopiedTasks, :upgrade, []}
},
"igniter.apply_upgrades": %{
mfa: {Igniter.CopiedTasks, :apply_upgrades, []}
}
]
def tasks do
for {task_name, config} <- @tasks do
task_name = to_string(task_name)
{task_name, Map.put(config, :module, mod_for_task(task_name))}
end
end
defp mod_for_task(task_name) do
task_name
|> String.split(".")
|> Enum.map(&Macro.camelize/1)
|> then(&[Mix.Tasks | &1])
|> Module.concat()
end
def copy_docs do
for {task_name, _} <- tasks() do
{short_doc_output, 0} =
System.cmd("mix", ["help", "--search", task_name], cd: "..")
short_doc =
short_doc_output
|> String.split("\n")
|> Enum.find(&String.starts_with?(&1, "mix #{task_name} "))
|> String.split("#", parts: 2)
|> Enum.at(1)
|> String.trim()
{long_doc_output, 0} = System.cmd("mix", ["help", task_name], cd: "..")
long_doc =
long_doc_output
|> String.split("\n")
|> Enum.slice(3..-3//1)
|> Enum.join("\n")
|> String.trim()
File.mkdir_p!("priv/docs/#{task_name}")
File.write!("priv/docs/#{task_name}/short.txt", short_doc)
File.write!("priv/docs/#{task_name}/long.txt", long_doc)
end
end
def long_doc(task_name) do
path = "priv/docs/#{task_name}/long.txt"
if File.exists?(path) do
File.read!(path)
else
"unknown"
end
end
def short_doc(task_name) do
path = "priv/docs/#{task_name}/short.txt"
if File.exists?(path) do
File.read!(path)
else
"unknown"
end
end
def wrap_task(task_name, {module, fun, args}, argv) do
prevent_infinite_loops!(argv)
load_deps(argv)
ensure_apps_started!()
update_igniter(argv)
argv = Enum.reject(argv, &(&1 in ["--igniter-repeat", "--from-igniter-new"]))
if Code.ensure_loaded?(module) do
apply(module, fun, [argv] ++ args)
else
if File.exists?("mix.exs") do
ensure_igniter_and_install(task_name, argv)
else
Mix.shell().error("""
Not in a mix project. No `mix.exs` file was found.
Did you mean `mix igniter.new`?
""")
exit({:shutdown, 1})
end
end
end
defp ensure_igniter_and_install(task_name, argv) do
cleanup? = ensure_igniter!()
if !Process.get(:registered_on_exit?) do
Process.put(:registered_on_exit?, true)
System.at_exit(fn _ ->
cleanup(cleanup?, argv)
end)
end
Mix.Project.clear_deps_cache()
Mix.Project.pop()
Mix.Dep.clear_cached()
old_undefined = Code.get_compiler_option(:no_warn_undefined)
old_relative_paths = Code.get_compiler_option(:relative_paths)
old_ignore_module_conflict = Code.get_compiler_option(:ignore_module_conflict)
try do
Code.compiler_options(
relative_paths: false,
no_warn_undefined: :all,
ignore_module_conflict: true
)
_ = Code.compile_file("mix.exs")
after
Code.compiler_options(
relative_paths: old_relative_paths,
no_warn_undefined: old_undefined,
ignore_module_conflict: old_ignore_module_conflict
)
end
Igniter.Installer.Loading.with_spinner(
"compiling igniter",
fn ->
case System.cmd("mix", ["deps.get"]) do
{_, 0} ->
:ok
{output, status} ->
raise("""
mix deps.get failed with exit code #{status}.
Output:
#{output}
""")
end
Mix.Task.reenable("deps.compile")
Mix.Task.reenable("deps.loadpaths")
Mix.Task.run("deps.compile", [])
Mix.Task.run("deps.loadpaths", ["--no-deps-check"])
Mix.Task.reenable("deps.compile")
Mix.Task.reenable("deps.loadpaths")
end,
verbose?: "--verbose" in argv
)
Mix.Task.reenable(task_name)
Mix.Task.run(task_name, argv ++ ["--igniter-repeat"])
end
defp cleanup(cleanup?, argv) do
if cleanup? do
Igniter.Installer.Loading.with_spinner(
"cleaning up",
fn ->
apply(Igniter.CopiedTasks, :remove, [["igniter", "--yes"]])
end,
verbose?: "--verbose" in argv
)
end
end
defp ensure_igniter! do
contents =
"mix.exs"
|> File.read!()
new_contents =
Igniter.Installer.Loading.with_spinner(
"temporarily adding igniter",
fn ->
new_contents =
contents
|> add_igniter_dep()
if contents == new_contents do
contents
else
new_contents
|> Code.format_string!()
end
end
)
if new_contents == contents && !String.contains?(contents, "{:igniter,") do
Mix.shell().error("""
Failed to add igniter to mix.exs. Please add it manually and try again
For more information, see: https://hexdocs.pm/igniter/readme.html#installation
""")
exit({:shutdown, 1})
end
File.write!("mix.exs", new_contents)
new_contents != contents
end
defp load_deps(argv) do
message =
cond do
"--igniter-repeat" in argv ->
"setting up igniter"
"--from-igniter-new" in argv ->
"installing igniter"
true ->
"checking for igniter in project"
end
Igniter.Installer.Loading.with_spinner(
message,
fn ->
if Code.ensure_loaded?(Igniter.Util.Install) do
Mix.Task.run("deps.loadpaths", ["--no-deps-check"])
end
end,
verbose?: "--verbose" in argv
)
end
defp update_igniter(argv) do
if !Process.get(:updated_igniter?) do
Igniter.Installer.Loading.with_spinner(
"Updating project's igniter dependency",
fn ->
System.cmd("mix", ["deps.update", "igniter"], stderr_to_stdout: true)
end,
verbose?: "--verbose" in argv
)
Process.put(:updated_igniter?, true)
end
end
defp ensure_apps_started! do
archives_path = Mix.path_for(:archives)
archive_apps =
archives_path
|> File.ls()
|> case do
{:ok, entries} ->
entries
_ ->
[]
end
|> Enum.map(&Mix.Local.archive_ebin/1)
|> Enum.map(&Path.join([archives_path, &1, "*.app"]))
|> Enum.flat_map(&Path.wildcard/1)
|> Enum.map(&Path.basename(&1, ".app"))
|> Enum.map(&String.to_atom/1)
for app <- @apps ++ archive_apps do
try do
Mix.ensure_application!(app)
rescue
_ ->
:ok
end
end
Application.ensure_all_started(:rewrite)
end
defp prevent_infinite_loops!(argv) do
if Enum.count(argv, &(&1 == "--igniter-repeat")) > 1 do
Mix.shell().error("""
There was a problem installing or setting up igniter.
Run your command again with `--verbose` to see more detail.
""")
exit({:shutdown, 1})
end
end
defp add_igniter_dep(contents) do
version_requirement = "\"~> 0.6\""
if String.contains?(contents, "{:igniter") do
contents
else
Mix.Tasks.Igniter.New.add_igniter_dep(contents, version_requirement)
end
end
end