Browse files

Start the application during compilation

  • Loading branch information...
1 parent cd02b90 commit 0a9af4e84afc06b5be80e934bd6c7b339492b79d @josevalim josevalim committed Sep 9, 2012
View
41 lib/dynamo/app.ex
@@ -75,8 +75,8 @@ defmodule Dynamo.App do
* `:start_dynamo_app` - starts the Dynamo application registered as `otp_app`
- * `:ensure_endpoint_is_available` - ensure the endpoint is available
- and raises a meaningful error message if not
+ * `:start_dynamo_renderer` - starts dynamo renderer if there
+ are templates to be compiled on demand
"""
@@ -89,7 +89,6 @@ defmodule Dynamo.App do
@before_compile { unquote(__MODULE__), :load_env_file }
@before_compile { unquote(__MODULE__), :normalize_options }
@before_compile { unquote(__MODULE__), :define_filters }
- @before_compile { unquote(__MODULE__), :define_finishers }
@before_compile { unquote(__MODULE__), :define_view_paths }
use Dynamo.Utils.Once
@@ -232,25 +231,15 @@ defmodule Dynamo.App do
Enum.partition(view_paths, fn(path) -> path.eager? end)
end
- compiled_initializer =
- if compiled != [] do
- module = dynamo[:compiled_view_paths]
- view_paths = [module|runtime]
-
- quote location: :keep do
- initializer :ensure_compiled_view_paths_is_available do
- module = unquote(module)
- unless Code.ensure_loaded?(module) do
- raise "could not find compiled view paths module #{inspect module}"
- end
- end
- end
- end
+ if compiled != [] do
+ module = dynamo[:compiled_view_paths]
+ view_paths = [module|runtime]
+ end
renderer_initializer =
if runtime != [] do
quote location: :keep do
- initializer :boot_view_renderer_server do
+ initializer :start_dynamo_renderer do
Dynamo.View.Renderer.start_link
if config[:dynamo][:compile_on_demand] do
@@ -262,23 +251,7 @@ defmodule Dynamo.App do
quote location: :keep do
def view_paths, do: unquote(Macro.escape(view_paths))
- unquote(compiled_initializer)
unquote(renderer_initializer)
end
end
-
- @doc false
- defmacro define_finishers(_) do
- quote location: :keep do
- initializer :ensure_endpoint_is_available do
- if @endpoint && not Code.ensure_compiled?(@endpoint) do
- if config[:dynamo][:compile_on_demand] do
- raise "could not find endpoint #{inspect @endpoint}, please ensure it is available"
- else
- raise "could not find endpoint #{inspect @endpoint}, please ensure it was compiled"
- end
- end
- end
- end
- end
end
View
4 lib/dynamo/app/config.ex
@@ -63,6 +63,10 @@ defmodule Dynamo.App.Config do
def config do
@config
end
+
+ def endpoint do
+ @endpoint
+ end
end
end
end
View
18 lib/mix/dynamo.ex
@@ -2,6 +2,24 @@ defmodule Mix.Dynamo do
@moduledoc false
@doc """
+ Returns the app file location.
+ """
+ def app_file do
+ Mix.project[:dynamo_app] || "config/app.ex"
+ end
+
+ @doc """
+ Check if the app beam file is stale compared to the app file,
+ env files and the mix file.
+ """
+ def stale_app?(app) do
+ mix_file = Mix.Utils.source(Mix.Project.current)
+ env_file = "config/environments/#{Dynamo.env}.exs"
+ app_beam = File.join(Mix.project[:compile_path], "#{app}.beam")
+ Mix.Utils.stale?([app_file(), mix_file, env_file], [app_beam])
+ end
+
+ @doc """
Returns the lock path.
"""
def lock_path do
View
30 lib/mix/tasks/compile.dynamo.ex
@@ -29,13 +29,13 @@ defmodule Mix.Tasks.Compile.Dynamo do
{ opts, files } = OptionParser.parse(args, flags: [:force])
# Load the dynamo app but don't start it.
- # We reenable the task so it can be called
- # down the road and the app finally started.
- Mix.Task.run "dynamo.app", ["--no-start"]
- Mix.Task.reenable "dynamo.app"
+ # We will start it just before compilation
+ # or manually.
+ Mix.Task.run "dynamo.app", ["--no-start", "--no-stale"]
app = Dynamo.app
if app.config[:dynamo][:compile_on_demand] do
+ app.start
:noop
else
do_compile(app, files, opts)
@@ -58,30 +58,26 @@ defmodule Mix.Tasks.Compile.Dynamo do
view_paths = dynamo[:view_paths]
source_paths = dynamo[:source_paths] ++ extract_views(view_paths)
- mix_file = Mix.Utils.source(Mix.Project.current)
- app_file = project[:dynamo_app] || "config/app.ex"
- env_file = "config/environments/#{Mix.env}.exs"
- app_beam = File.join(compile_path, atom_to_binary(app) <> ".beam")
+ to_compile = extract_files(source_paths, files, [:ex])
+ to_watch = extract_files(source_paths, files, compile_exts)
+ targets = [compile_path]
- to_compile = [app_file | extract_files(source_paths, files, [:ex])]
- to_watch = [app_file, env_file, mix_file | extract_files(source_paths, files, compile_exts)]
- targets = [app_beam, compile_path]
-
- if opts[:force] or Mix.Utils.stale?(to_watch, targets) do
- unload_app(app)
+ if opts[:force] or Mix.Dynamo.stale_app?(app) or Mix.Utils.stale?(to_watch, targets) do
File.mkdir_p!(compile_path)
if elixir_opts = project[:elixirc_options] do
Code.compiler_options(elixir_opts)
end
Mix.Dynamo.lock_snapshot fn ->
+ compile_app app, compile_path, root
compile_files List.uniq(to_compile), compile_path, root
compile_views dynamo[:compiled_view_paths], view_paths, compile_path
end
:ok
else
+ app.start
:noop
end
end
@@ -103,6 +99,12 @@ defmodule Mix.Tasks.Compile.Dynamo do
lc view_path inlist view_paths, path = view_path.to_path, do: path
end
+ defp compile_app(app, compile_path, root) do
+ unload_app(app)
+ compile_files [Mix.Dynamo.app_file], compile_path, root
+ Dynamo.app.start
+ end
+
defp compile_files(files, to, root) do
Kernel.ParallelCompiler.files_to_path files, to, fn(original) ->
relative = :binary.replace original, root <> "/", ""
View
19 lib/mix/tasks/dynamo.app.ex
@@ -6,7 +6,7 @@ defmodule Mix.Tasks.Dynamo.App do
It is usually used as dependency by other tasks.
"""
def run(args) do
- { opts, _ } = OptionParser.parse(args, flags: [:compile])
+ { opts, _ } = OptionParser.parse(args)
mixfile = Mix.Utils.source(Mix.Project.current)
Dynamo.start(Mix.env, File.dirname(mixfile))
@@ -17,7 +17,7 @@ defmodule Mix.Tasks.Dynamo.App do
opts[:app] ->
load_app_from_opts(opts[:app])
lock = Mix.Dynamo.read_lock ->
- load_app_from_lock(lock, opts[:compile])
+ load_app_from_lock(lock, opts)
true ->
load_app_from_file
end
@@ -26,7 +26,7 @@ defmodule Mix.Tasks.Dynamo.App do
app
end
- defp load_app_from_lock([env, app|_], _compile) do
+ defp load_app_from_lock([env, app|_], opts) do
app = binary_to_atom(app)
unless env == atom_to_binary(Mix.env) do
@@ -35,11 +35,14 @@ defmodule Mix.Tasks.Dynamo.App do
%b(You can remove the lock and compiled artifacts with `mix clean`.)
end
- unless Code.ensure_loaded?(app) do
- raise Mix.Error, message: "Expected app #{inspect app} in env.lock file to be available, but it is not"
+ cond do
+ opts[:no_stale] && Mix.Dynamo.stale_app?(app) ->
+ load_app_from_file
+ not Code.ensure_loaded?(app) ->
+ raise Mix.Error, message: "Expected app #{inspect app} in env.lock file to be available, but it is not"
+ true ->
+ app
end
-
- app
end
defp load_app_from_opts(app) do
@@ -51,7 +54,7 @@ defmodule Mix.Tasks.Dynamo.App do
end
defp load_app_from_file do
- Code.require_file Mix.project[:dynamo_app] || "config/app.ex"
+ Code.require_file Mix.Dynamo.app_file
app = Dynamo.app || raise "Dynamo.app is not available"
if app.config[:dynamo][:compile_on_demand] do
View
5 lib/mix/tasks/dynamo.filters.ex
@@ -8,12 +8,13 @@ defmodule Mix.Tasks.Dynamo.Filters do
"""
def run(args) do
Mix.Task.run "dynamo.app", args
+ app = Dynamo.app
shell = Mix.shell
- Enum.each Dynamo.app.filters, fn(filter) ->
+ Enum.each app.filters, fn(filter) ->
shell.info "filter #{inspect filter}"
end
- shell.info "#{inspect Dynamo.app}.service/1"
+ shell.info "#{inspect app.endpoint || app}.service/1"
end
end
View
13 lib/mix/tasks/server.ex
@@ -26,8 +26,19 @@ defmodule Mix.Tasks.Server do
{ opts, _ } = OptionParser.parse(args, aliases: [p: :port])
Mix.Task.run "dynamo.app"
+ app = Dynamo.app
+ endpoint = app.endpoint
+
+ if endpoint && not Code.ensure_compiled?(endpoint) do
+ if app.config[:dynamo][:compile_on_demand] do
+ raise "could not find endpoint #{inspect endpoint}, please ensure it is available"
+ else
+ raise "could not find endpoint #{inspect endpoint}, please ensure it was compiled"
+ end
+ end
+
opts = Keyword.merge [port: 4000], opts
- Dynamo.app.run opts
+ app.run opts
:timer.sleep(:infinity)
end
View
6 test/mix/tasks_test.exs
@@ -43,17 +43,17 @@ defmodule Mix.TasksTest do
output = System.cmd "mix dynamo.filters"
assert output =~ %r(filter Dynamo.Filters.Head)
assert output =~ %r(filter \{Dynamo.Filters.Reloader,true,true\})
- assert output =~ %r(MyFiltersApp.service/1)
+ assert output =~ %r(ApplicationRouter.service/1)
# Check it works with first compilation in prod
output = System.cmd "MIX_ENV=prod mix do compile, dynamo.filters"
refute output =~ %r(Dynamo.Filters.Reloader)
- assert output =~ %r(MyFiltersApp.service/1)
+ assert output =~ %r(ApplicationRouter.service/1)
# Check that noop compile also works
output = System.cmd "MIX_ENV=prod mix do compile, dynamo.filters"
refute output =~ %r(Dynamo.Filters.Reloader)
- assert output =~ %r(MyFiltersApp.service/1)
+ assert output =~ %r(ApplicationRouter.service/1)
end
end

0 comments on commit 0a9af4e

Please sign in to comment.