Packages
fermo
0.16.3
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.4
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 static site generator
Current section
Files
Jump to
Current section
Files
lib/mix/fermo/compiler.ex
defmodule Mix.Fermo.Compiler do
@moduledoc false
require Logger
import Mix.Fermo.Paths, only: [full_source_path: 0]
# Implementations for testing
@compilers Application.get_env(:fermo, :compilers, Fermo.Compilers)
@file_impl Application.get_env(:fermo, :file_impl, File)
@mix_compiler_manifest Application.get_env(:fermo, :mix_compiler_manifest, Mix.Fermo.Compiler.Manifest)
@mix_utils Application.get_env(:fermo, :mix_utils, Mix.Utils)
def run do
:yamerl_app.set_param(:node_mods, [])
compilation_timestamp = compilation_timestamp()
ensure_helpers_module()
all_sources = @compilers.templates(full_source_path())
timestamp = @mix_compiler_manifest.timestamp()
helpers_changed = helpers_changed?(timestamp)
changed = if helpers_changed do
all_sources
else
changed_since(all_sources, timestamp)
end
count = length(changed)
if count > 0 do
Logger.info "Fermo.Compiler compiling #{count} file(s)... "
compilers = @compilers.compilers()
Enum.each(changed, fn {type, template_project_path} ->
Logger.info "Compiling #{template_project_path} with #{type} compiler"
compiler = compilers[type]
compiler.compile(template_project_path)
end)
Logger.info "Done!"
end
{:ok} = @mix_compiler_manifest.write(all_sources, compilation_timestamp)
:ok
end
defp changed_since(types_and_paths, timestamp) do
Enum.filter(types_and_paths, fn {_type, path} ->
@mix_utils.last_modified(path) > timestamp
end)
end
def compilation_timestamp, do: System.os_time(:second)
def helpers_module, do: :"Elixir.Helpers"
def helpers_path, do: "lib/helpers.ex"
def ensure_helpers_module do
Code.ensure_loaded(helpers_module())
has_helpers = has_helpers?()
if !has_helpers do
[{module, bytecode}] = Code.compile_string("defmodule #{helpers_module()} do; defmacro __using__(_opts \\\\ %{}) do; end; end")
base = Mix.Project.compile_path()
module_path = Path.join(base, "#{module}.beam")
@file_impl.write!(module_path, bytecode, [:write])
Code.ensure_loaded(helpers_module())
end
end
def has_helpers? do
function_exported?(helpers_module(), :__info__, 1)
end
def helpers_changed?(timestamp) do
@mix_utils.last_modified(helpers_path()) > timestamp
end
end