Skip to content

Commit 4e8fb99

Browse files
author
José Valim
committed
Validate all app properties and do not accept nil values
1 parent cf5f57f commit 4e8fb99

File tree

2 files changed

+47
-41
lines changed

2 files changed

+47
-41
lines changed

lib/mix/lib/mix/tasks/compile.app.ex

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ defmodule Mix.Tasks.Compile.App do
1919
http://www.erlang.org/doc/design_principles/applications.html
2020
2121
## Configuration
22-
22+
2323
* `:app` - The application name as a binary (required)
2424
* `:version` - The application version as a binary (required)
2525
@@ -86,51 +86,57 @@ defmodule Mix.Tasks.Compile.App do
8686

8787
defp ensure_correct_properties(app, properties) do
8888
properties = Keyword.from_enum(properties)
89-
properties = Keyword.put properties, :description,
89+
properties = Keyword.put properties, :description,
9090
to_char_list(properties[:description] || app)
9191
properties = Keyword.put properties, :registered, (properties[:registered] || [])
9292
validate_properties(properties)
9393
properties
9494
end
9595

9696
defp validate_properties(properties) do
97-
unless nil?(properties[:description]) or is_list(properties[:description]) do
98-
raise(Mix.Error, message: "Application description (:description) is not a character list (got #{inspect properties[:description]})")
99-
end
100-
unless nil?(properties[:id]) or is_list(properties[:id]) do
101-
raise(Mix.Error, message: "Application id (:id) is not a character list (got #{inspect properties[:id]} instead)")
102-
end
103-
unless nil?(properties[:vsn]) or is_list(properties[:vsn]) do
104-
raise(Mix.Error, message: "Application vsn (:vsn) is not a character list (got #{inspect properties[:vsn]} instead)")
105-
end
106-
unless nil?(properties[:modules]) or (is_list(properties[:modules]) and Enum.all?(properties[:modules], is_atom(&1))) do
107-
raise(Mix.Error, message: "Application modules (:modules) should be a list of atoms (got #{inspect properties[:modules]} instead)")
108-
end
109-
unless nil?(properties[:maxT]) or properties[:maxT] == :infinity or is_integer(properties[:maxT]) do
110-
raise(Mix.Error, message: "Application maximum time (:maxT) is not an integer or :infinity (got #{inspect properties[:maxT]} instead)")
111-
end
112-
unless nil?(properties[:registered]) or is_list(properties[:registered]) and (Enum.all?(properties[:registered], is_atom(&1))) do
113-
raise(Mix.Error, message: "Application registered processes (:registered) should be a list of atoms (got #{inspect properties[:registered]} instead)")
114-
end
115-
unless nil?(properties[:included_applications]) or (is_list(properties[:included_applications]) and Enum.all?(properties[:included_applications], is_atom(&1))) do
116-
raise(Mix.Error, message: "Application included applications (:included_applications) should be a list of atoms (got #{inspect properties[:included_applications]} instead)")
117-
end
118-
unless nil?(properties[:applications]) or (is_list(properties[:applications]) and Enum.all?(properties[:applications], is_atom(&1))) do
119-
raise(Mix.Error, message: "Application dependencies (:applications) should be a list of atoms (got #{inspect properties[:applications]} instead)")
120-
end
121-
unless nil?(properties[:env]) or (Keyword.keyword?(properties[:env])) do
122-
raise(Mix.Error, message: "Application dependencies (:env) should be a keyword list (got #{inspect properties[:env]} instead)")
123-
end
124-
unless nil?(properties[:mod]) do
125-
case properties[:mod] do
126-
[] -> :ok
127-
{module, _start_args} when is_atom(module) -> :ok
128-
other ->
129-
raise(Mix.Error, message: "Application callback module (:mod) should be either [] or {module, start_args} (got #{inspect properties[:mod]} instead)")
130-
end
131-
end
132-
unless nil?(properties[:start_phases]) or (Keyword.keyword?(properties[:start_phases])) do
133-
raise(Mix.Error, message: "Application start phases (:start_phases) should be a keyword list (got #{inspect properties[:start_phases]} instead)")
97+
Enum.each properties, fn
98+
{ :description, value } ->
99+
unless is_list(value), do:
100+
invalid "Application description (:description) is not a character list (got #{inspect value})"
101+
{ :id, value } ->
102+
unless is_list(value), do:
103+
invalid "Application id (:id) is not a character list (got #{inspect value} instead)"
104+
{ :vsn, value } ->
105+
unless is_list(value), do:
106+
invalid "Application vsn (:vsn) is not a character list (got #{inspect value} instead)"
107+
{ :maxT, value } ->
108+
unless value == :infinity or is_integer(value), do:
109+
invalid "Application maximum time (:maxT) is not an integer or :infinity (got #{inspect value} instead)"
110+
{ :modules, value } ->
111+
unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
112+
invalid "Application modules (:modules) should be a list of atoms (got #{inspect value} instead)"
113+
{ :registered, value } ->
114+
unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
115+
invalid "Application registered processes (:registered) should be a list of atoms (got #{inspect value} instead)"
116+
{ :included_applications, value } ->
117+
unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
118+
invalid "Application included applications (:included_applications) should be a list of atoms (got #{inspect value} instead)"
119+
{ :applications, value } ->
120+
unless is_list(value) and Enum.all?(value, is_atom(&1)), do:
121+
invalid "Application dependencies (:applications) should be a list of atoms (got #{inspect value} instead)"
122+
{ :env, value } ->
123+
unless Keyword.keyword?(value), do:
124+
invalid "Application dependencies (:env) should be a keyword list (got #{inspect value} instead)"
125+
{ :start_phases, value } ->
126+
unless Keyword.keyword?(value), do:
127+
invalid "Application start phases (:start_phases) should be a keyword list (got #{inspect value} instead)"
128+
{ :mod, [] } ->
129+
:ok
130+
{ :mod, { module, _args } } when is_atom(module) ->
131+
:ok
132+
{ :mod, value } ->
133+
invalid "Application callback module (:mod) should be either [] or {module, start_args} (got #{inspect value} instead)"
134+
{ key, value } ->
135+
invalid "Unknown application key #{inspect key} with value #{inspect value}"
134136
end
135137
end
138+
139+
defp invalid(message) do
140+
raise Mix.Error, message: message
141+
end
136142
end

lib/mix/test/mix/tasks/compile.app_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ defmodule Mix.Tasks.Compile.AppTest do
1515
end
1616

1717
def application do
18-
[hello: 'beautiful']
18+
[maxT: :infinity]
1919
end
2020
end
2121

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

0 commit comments

Comments
 (0)