Skip to content

Commit

Permalink
Validate all app properties and do not accept nil values
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Dec 2, 2012
1 parent cf5f57f commit 4e8fb99
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 41 deletions.
84 changes: 45 additions & 39 deletions lib/mix/lib/mix/tasks/compile.app.ex
Expand Up @@ -19,7 +19,7 @@ defmodule Mix.Tasks.Compile.App do
http://www.erlang.org/doc/design_principles/applications.html http://www.erlang.org/doc/design_principles/applications.html
## Configuration ## Configuration
* `:app` - The application name as a binary (required) * `:app` - The application name as a binary (required)
* `:version` - The application version as a binary (required) * `:version` - The application version as a binary (required)
Expand Down Expand Up @@ -86,51 +86,57 @@ defmodule Mix.Tasks.Compile.App do


defp ensure_correct_properties(app, properties) do defp ensure_correct_properties(app, properties) do
properties = Keyword.from_enum(properties) properties = Keyword.from_enum(properties)
properties = Keyword.put properties, :description, properties = Keyword.put properties, :description,
to_char_list(properties[:description] || app) to_char_list(properties[:description] || app)
properties = Keyword.put properties, :registered, (properties[:registered] || []) properties = Keyword.put properties, :registered, (properties[:registered] || [])
validate_properties(properties) validate_properties(properties)
properties properties
end end


defp validate_properties(properties) do defp validate_properties(properties) do
unless nil?(properties[:description]) or is_list(properties[:description]) do Enum.each properties, fn
raise(Mix.Error, message: "Application description (:description) is not a character list (got #{inspect properties[:description]})") { :description, value } ->
end unless is_list(value), do:
unless nil?(properties[:id]) or is_list(properties[:id]) do invalid "Application description (:description) is not a character list (got #{inspect value})"
raise(Mix.Error, message: "Application id (:id) is not a character list (got #{inspect properties[:id]} instead)") { :id, value } ->
end unless is_list(value), do:
unless nil?(properties[:vsn]) or is_list(properties[:vsn]) do invalid "Application id (:id) is not a character list (got #{inspect value} instead)"
raise(Mix.Error, message: "Application vsn (:vsn) is not a character list (got #{inspect properties[:vsn]} instead)") { :vsn, value } ->
end unless is_list(value), do:
unless nil?(properties[:modules]) or (is_list(properties[:modules]) and Enum.all?(properties[:modules], is_atom(&1))) do invalid "Application vsn (:vsn) is not a character list (got #{inspect value} instead)"
raise(Mix.Error, message: "Application modules (:modules) should be a list of atoms (got #{inspect properties[:modules]} instead)") { :maxT, value } ->
end unless value == :infinity or is_integer(value), do:
unless nil?(properties[:maxT]) or properties[:maxT] == :infinity or is_integer(properties[:maxT]) do invalid "Application maximum time (:maxT) is not an integer or :infinity (got #{inspect value} instead)"
raise(Mix.Error, message: "Application maximum time (:maxT) is not an integer or :infinity (got #{inspect properties[:maxT]} instead)") { :modules, value } ->
end unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
unless nil?(properties[:registered]) or is_list(properties[:registered]) and (Enum.all?(properties[:registered], is_atom(&1))) do invalid "Application modules (:modules) should be a list of atoms (got #{inspect value} instead)"
raise(Mix.Error, message: "Application registered processes (:registered) should be a list of atoms (got #{inspect properties[:registered]} instead)") { :registered, value } ->
end unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
unless nil?(properties[:included_applications]) or (is_list(properties[:included_applications]) and Enum.all?(properties[:included_applications], is_atom(&1))) do invalid "Application registered processes (:registered) should be a list of atoms (got #{inspect value} instead)"
raise(Mix.Error, message: "Application included applications (:included_applications) should be a list of atoms (got #{inspect properties[:included_applications]} instead)") { :included_applications, value } ->
end unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
unless nil?(properties[:applications]) or (is_list(properties[:applications]) and Enum.all?(properties[:applications], is_atom(&1))) do invalid "Application included applications (:included_applications) should be a list of atoms (got #{inspect value} instead)"
raise(Mix.Error, message: "Application dependencies (:applications) should be a list of atoms (got #{inspect properties[:applications]} instead)") { :applications, value } ->
end unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
unless nil?(properties[:env]) or (Keyword.keyword?(properties[:env])) do invalid "Application dependencies (:applications) should be a list of atoms (got #{inspect value} instead)"
raise(Mix.Error, message: "Application dependencies (:env) should be a keyword list (got #{inspect properties[:env]} instead)") { :env, value } ->
end unless Keyword.keyword?(value), do:
unless nil?(properties[:mod]) do invalid "Application dependencies (:env) should be a keyword list (got #{inspect value} instead)"
case properties[:mod] do { :start_phases, value } ->
[] -> :ok unless Keyword.keyword?(value), do:
{module, _start_args} when is_atom(module) -> :ok invalid "Application start phases (:start_phases) should be a keyword list (got #{inspect value} instead)"
other -> { :mod, [] } ->
raise(Mix.Error, message: "Application callback module (:mod) should be either [] or {module, start_args} (got #{inspect properties[:mod]} instead)") :ok
end { :mod, { module, _args } } when is_atom(module) ->
end :ok
unless nil?(properties[:start_phases]) or (Keyword.keyword?(properties[:start_phases])) do { :mod, value } ->
raise(Mix.Error, message: "Application start phases (:start_phases) should be a keyword list (got #{inspect properties[:start_phases]} instead)") invalid "Application callback module (:mod) should be either [] or {module, start_args} (got #{inspect value} instead)"
{ key, value } ->

This comment has been minimized.

Copy link
@yrashk

yrashk Dec 2, 2012

Contributor

Lets drop this. Application files are permitted to have optional keys. Agner, for example, used this property.

This comment has been minimized.

Copy link
@josevalim

josevalim Dec 2, 2012

Member

Ah, so go ahead. :)

This comment has been minimized.

Copy link
@yrashk

yrashk via email Dec 2, 2012

Contributor
invalid "Unknown application key #{inspect key} with value #{inspect value}"
end end
end end

defp invalid(message) do
raise Mix.Error, message: message
end
end end
4 changes: 2 additions & 2 deletions lib/mix/test/mix/tasks/compile.app_test.exs
Expand Up @@ -15,7 +15,7 @@ defmodule Mix.Tasks.Compile.AppTest do
end end


def application do def application do
[hello: 'beautiful'] [maxT: :infinity]
end end
end end


Expand Down Expand Up @@ -66,7 +66,7 @@ defmodule Mix.Tasks.Compile.AppTest do
Mix.Tasks.Compile.App.run([]) Mix.Tasks.Compile.App.run([])
contents = File.read!("ebin/custom_project.app") contents = File.read!("ebin/custom_project.app")
assert contents =~ %r/0.2.0/ assert contents =~ %r/0.2.0/
assert contents =~ %r/{hello,"beautiful"}/ assert contents =~ %r/{maxT,infinity}/
end end
after after
purge [A, B, C] purge [A, B, C]
Expand Down

0 comments on commit 4e8fb99

Please sign in to comment.