defmodule JacobCli.Services.ShellExtensionInstaller do require EEx @moduledoc false @doc """ Run the installation. """ def run(shell) do Jacob.escript_name() |> Kernel.to_string() |> run(shell) end def run(app_name, shell) when is_binary(app_name) do with rendered_extension = render_extension(shell, app_name), :ok <- create_extension_file(shell, rendered_extension), :ok <- add_extension_in_shell_config(shell), do: :ok end defp add_extension_in_shell_config(shell) do unless extension_already_sourced?(shell), do: source_extension(shell) :ok end # Metaprogramming hell @shells [ %{ name: :bash, extension_filename: "bash_extension", extension_template: "bash_extension.eex", config: "~/.bashrc" }, %{ name: :zsh, extension_filename: "zsh_extension", extension_template: "zsh_extension.eex", config: "~/.zshrc" } ] for shell <- @shells do template_file = JacobCli.template_path("/installers/#{shell.extension_template}") @external_resource template_file compiled_template = EEx.compile_file(template_file, file: template_file, line: 1) def render_extension(unquote(shell.name), app_name), do: unquote(compiled_template) defp create_extension_file(unquote(shell.name), rendered_extension) do Jacob.Files.save(unquote(shell.extension_filename), rendered_extension) end defp source_string(unquote(shell.name)) do "source #{Jacob.Files.dot_directory_path(unquote(shell.extension_filename))}" end defp source_extension(shell = unquote(shell.name)) do unquote(shell.config) |> Path.expand() |> File.open!([:append]) |> IO.puts(source_string(shell)) :ok end defp extension_already_sourced?(shell = unquote(shell.name)) do unquote(shell.config) |> Path.expand() |> File.read!() |> String.contains?(source_string(shell)) end end end