Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement Mix.Project.application values validation

Closes #685

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
  • Loading branch information...
commit cf5f57f07a74a46a9cbbe10fc065f7cf1d60a11f 1 parent fc03c8b
@yrashk yrashk authored josevalim committed
View
45 lib/mix/lib/mix/tasks/compile.app.ex
@@ -88,6 +88,49 @@ defmodule Mix.Tasks.Compile.App do
properties = Keyword.from_enum(properties)
properties = Keyword.put properties, :description,
to_char_list(properties[:description] || app)
- Keyword.put properties, :registered, (properties[:registered] || [])
+ properties = Keyword.put properties, :registered, (properties[:registered] || [])
+ validate_properties(properties)
+ properties
+ end
+
+ defp validate_properties(properties) do
+ unless nil?(properties[:description]) or is_list(properties[:description]) do
+ raise(Mix.Error, message: "Application description (:description) is not a character list (got #{inspect properties[:description]})")
+ end
+ unless nil?(properties[:id]) or is_list(properties[:id]) do
+ raise(Mix.Error, message: "Application id (:id) is not a character list (got #{inspect properties[:id]} instead)")
+ end
+ unless nil?(properties[:vsn]) or is_list(properties[:vsn]) do
+ raise(Mix.Error, message: "Application vsn (:vsn) is not a character list (got #{inspect properties[:vsn]} instead)")
+ end
+ unless nil?(properties[:modules]) or (is_list(properties[:modules]) and Enum.all?(properties[:modules], is_atom(&1))) do
+ raise(Mix.Error, message: "Application modules (:modules) should be a list of atoms (got #{inspect properties[:modules]} instead)")
+ end
+ unless nil?(properties[:maxT]) or properties[:maxT] == :infinity or is_integer(properties[:maxT]) do
+ raise(Mix.Error, message: "Application maximum time (:maxT) is not an integer or :infinity (got #{inspect properties[:maxT]} instead)")
+ end
+ unless nil?(properties[:registered]) or is_list(properties[:registered]) and (Enum.all?(properties[:registered], is_atom(&1))) do
+ raise(Mix.Error, message: "Application registered processes (:registered) should be a list of atoms (got #{inspect properties[:registered]} instead)")
+ end
+ unless nil?(properties[:included_applications]) or (is_list(properties[:included_applications]) and Enum.all?(properties[:included_applications], is_atom(&1))) do
+ raise(Mix.Error, message: "Application included applications (:included_applications) should be a list of atoms (got #{inspect properties[:included_applications]} instead)")
+ end
+ unless nil?(properties[:applications]) or (is_list(properties[:applications]) and Enum.all?(properties[:applications], is_atom(&1))) do
+ raise(Mix.Error, message: "Application dependencies (:applications) should be a list of atoms (got #{inspect properties[:applications]} instead)")
+ end
+ unless nil?(properties[:env]) or (Keyword.keyword?(properties[:env])) do
+ raise(Mix.Error, message: "Application dependencies (:env) should be a keyword list (got #{inspect properties[:env]} instead)")
+ end
+ unless nil?(properties[:mod]) do
+ case properties[:mod] do
+ [] -> :ok
+ {module, _start_args} when is_atom(module) -> :ok
+ other ->
+ raise(Mix.Error, message: "Application callback module (:mod) should be either [] or {module, start_args} (got #{inspect properties[:mod]} instead)")
+ end
+ end
+ unless nil?(properties[:start_phases]) or (Keyword.keyword?(properties[:start_phases])) do
+ raise(Mix.Error, message: "Application start phases (:start_phases) should be a keyword list (got #{inspect properties[:start_phases]} instead)")
+ end
end
end
View
37 lib/mix/test/mix/tasks/compile.app_test.exs
@@ -19,6 +19,25 @@ defmodule Mix.Tasks.Compile.AppTest do
end
end
+ defmodule InvalidProject do
+ def project do
+ [app: :invalid_project, version: "0.3.0"]
+ end
+
+ def application do
+ case Process.get(:error) do
+ :modules -> [modules: :invalid]
+ :maxT -> [maxT: :invalid]
+ :registered -> [registered: ["invalid"]]
+ :included_applications -> [included_applications: ["invalid"]]
+ :applications -> [applications: ["invalid"]]
+ :env -> [env: [:a]]
+ :mod -> [mod: {Mod}]
+ :start_phases -> [start_phases: [:invalid]]
+ end
+ end
+ end
+
test "generates .app file when changes happen" do
Mix.Project.push SimpleProject
@@ -54,6 +73,24 @@ defmodule Mix.Tasks.Compile.AppTest do
Mix.Project.pop
end
+ test "application properties validation" do
+ Mix.Project.push InvalidProject
+
+ in_fixture "no_mixfile", fn ->
+ lc error inlist [:modules, :maxT, :registered, :included_applications,
+ :applications, :env, :mod, :start_phases] do
+ Process.put(:error, error)
+ assert e = Mix.Error[] = catch_error(Mix.Tasks.Compile.App.run([]))
+ assert e.message =~ %r/:#{error}/
+ assert e.message =~ %r/#{inspect InvalidProject.application[error]}/
+ end
+ Process.delete(:error)
+ end
+ after
+ purge [A, B, C]
+ Mix.Project.pop
+ end
+
test ".app contains description and registered (as required by systools)" do
Mix.Project.push SimpleProject
Please sign in to comment.
Something went wrong with that request. Please try again.