Current section
Files
Jump to
Current section
Files
lib/raxx/kit.ex
defmodule Raxx.Kit do
@enforce_keys [
:name,
:module,
:docker,
:api_blueprint,
:node_assets
]
defstruct @enforce_keys
def generate(options) do
# TODO check if dir exists
config = check_config!(options)
:ok = Mix.Generator.create_directory(config.name)
File.cd!(config.name, fn ->
assigns = Map.from_struct(config)
:ok =
template_dir()
|> Path.join("./**/*")
|> Path.wildcard(match_dot: true)
|> Enum.each(©_template(&1, template_dir(), assigns))
# If using docker elixir and mix might not be installed so this should be run in docker
if !config.docker do
Mix.shell().cmd("mix deps.get")
end
end)
# If using docker node might not be installed so this should be run in docker
if !config.docker && config.node_assets do
File.cd!(config.name <> "/lib/" <> config.name <> "/www", fn ->
Mix.shell().cmd("nodejs -v")
Mix.shell().cmd("npm install")
end)
end
message =
"""
Your Raxx project was created successfully.
Get started:
cd #{config.name}
#{if config.docker, do: "docker-compose up", else: "iex -S mix"}
View on http://localhost:8080
View on https://localhost:8443 (NOTE: uses a self signed certificate)
"""
|> String.trim_trailing()
{:ok, message}
end
defp check_config!(options) do
{:ok, name} = Keyword.fetch(options, :name)
module = Keyword.get(options, :module, Macro.camelize(name))
docker = Keyword.get(options, :docker, false)
node_assets = Keyword.get(options, :node_assets, false)
api_blueprint = Keyword.get(options, :apib, false)
%__MODULE__{
name: name,
module: module,
docker: docker,
api_blueprint: api_blueprint,
node_assets: node_assets
}
end
defp template_dir() do
Application.app_dir(:raxx_kit, "priv/template")
end
defp copy_template(file, root, assigns) do
case File.read(file) do
{:error, :eisdir} ->
Mix.Generator.create_directory(file)
{:ok, template} ->
path = Path.relative_to(file, root)
{path, contents} =
case String.split(path, ~r/\.eex$/) do
[path, ""] ->
path = String.replace(path, "app_name", assigns.name)
contents = EEx.eval_string(template, assigns: assigns)
{path, contents}
[path] ->
path = String.replace(path, "app_name", assigns.name)
contents = template
{path, contents}
end
if String.trim(contents) == "" do
:ok
else
Mix.Generator.create_file(path, contents)
end
end
end
end